[英]How do I set the attributes of a SQLAlchemy ORM class before query?
For example, using Flask-SQLAlchemy and jsontools to serialize to JSON like shown -here- , and given a model like this: 例如,使用Flask-SQLAlchemy和jsontools如-here-所示序列化为JSON,并给出如下模型:
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"]
How do I change the schema
attribute before query so that it takes effect on the return data? 如何在查询之前更改
schema
属性,以使其对返回数据生效?
enginelist = db.session.query(Engine).all()
return enginelist
So far, I have succeeded with subclassing and single-table inheritance like so: 到目前为止,我已经成功实现了子类化和单表继承,如下所示:
class Engine_smallschema(Engine):
__mapper_args__ = {'polymorphic_identity': 'smallschema'}
schema = ["id"
, "this"
, "that"
]
and 和
enginelist = db.session.query(Engine_smallschema).all()
return enginelist
...but it seems there should be a better way without needing to subclass (I'm not sure if this is wise). ...但是似乎应该有一种无需子类化的更好方法(我不确定这是否明智)。 I've tried various things such as setting an attribute or calling a method to set an internal variable.
我尝试了各种方法,例如设置属性或调用方法来设置内部变量。 Problem is, when trying such things, the query doesn't like the instance object given it and I don't know SQLAlchemy well enough yet to know if queries can be executed on pre-made instances of these classes.
问题是,在尝试此类操作时,查询不喜欢指定的实例对象,而且我对SQLAlchemy的了解还不够,还不知道是否可以对这些类的预制实例执行查询。
I can also loop through the returned objects, setting a new schema, and get the wanted JSON, but this isn't a solution for me because it launches new queries (I usually request the small dataset first). 我还可以遍历返回的对象,设置新的架构,并获取所需的JSON,但这对我来说不是一个解决方案,因为它会启动新的查询(我通常首先请求小的数据集)。
Any other ideas? 还有其他想法吗?
The JSON serialization takes place in flask, not in SQLAlchemy. JSON序列化在flask中进行,而不是在SQLAlchemy中进行。 Thus, the
__json__
function is not consulted until after you return from your view function. 因此,直到从视图函数返回后,才使用
__json__
函数。 This has therefore nothing to do with SQLAlchemy, and instead it has to do with the custom encoding function, which presumably you can change. 因此,这与SQLAlchemy无关,而是与自定义编码功能有关,该功能大概可以更改。
I would actually suggest not attempting to do it this way if you have different sets of attributes you want to serialize for a model. 实际上,如果您要对模型进行序列化的属性集不同,则建议不要尝试通过这种方式进行操作。 Setting a magic attribute on an instance that affects how it's serialized violates the principle of least surprise.
在实例上设置影响其序列化方式的魔术属性违反了最小惊讶原则。 Instead, you can, for example, make a
Serializer
class that you can initialize with the list of fields you want to be serialized, then pass your Engine
to it to produce a dict
that can be readily converted to JSON. 相反,例如,您可以创建一个
Serializer
类,该类可以使用要序列化的字段列表进行初始化,然后将Engine
传递给它,以生成可以轻松转换为JSON的dict
。
If you insist on doing it your way, you can probably just do this: 如果您坚持以自己的方式进行操作,则可以执行以下操作:
for e in enginelist:
e.__json__ = lambda: ["id", "this", "that"]
Of course, you can change __json__
to be a property instead if you want to avoid the lambda. 当然,如果要避免使用lambda,则可以将
__json__
更改为属性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.