如何为Sqlalchemy中的所有模型编写通用的get_by_id()方法?

1 投票
3 回答
1166 浏览
提问于 2025-04-16 03:41

我在用pylons和sqlalchemy。我的项目里有好几个模型,但我发现自己总是写类似的代码,重复了很多次:

question = Session.query(Question).filter_by(id=question_id).one()
answer = Session.query(Answer).fileter_by(id=answer_id).one()
...
user = Session.query(User).filter_by(id=user_id).one()

因为这些模型都是继承自Base类的,有没有办法定义一个通用的get_by_id()方法呢?

这样我就可以像这样使用它:

quesiton = Question.get_by_id(question_id)
answer = Answer.get_by_id(answer_id)
...
user = User.get_by_id(user_id)

3 个回答

0
class Base(object):
    @classmethod
    def get_by_id(cls, session, id):
        q = session.query(cls).filter_by(id=id)
        return q.one()

Question.get_by_id(Session, question_id)

当然可以!请把你想要翻译的内容发给我,我会帮你用简单易懂的语言解释清楚。

3

如果id是你的主键列,你只需要这样做:

session.query(Foo).get(id)

这样做的好处是,如果这个实例已经在会话中,就不需要再去查询数据库了。

2

很遗憾,SQLAlchemy不允许你在没有相应表声明的情况下去扩展Base类。你可以定义一个带有get_by_id作为类方法的混合类,但这样的话你就得为每个类都指定它。

一个更简单但不太优雅的解决办法是直接把它加到Base里:

def get_by_id(cls, id, session=session):
    return session.query(cls).filter_by(id=id).one()

Base.get_by_id = classmethod(get_by_id)

这个方法假设你在定义的时候已经有一个session对象可用,否则你每次都得把它作为参数传进去。

撰写回答