Mệnh đề SQLAlchemy IN


237

Tôi đang cố gắng thực hiện truy vấn này trong sqlalchemy

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

Tôi muốn ràng buộc danh sách [123, 456]tại thời điểm thực hiện.

Câu trả lời:


332

Làm thế nào về

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

chỉnh sửa : Nếu không có ORM, nó sẽ là

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

select()lấy hai tham số, cái đầu tiên là danh sách các trường cần lấy, cái thứ hai là wheređiều kiện. Bạn có thể truy cập tất cả các trường trên một đối tượng bảng thông qua thuộc tính c(hoặc columns).


6
Tôi hiện không sử dụng phần ORM của sqlachemy, mà chỉ sử dụng API biểu thức SQL.
wonzbak

136

Giả sử bạn sử dụng kiểu khai báo (tức là các lớp ORM), điều này khá dễ dàng:

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

db_sessionlà phiên cơ sở dữ liệu của bạn ở đây, trong khi Userlớp ORM __tablename__bằng "users".


29
Sử dụng ~( ~User.id.in_([123,456])) hoặc not_từ sqlalchemy.sql.expression( not_(User.id.in_([123,456]))).
Xion


38

Một cách khác là sử dụng chế độ SQL thô với SQLAlchemy, tôi sử dụng SQLAlchemy 0.9.8, python 2.7, MySQL 5.X và MySQL-Python làm trình kết nối, trong trường hợp này, cần một tuple. Mã của tôi được liệt kê dưới đây:

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

Hy vọng mọi thứ làm việc cho bạn.


5
Nếu bạn sử dụng SQL thô cho các truy vấn đơn giản như vậy, tốt hơn hết bạn nên sử dụng psycopg2 hoặc trình kết nối khác trực tiếp.
omikron

6

Với API biểu thức, dựa trên các nhận xét là câu hỏi này yêu cầu gì, bạn có thể sử dụng in_ phương pháp của cột có liên quan.

Để truy vấn

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

sử dụng

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)

Điều này giả định rằng user_tableconnđã được xác định một cách thích hợp.


1

Chỉ muốn chia sẻ giải pháp của tôi bằng cách sử dụng sqlalchemy và gấu trúc trong python 3. Có lẽ, người ta sẽ thấy nó hữu ích.

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

Chỉ là một bổ sung cho các câu trả lời ở trên.

Nếu bạn muốn thực thi SQL bằng câu lệnh "IN", bạn có thể thực hiện việc này:

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)

Hai điểm:

  • Không cần ngoặc đơn cho câu lệnh IN (như "... IN (% s)"), chỉ cần đặt "... IN% s"
  • Buộc danh sách id của bạn là một yếu tố của một tuple. Đừng quên ",": (ids_list,)

EDIT Xem ra rằng nếu độ dài của danh sách là một hoặc không, điều này sẽ gây ra lỗi!


2
Tôi nghĩ bạn nên làm args = [(tuple(ids_list),)], xin vui lòng kiểm tra lại.
zs2020

4
OP đang hỏi làm thế nào để làm điều này trong sqlalchemy, không sử dụng cuộc gọi dbapi thô ...
cowbert

Điều này không hoạt động với một danh sách vật phẩm duy nhất vì nó tạo ra (item, )và nó không chính xác trong SQL
danius
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.