SQLAlchemy IN klausa


237

Saya mencoba melakukan kueri ini di sqlalchemy

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

Saya ingin mengikat daftar [123, 456]pada waktu eksekusi.

Jawaban:


332

Bagaimana tentang

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

sunting : Tanpa ORM, itu akan menjadi

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

select()mengambil dua parameter, yang pertama adalah daftar bidang yang akan diambil, yang kedua adalah wherekondisi. Anda bisa mengakses semua bidang pada objek tabel melalui properti c(atau columns).


6
Saat ini saya tidak menggunakan bagian ORM dari sqlachemy, tetapi hanya SQL Expression API.
wonzbak

136

Dengan asumsi Anda menggunakan gaya deklaratif (yaitu kelas ORM), itu cukup mudah:

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

db_sessionadalah sesi basis data Anda di sini, sedangkan Userkelas ORM dengan __tablename__sama dengan "users".


29
Gunakan ~( ~User.id.in_([123,456])) atau not_dari sqlalchemy.sql.expression( not_(User.id.in_([123,456]))).
Xion


38

Cara alternatif adalah menggunakan mode SQL mentah dengan SQLAlchemy, saya menggunakan SQLAlchemy 0.9.8, python 2.7, MySQL 5.X, dan MySQL-Python sebagai konektor, dalam hal ini, diperlukan sebuah tuple. Kode saya tercantum di bawah ini:

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()

Semoga semuanya berhasil untuk Anda.


5
Jika Anda menggunakan SQL mentah untuk pertanyaan sederhana seperti itu, Anda lebih baik menggunakan psycopg2 atau konektor lain secara langsung.
omikron

6

Dengan API ekspresi, yang berdasarkan pada komentar adalah apa yang ditanyakan oleh pertanyaan ini, Anda dapat menggunakan in_metode kolom yang relevan.

Ke kueri

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

menggunakan

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)

Ini mengasumsikan bahwa user_tabledan conntelah didefinisikan secara tepat.


1

Hanya ingin berbagi solusi saya menggunakan sqlalchemy dan panda di python 3. Mungkin, orang akan merasa berguna.

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

Hanya tambahan jawaban di atas.

Jika Anda ingin menjalankan SQL dengan pernyataan "IN" Anda bisa melakukan ini:

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)

Dua poin:

  • Tidak perlu Parenthesis untuk pernyataan IN (seperti "... IN (% s)"), cukup cantumkan "... IN% s"
  • Paksa daftar id Anda menjadi salah satu elemen tuple. Jangan lupa tanda ",": (ids_list,)

EDIT Perhatikan bahwa jika panjang daftar adalah satu atau nol, ini akan menimbulkan kesalahan!


2
Saya pikir Anda harus melakukannya args = [(tuple(ids_list),)], periksa kembali.
zs2020

4
OP bertanya bagaimana melakukan ini dalam sqlalchemy, tidak menggunakan panggilan dbapi mentah ...
cowbert

Ini tidak berfungsi dengan daftar item tunggal karena menghasilkan (item, )dan itu tidak benar dalam SQL
danius
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.