* Код не завершен, но достаточен для выражения проблемы.
Допустим, у нас есть две модели в отношении один ко многим (где Parent
может иметь много Child
):
class Child(db.Model):
__table_args__ = unique by child's name and parent id
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String)
parent = db.relationship(Parent)
class Parent(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String, unique=True)
Итак, в этом мире родители уникальны по именам, а ребенок уникален по имени и идентификатору родителя.Я хочу написать метод массовой вставки Child
моделей и получил что-то вроде этого:
def bulk_insert(parent_child_list):
for parent_name, child_name in parent_child_list:
parent = Parent.query.filter_by(name=parent_name).first()
if parent:
child = Child(name=child_name, parent=parent)
else:
child = Child(name=child_name, parent=Parent(name=parent_name))
Однако проблема возникает при попытке массовой вставки Child
моделей с одинаковыми Parent
имена (например, bulk_insert([("john", "alex"), ("john", "kris")])
), поскольку метод попытается вставить несколько моделей Parent
с одним и тем же именем, тем самым нарушая ограничение уникальности.Это происходит потому, что фиксация сеанса является внешней по отношению к bulk_insert
.
Один из способов сделать это - сначала вставить все уникальные модели Parent
и зафиксировать, а затем вставить все уникальные модели Child
.Тем не менее, есть ли более простой способ сделать эту работу в Flask SqlAlchemy без этой пользовательской логики?Это похоже на проблему с управлением сеансом, поэтому я подозреваю, что мне чего-то не хватает в sqlalchemy, что может помочь с этим.