【发布时间】:2017-06-13 13:05:04
【问题描述】:
我们正在使用 tornado 和 sqlalchemy 为应用创建服务。该应用程序是用 django 编写的,并使用“软删除机制”。这意味着基础 mysql 表中没有删除。要将行标记为已删除,我们只需将属性“删除”设置为 True。但是,在服务中我们使用的是 sqlalchemy。最初,我们开始在通过 sqlalchemy 本身发出的查询中添加检查删除,例如:
customers = db.query(Customer).filter(not_(Customer.deleted)).all()
但是,这会导致很多潜在的错误,因为开发人员往往会错过在查询中删除的检查。因此,我们决定使用执行“预过滤器”的查询类覆盖默认查询:
class SafeDeleteMixin(Query):
def __iter__(self):
return Query.__iter__(self.deleted_filter())
def from_self(self, *ent):
# override from_self() to automatically apply
# the criterion too. this works with count() and
# others.
return Query.from_self(self.deleted_filter(), *ent)
def deleted_filter(self):
mzero = self._mapper_zero()
if mzero is not None:
crit = mzero.class_.deleted == False
return self.enable_assertions(False).filter(crit)
else:
return self
这灵感来自此处关于 sqlalchemy 文档的解决方案:
https://bitbucket.org/zzzeek/sqlalchemy/wiki/UsageRecipes/PreFilteredQuery
但是,我们仍然面临一些问题,例如我们同时进行过滤和更新,并且使用上面定义的这个查询类,更新在应用过滤器进行更新时不遵守delete=False 的标准。
db = CustomSession(with_deleted=False)()
result = db.query(Customer).filter(Customer.id == customer_id).update({Customer.last_active_time: last_active_time })
如何在 sqlalchemy 中实现“软删除”功能
【问题讨论】:
标签: orm sqlalchemy