在我的應用程序中,我使用SQLAlchemy在應用程序重新啓動時存儲大多數持久數據。爲此,我有一個包含我的映射程序類(如Tag
,Group
等)的db
程序包,以及使用create_engine
和使用sessionmaker
的單個全局Session
工廠創建單個引擎實例的支持類。多個會話的問題
現在我對如何使用SQLAlchemys會話的理解是,我不會在應用中傳遞它們,而是在需要數據庫訪問時使用全局工廠創建實例。
這會導致在一個會話中查詢記錄,然後傳遞到應用的另一部分,該應用使用不同的會話實例。這給了我喜歡的例外這一個:
Traceback (most recent call last):
File "…", line 29, in delete
session.delete(self.record)
File "/usr/lib/python3.3/site-packages/sqlalchemy/orm/session.py", line 1444, in delete
self._attach(state, include_before=True)
File "/usr/lib/python3.3/site-packages/sqlalchemy/orm/session.py", line 1748, in _attach
state.session_id, self.hash_key))
sqlalchemy.exc.InvalidRequestError: Object '<Group at 0x7fb64c7b3f90>' is already attached to session '1' (this is '3')
現在我的問題是:我纔拿到的使用Session
完全地錯誤的(所以我應該一次只使用一個會話和周圍一起傳遞會話到其他部件來自數據庫的記錄),還是可能由實際的代碼問題導致?
一些示例代碼演示我確切的問題:
from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base, declared_attr
Base = declarative_base()
class Record(Base):
__tablename__ = "record"
id = Column(Integer, primary_key=True)
name = Column(String)
def __init__(self, name):
self.name = name
def __repr__(self):
return "<%s('%s')>" % (type(self).__name__, self.name)
engine = create_engine("sqlite:///:memory:")
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
s1 = Session()
record = Record("foobar")
s1.add(record)
s1.commit()
# This would be a completly different part of app
s2 = Session()
record = s2.query(Record).filter(Record.name == "foobar").first()
def delete_record(record):
session = Session()
session.delete(record)
session.commit()
delete_record(record)