如何在查询之前设置SQLAlchemy ORM类的属性?

时间:2016-03-01 05:19:58

标签: python json flask sqlalchemy flask-sqlalchemy

例如,使用Flask-SQLAlchemy和jsontools序列化为JSON,如-here-所示,并给出如下模型:

class Engine(db.Model):
    __tablename__ = "engines"

    id      = db.Column(db.Integer, primary_key=True)
    this    = db.Column(db.String(10))
    that    = db.Column(db.String(10))
    parts   = db.relationship("Part")

    schema = ["id"
        ,   "this"
        ,   "that"
        ,       "parts"
        ]

    def __json__(self):
        return self.schema

class Part(db.Model):
    __tablename__ = "parts"

    id          = db.Column(db.Integer, primary_key=True)
    engine_id   = db.Column(db.Integer, db.ForeignKey("engines.id"))
    code        = db.Column(db.String(10))

    def __json__(self):
        return ["id", "code"]

如何在查询之前更改schema属性,使其对返回数据生效?

enginelist = db.session.query(Engine).all()
return enginelist

到目前为止,我已经成功完成了子类化和单表继承:

class Engine_smallschema(Engine):
    __mapper_args__ = {'polymorphic_identity': 'smallschema'}

    schema = ["id"
        ,   "this"
        ,   "that"
        ]

enginelist = db.session.query(Engine_smallschema).all()
return enginelist

...但似乎应该有更好的方法而不需要子类(我不确定这是否明智)。我尝试过各种各样的事情,例如设置属性或调用方法来设置内部变量。问题是,在尝试这样的事情时,查询并不喜欢给出它的实例对象,并且我还不太了解SQLAlchemy,但还不知道是否可以在这些类的预制实例上执行查询。 / p>

我也可以遍历返回的对象,设置新的模式,并获得所需的JSON,但这对我来说不是解决方案,因为它会启动新的查询(我通常首先请求小数据集)。

还有其他想法吗?

1 个答案:

答案 0 :(得分:0)

JSON序列化发生在flask中,而不是SQLAlchemy中。因此,直到从视图函数返回后才会查询__json__函数。因此,这与SQLAlchemy无关,而是与自定义编码功能有关,可能您可以更改。

如果您要为模型序列化不同的属性集,我实际上建议不要尝试这样做。在影响其序列化方式的实例上设置魔术属性违反了最少惊喜的原则。相反,您可以创建一个Serializer类,您可以使用要序列化的字段列表进行初始化,然后将Engine传递给它,以生成dict可以很容易地转换为JSON。

如果你坚持按自己的方式去做,你可以这样做:

for e in enginelist:
    e.__json__ = lambda: ["id", "this", "that"]

当然,如果您想避免使用lambda,可以将__json__更改为属性。