2013-04-23 33 views
11

böyle, sqlalchemy bir sorguyu basit filtre işlemini yapmaya çalışıyorum:SQLAlchemy filtre in_ operatörü

inall dizeleri listesidir

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

Genotipler bir tabloya eşleştirilir : sınıf Genotipler (nesne): geçişli

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

Bu benim için oldukça basit görünüyor, ama ben f olsun

"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.

mıyım yanlış filtreleme yapıyor: Ne q.first() yaparak yukarıdaki sorgu çalıştırdığınızda hata ollowing?

Ben subquery kullanmayı tercih ediyorum aynı veritabanında

cevap

14

Eğer adresinin rsid s alıyorsanız tablo varsa bir milyon aktarmak yerine sizin Genotypes sorgusu içine geçmesine (db sqlite olan) Python kodunuzdaki girişler.

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

sorunu SQLite o listeyi (veya herhangi bir veritabanı, gerçekten) geçmek için, SQLAlchemy bir değişken olarak in maddesi için her giriş üzerinden geçmek zorunda olmasıdır. Aşağıdaki geçici çözüm benim için çalıştı

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

: SQL kabaca çevirir

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

Bu temelde bütün değişkenler sorunu atlar yürütme önce bir dize olarak derlemek için sorgu zorlar. Bununla ilgili bazı ayrıntılar SQLAlchemy'nin dokümanları here'da bulunabilir.

BTW, SQLite kullanmıyorsanız, ANY işlecini liste nesnesini tek bir parametre olarak iletmek için kullanabilirsiniz (bu soruyu yanıtıma bakın here).