Eu tenho uma lista python, digamos, l
l = [1,5,8]
Eu quero escrever uma consulta sql para obter os dados de todos os elementos da lista, digamos
select name from students where id = |IN THE LIST l|
Como eu faço isso?
Até agora, as respostas foram modelar os valores em uma sequência SQL simples. Isso é absolutamente bom para números inteiros, mas se quisermos fazer isso por strings, obtemos o problema de escape.
Aqui está uma variante usando uma consulta parametrizada que funcionaria para ambos:
placeholder= '?' # For SQLite. See DBAPI paramstyle.
placeholders= ', '.join(placeholder for unused in l)
query= 'SELECT name FROM students WHERE id IN (%s)' % placeholders
cursor.execute(query, l)
','.join(placeholder * len(l))
seria um pouco menor, enquanto ainda imho legível([placeholder]*len(l))
no caso geral, pois o espaço reservado pode ter vários caracteres.cursor.execute(f'SELECT name FROM students WHERE id IN ({','.join('?' for _ in l)})', l)
. @bince, você também deve observar em sua solução que o uso?
é o caminho seguro para evitar a injeção de SQL. Há muitas respostas aqui vulneráveis, basicamente as que concatenam cadeias de caracteres em python.A maneira mais fácil é transformar a lista em
tuple
primeiro lugarfonte
Não complique, a solução para isso é simples.
Espero que isso tenha ajudado !!!
fonte
l
apenas contiver um elemento, você vai acabar comid IN (1,)
. O que é um erro de sintaxe.sqlite3
. Em qual biblioteca você testou isso?O SQL que você deseja é
Se você deseja construir isso a partir do python, você pode usar
A função map transformará a lista em uma lista de cadeias que podem ser coladas por vírgulas usando o método str.join .
Alternativamente:
se você preferir expressões geradoras à função map.
UPDATE: S. Lott menciona nos comentários que as ligações Python SQLite não suportam sequências. Nesse caso, você pode querer
Gerado por
fonte
string.join os valores da lista separados por vírgulas e use o operador format para formar uma string de consulta.
(Obrigado, Blair-Conrad )
fonte
%
está sendo usado aqui é apenas uma formatação simples de string Python.Eu gosto da resposta de bobince:
Mas eu notei isso:
Pode ser substituído por:
Acho isso mais direto, se menos inteligente e menos geral. Aqui
l
é necessário ter um comprimento (ou seja, referir-se a um objeto que define um__len__
método), o que não deve ser um problema. Mas o espaço reservado também deve ser um único caractere. Para oferecer suporte a um espaço reservado para vários caracteres, use:fonte
Solução para resposta @umounted, porque ela quebrou com uma tupla de um elemento, pois (1,) não é SQL válido:
Outra solução para sql string:
fonte
Isso deve resolver seu problema.
fonte
Se você estiver usando o PostgreSQL com a biblioteca Psycopg2, poderá permitir que sua adaptação à tupla faça toda a interpolação de escape e de string para você, por exemplo:
ou seja, apenas verifique se você está passando o
IN
parâmetro como atuple
. se for um,list
você pode usar a= ANY
sintaxe da matriz :observe que esses dois serão transformados no mesmo plano de consulta; portanto, você deve usar o que for mais fácil. por exemplo, se sua lista vem em uma tupla, use a primeira, se eles estão armazenados em uma lista, use a segunda.
fonte
Por exemplo, se você deseja a consulta sql:
A respeito:
fonte
uma solução mais simples:
fonte
A
:var
notação parece mais simples. (Python 3.7)fonte
Isso usa substituição de parâmetro e cuida do caso da lista de valores únicos:
fonte