我正在使用python flask和api
休息SQLalchemy
。我有两个班级父母和孩子:
Class Parent(db.Model):
id = db.Column(db.Integer, nullable=False, autoincrement=True, primary_key=True)
name = db.Column(db.String, nullable=False)
children = relationship('Child',
secondary=parent_has_children,
back_populates='parents'
)
Class Child(db.Model):
id = db.Column(db.Integer, nullable=False, autoincrement=True, primary_key=True)
name = db.Column(db.String, nullable=False)
parents = relationship('Parent',
secondary=parent_has_children,
back_populates='children'
)
parent_has_children = db.Table('parent_has_children', db.metadata,
db.Column('parent_id', db.Integer, ForeignKey('Parent.id')),
db.Column('child_id', db.Integer, ForeignKey('Child.id'))
)
我有很多关系,因此我使用的是辅助表。让我说我有一条接收child_id和parent_id并建立关系的路线:
@app.route('/buildrelationship', methods=['POST'])
def buildrelationship():
child_id= request.json['student_id']
parent_id = request.json['parent_id']
child = Child.query.get(child_id)
parent = Parent.query.get(parent_id)
parent.children.append(child)
db.session.commit()
这种方式我添加了一个孩子的父亲之间的关系,但我必须首先从数据库中获取父和子,然后添加关系。 request.json可能有一个子列表要附加到父级或父级列表o父级要附加到特定子级。在这种情况下,我必须查询列表长度的次数,以获取父级或子级,然后附加关系。是否有更好的方法来追加关系,而不是每次都加载父对象和子对象?
答案 0 :(得分:2)
可以减少查询,但是您希望尽可能地依赖ORM。如果您没有执行查询以将POSTed数据解析为Child或Parent对象,而是直接插入到M2M表中,则会显示id - 您可能会对数据库的完整性造成一些麻烦。
您只需触发一个更新查询 - 如果您首先在您的孩子列表中迭代一次,那么您最终可能会获得[Flags]
public enum ParallelScope
{
None, // the test may not be run in parallel with other tests
Self, // the test itself may be run in parallel with other tests
Children, // child tests may be run in parallel with one another
Fixtures // fixtures may be run in parallel with one another
}
列表,那么您可以children = [Child<1>, Child<2>, Child<3>]
如果,你真的每个POST处理数十/数十万个子对象,时间,内存等实际上是一个问题,你可以翻转批量加载数据,几乎完全跳过ORM层和所有安全功能它可以帮助您。
首先,您需要获取当前子对象的列表,这样您才能确保不会导致完整性错误(再次,安全手套已关闭,如果您正在做的话,您会很奇怪这没有充分的理由)。
Parent.children.append(children)
接下来,您将获得已发布的子ID ID列表:
existing = {x.id for x in Child.query.all()}
# lets say: existing = {1,3,4,5,6}
因此,我们现在可以过滤实际需要插入的内容,清理可能导致我们麻烦的任何事情:
target = request.json['student_id']
# lets say target = [1,2,3,3,3]
构建字典列表以表示我们的M2M表数据:
children_to_insert = {x for x in target if x in existing}
# active_children = {1,3}
我已经跳过了你想要的所有其他完整性检查(父母是否存在?它是否已经有了孩子?)但是你希望得到这一点,即只使用ORM并且不要试图四处走动它没有很好的理由回来了。