Python 使用SQLAlchemy的事务和方法
我有一个collection类,用于使用SQLAlchemy修改数据库中的一些数据:Python 使用SQLAlchemy的事务和方法,python,transactions,sqlalchemy,Python,Transactions,Sqlalchemy,我有一个collection类,用于使用SQLAlchemy修改数据库中的一些数据: import sqlalchemy as sa class Collection: def __init__(self, ...): self.engine = sa.create_engine(...) def get_some_name_by_id(self, name): return self.engine.execute(select(), ...)
import sqlalchemy as sa
class Collection:
def __init__(self, ...):
self.engine = sa.create_engine(...)
def get_some_name_by_id(self, name):
return self.engine.execute(select(), ...).fetchone().id
def add(self, name):
some_id = self.get_some_name_by_id(name)
with self.engine.begin() as conn:
conn.execute(...)
conn.execute(...)
conn.execute(...)
...
所以它有两种方法:
通过\u id获取\u some\u name \u-给定名称将返回一些id
add方法使用get_some_name_by_id中的id来执行一系列SQL请求。
问题是我想在事务中包含get_some_name_by_id。起初,我有一个巨大的add方法,其中所有的执行语句都在with语句下。现在我正在重构代码,将一些块提取到方法中,我不知道如何将它们添加到事务中。如果可能的话,方法应该在事务中运行,如果它是在事务中调用的
当然,我可以这样做:
def get_some_name_by_id(self, name, conn=None):
if conn is None:
conn = self.engine
return conn.execute(select(), ...).fetchone().id
def add(self, name):
with self.engine.begin() as conn:
some_id = self.get_some_name_by_id(name, conn)
conn.execute(...)
但我觉得这有点笨拙。我将得到很多函数,它们都有相同的if子句。有更好的办法吗 我认为你建议的方法还可以。您可以使用@property decorator为conn实现自定义检索: 例如:
import sqlalchemy as sa
class Collection(object):
def __init__(self, ...):
self.engine = sa.create_engine(...)
self._conn = None
@property
def conn(self):
if self._conn is None:
self._conn = self.engine
return self._conn
@conn.setter
def conn(self, value):
self._conn = value
def get_some_name_by_id(self, name):
return self.conn.execute(select(), ...).fetchone().id
def add(self, name):
with self.engine.begin() as self.conn:
some_id = self.get_some_name_by_id(name)
self.conn.execute(...)
这样你就不必绕过康恩了。您可以初始化self.conn一次并使用它,因为每个集合对象只能有一个连接。如果需要,您可以修改它以支持多个连接。Hm,有趣的解决方案。使用块后,self.conn将变为“无”或“无”?self.conn仍将是连接对象,但如果不调用self.conn.begin,您将无法将其用于任何其他查询。查看调用begin时发生的情况这很糟糕。因为这意味着我不能在没有事务的情况下使用get\u some\u name\u by\u id。您仍然可以在事务之外使用get\u some\u name\u by\u id作为独立的。在“添加”结束时,必须将self.conn设置为“无”。因此,下次访问self.conn时,它将返回self.engine和.execute…fetchone。。。仍然有效。