Flask SqlAlchemy для объемных вставок с уникальными ограничениями - PullRequest
0 голосов
/ 04 июня 2019

* Код не завершен, но достаточен для выражения проблемы.

Допустим, у нас есть две модели в отношении один ко многим (где 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, что может помочь с этим.

...