我有一个集合类,用于使用SQLAlchemy修改DB中的某些数据:
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(...)
...
所以它有两种方法:
get_some_name_by_id
- 给定名称返回一些id add
方法使用get_some_name_by_id
中的id来执行一系列SQL请求。 问题是我想在事务中加入get_some_name_by_id
。起初我有一个巨大的add
方法,其中所有execute
语句都在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条款的函数。有没有更好的办法?
答案 0 :(得分:0)
我认为你建议的方法没问题。您可以使用@property装饰器来实现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(...)
这样你就不必通过conn了。您可以初始化self.conn一次并使用它使用此按钮,您将被限制为每个Collection对象一个连接。您可以修改它以支持多个连接(如果需要)。