假设以下设置:
from sqlalchemy import Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class MyClass(Base):
id = Column(Integer, primary_key=True)
name = Column(String)
使用 SQLAlchemy 查询数据库的正常范例是执行以下操作:
Session = sessionmaker()
engine = 'some_db_location_string'
session = Session(bind=engine)
session.query(MyClass).filter(MyClass.id == 1).first()
假设,我想将查询简化为以下内容:
MyClass(s).filter(MyClass.id == 1).first()
或 MyClass(s).filter(id == 1).first()
我该怎么做?我第一次尝试使用模型 Mixin 类失败了。这是我尝试过的:
class ModelMixins(object)
def __init__(self, session):
self.session = session
def filter(self, *args):
self.session.query(self).filter(*args)
# Redefine MyClass to use the above class
class MyClass(ModelMixins, Base):
id = Column(Integer, primary_key=True)
name = Column(String)
主要的失败似乎是我无法完全将表达式“MyClass.id == 1”传输到作为 session 对象一部分的实际过滤器函数。
人们可能会问我为什么要这样做:
MyClass(s).filter(id == 1).first()
我以前见过类似的东西,并且认为语法变得更加清晰,我可以实现这一点。我想复制这个,但没能做到。能够做这样的事情:
def get_stuff(some_id):
with session_scope() as s:
rec = MyClass(s).filter(MyClass.id== some_id').first()
if rec:
return rec.name
else:
return None
...似乎是最干净的做事方式。其一, session 管理是分开的。其次,查询本身被简化。拥有这样的 Mixin 类将允许我将过滤器功能添加到任意数量的类中......那么有人可以在这方面提供帮助吗?
最佳答案
session.query
采用一个类;你给它self
,它是一个实例。将您的 filter
方法替换为:
def filter(self, *args):
return session.query(self.__class__).filter(*args)
至少这么多有效:
In [45]: MyClass(session).filter(MyClass.id==1)
Out[45]: <sqlalchemy.orm.query.Query at 0x10e0bbe80>
生成的 SQL 看起来也正确(为了清晰起见添加了换行符):
In [57]: str(MyClass(session).filter(MyClass.id==1))
Out[57]: 'SELECT "MyClass".id AS "MyClass_id", "MyClass".name AS "MyClass_name"
FROM "MyClass"
WHERE "MyClass".id = ?'
不保证不会出现异常情况;我以前从未尝试过这样的事情。
关于python - 如何将 Mixins 与 SQLAlchemy 结合使用来简化查询和过滤操作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48471732/