2013-04-23 49 views
11

tôi đang cố gắng để làm một bộ lọc hoạt động đơn giản trên một truy vấn trong SQLAlchemy, như thế này:SQLAlchemy lọc in_ hành

q = session.query(Genotypes).filter(Genotypes.rsid.in_(inall)) 

nơi

inall là một danh sách các chuỗi Kiểu gen được ánh xạ vào một bảng : Kiểu gen lớp (đối tượng): qua

Genotypes.mapper = mapper(Genotypes, kg_table, properties={'rsid': getattr(kg_table.c, 'rs#')}) 

Điều này có vẻ khá đơn giản đối với tôi, nhưng tôi nhận được e Lỗi ollowing khi tôi thực hiện truy vấn trên bằng cách thực hiện q.first():

"sqlalchemy.exc.OperationalError: (OperationalError) too many SQL variables u'SELECT" followed by a list of the 1M items in the inall list. But they aren't supposed to be SQL variables, just a list whose membership is the filtering criteria.

Tôi có lọc không chính xác không?

(db là sqlite)

Trả lời

14

Nếu chiếc bàn nơi bạn đang nhận được rsid của bạn từ có sẵn trong cơ sở dữ liệu cùng tôi muốn sử dụng một subquery để chuyển chúng vào truy vấn Genotypes của bạn chứ không phải đi qua các một triệu các mục xung quanh trong mã Python của bạn.

sq = session.query(RSID_Source).subquery() 
q = session.query(Genotypes).filter(Genotypes.rsid.in_(sq)) 

Vấn đề là để thông qua đó danh sách để SQLite (hoặc bất kỳ cơ sở dữ liệu, thực sự), SQLAlchemy phải vượt qua mỗi mục nhập cho khoản in của bạn như là một biến. SQL dịch xấp xỉ tới:

-- Not valid SQLite SQL 
DECLARE @Param1 TEXT; 
SET @Param1 = ?; 
DECLARE @Param2 TEXT; 
SET @Param2 = ?; 
-- snip 999,998 more 

SELECT field1, field2, -- etc. 
FROM Genotypes G 
WHERE G.rsid IN (@Param1, @Param2, /* snip */) 
1

Cách giải quyết dưới đây làm việc cho tôi:

q = session.query(Genotypes).filter(Genotypes.rsid.in_(inall)) 
query_as_string = str(q.statement.compile(compile_kwargs={"literal_binds": True})) 
session.execute(query_as_string).first() 

này bắt buộc người truy vấn để biên dịch như là một chuỗi trước khi thực hiện, mà bỏ qua toàn bộ vấn đề biến. Một số chi tiết về điều này có sẵn trong tài liệu của SQLAlchemy here.

BTW, nếu bạn không sử dụng SQLite, bạn có thể sử dụng toán tử ANY để chuyển đối tượng danh sách dưới dạng tham số duy nhất (xem câu trả lời của tôi cho câu hỏi này here).

Các vấn đề liên quan