我们正在为使用龙卷风和sqlalchemy的应用程序创建服务。该应用程序使用django编写,并使用“软删除机制”。这意味着在底层的mysql表中没有删除。要将行标记为已删除,我们只需将属性“delete”设置为True即可。但是,在我们使用sqlalchemy的服务中。一开始,我们就开始通过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的
这不会停止查询没有删除,这是至关重要的。因为整个观点是避免错误。 – dusual
'customer_query().filter(something).update(something2)'应该将删除过滤器和'something'过滤器一起应用。 – aitchnyu