2012-12-21 45 views
2

我正在嘗試SELECT FOR SHARE表中的一組行,以便它們被鎖定直到事務結束。我正在使用SQLAlchemy 0.7.9在PostgreSQL 9.1.6數據庫中執行此操作。這是有問題的Python代碼:如何使用SQLAlchemy和PostgreSQL選擇共享?

NUM_TERMS = 10 
conn = engine.connect() 
get_terms = select([search_terms.c.term_id, search_terms.c.term], 
        and_(search_terms.c.lock==False, 
        search_terms.c.status==False), 
        order_by=search_terms.c.term, 
        limit=NUM_TERMS, for_update="read") 
trans = conn.begin() 
try: 
    search_terms = conn.execute(get_terms).fetchall() 
    for term in search_terms: 
     lock_terms = update(search_terms).\ 
        where(search_terms.c.term_id==term.term_id).\ 
        values(lock=True) 
     conn.execute(lock_terms) 
    if trans.commit(): 
     <do things with the search terms> 
except: 
    trans.rollback() 

的問題是上面的選擇代碼生成的SQL查詢是不是爲了分享,這是FOR UPDATE:

SELECT search_terms.term_id, search_terms.term 
FROM search_terms 
WHERE search_terms.lock = :lock_1 AND search_terms.status = :status_1  
ORDER BY search_terms.term 
LIMIT :param_1 FOR UPDATE 

按照SQLAlchemy API docs,下「for_update」參數說明:

使用Postgresql方言,值「read」和「read_nowait」翻譯爲FOR SHARE和FOR NOWAREA,分別爲LY。

根據以上所述,編譯的SQL語句應該是FOR SHARE,但它不是。我的代碼中的錯誤在哪裏?

回答

1

無法重現:

from sqlalchemy import * 

m = MetaData() 
t = Table('t', m, Column('x', Integer)) 

s = select([t], for_update="read") 

from sqlalchemy.dialects import postgresql 
print s.compile(dialect=postgresql.dialect()) 

e = create_engine("postgresql://scott:[email protected]/test", echo=True) 
with e.begin() as conn: 
    m.create_all(conn) 
    conn.execute(s) 

輸出表明,無論作爲一個獨立的編譯和PostgreSQL的談話中,我們得到的份額。測試在0.7.9和0.8.0b2。如果您可以提供完整的可運行測試用例,則可能會釋放更多光線:

SELECT t.x 
FROM t FOR SHARE 
2012-12-20 23:53:33,670 INFO sqlalchemy.engine.base.Engine select version() 
2012-12-20 23:53:33,671 INFO sqlalchemy.engine.base.Engine {} 
2012-12-20 23:53:33,672 INFO sqlalchemy.engine.base.Engine select current_schema() 
2012-12-20 23:53:33,672 INFO sqlalchemy.engine.base.Engine {} 
2012-12-20 23:53:33,674 INFO sqlalchemy.engine.base.Engine BEGIN (implicit) 
2012-12-20 23:53:33,674 INFO sqlalchemy.engine.base.Engine select relname from pg_class c join pg_namespace n on n.oid=c.relnamespace where n.nspname=current_schema() and relname=%(name)s 
2012-12-20 23:53:33,675 INFO sqlalchemy.engine.base.Engine {'name': u't'} 
2012-12-20 23:53:33,676 INFO sqlalchemy.engine.base.Engine SELECT t.x 
FROM t FOR SHARE 
2012-12-20 23:53:33,676 INFO sqlalchemy.engine.base.Engine {} 
2012-12-20 23:53:33,676 INFO sqlalchemy.engine.base.Engine COMMIT 
相關問題