Clause SQLAlchemy IN


237

J'essaie de faire cette requête dans sqlalchemy

SELECT id, name FROM user WHERE id IN (123, 456)

Je voudrais lier la liste [123, 456]au moment de l'exécution.

Réponses:


332

Que diriez-vous

session.query(MyUserClass).filter(MyUserClass.id.in_((123,456))).all()

edit : Sans l'ORM, ce serait

session.execute(
    select(
        [MyUserTable.c.id, MyUserTable.c.name], 
        MyUserTable.c.id.in_((123, 456))
    )
).fetchall()

select()prend deux paramètres, le premier est une liste de champs à récupérer, le second est la wherecondition. Vous pouvez accéder à tous les champs d'un objet table via la propriété c(ou columns).


6
Je n'utilise pas actuellement la partie ORM de sqlachemy, mais seulement l'API SQL Expression.
wonzbak

136

En supposant que vous utilisez le style déclaratif (c'est-à-dire les classes ORM), c'est assez simple:

query = db_session.query(User.id, User.name).filter(User.id.in_([123,456]))
results = query.all()

db_sessionest votre session de base de données ici, tandis que Userla classe ORM est __tablename__égale à "users".


29
Utilisez ~( ~User.id.in_([123,456])) ou not_depuis sqlalchemy.sql.expression( not_(User.id.in_([123,456]))).
Xion


38

Une autre manière est d'utiliser le mode SQL brut avec SQLAlchemy, j'utilise SQLAlchemy 0.9.8, python 2.7, MySQL 5.X et MySQL-Python comme connecteur, dans ce cas, un tuple est nécessaire. Mon code ci-dessous:

id_list = [1, 2, 3, 4, 5] # in most case we have an integer list or set
s = text('SELECT id, content FROM myTable WHERE id IN :id_list')
conn = engine.connect() # get a mysql connection
rs = conn.execute(s, id_list=tuple(id_list)).fetchall()

J'espère que tout fonctionne pour vous.


5
Si vous utilisez du SQL brut pour de telles requêtes simples, il vaut mieux utiliser directement psycopg2 ou un autre connecteur.
omikron

6

Avec l'expression API, qui, sur la base des commentaires, est ce que cette question demande, vous pouvez utiliser la in_méthode de la colonne appropriée.

Pour interroger

SELECT id, name FROM user WHERE id in (123,456)

utilisation

myList = [123, 456]
select = sqlalchemy.sql.select([user_table.c.id, user_table.c.name], user_table.c.id.in_(myList))
result = conn.execute(select)
for row in result:
    process(row)

Cela suppose que user_tableet connont été définis de manière appropriée.


1

Je voulais juste partager ma solution en utilisant sqlalchemy et pandas en python 3. Peut-être, on le trouverait utile.

import sqlalchemy as sa
import pandas as pd
engine = sa.create_engine("postgresql://postgres:my_password@my_host:my_port/my_db")
values = [val1,val2,val3]   
query = sa.text(""" 
                SELECT *
                FROM my_table
                WHERE col1 IN :values; 
""")
query = query.bindparams(values=tuple(values))
df = pd.read_sql(query, engine)

-2

Juste un ajout aux réponses ci-dessus.

Si vous souhaitez exécuter un SQL avec une instruction "IN", vous pouvez le faire:

ids_list = [1,2,3]
query = "SELECT id, name FROM user WHERE id IN %s" 
args = [(ids_list,)] # Don't forget the "comma", to force the tuple
conn.execute(query, args)

Deux points:

  • Il n'y a pas besoin de parenthèses pour l'instruction IN (comme "... IN (% s)"), mettez simplement "... IN% s"
  • Forcez la liste de vos identifiants à être un élément d'un tuple. N'oubliez pas le ",": (ids_list,)

EDIT Attention, si la longueur de la liste est de un ou zéro, cela provoquera une erreur!


2
Je pense que vous devriez le faire args = [(tuple(ids_list),)], veuillez vérifier.
zs2020

4
L'OP demande comment faire cela dans sqlalchemy, sans utiliser d'appel dbapi brut ...
cowbert

Cela ne fonctionne pas avec une seule liste d'éléments car elle produit (item, )et elle est incorrecte dans SQL
danius
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.