При объединении со связанными объектами новые отношения не сохраняются - PullRequest
1 голос
/ 11 марта 2019

Я столкнулся с некоторым странным поведением с моими моделями SQLAlchemy, когда я пытаюсь обновить данные.У меня есть отношение один ко многим, определенное так:

app = Flask(__name__)
app.config[
    "SQLALCHEMY_DATABASE_URI"
] = "postgresql://geonatadmin:monpassachanger@localhost:5432/geonature2db_test"
app.debug = True
DB = SQLAlchemy(app)


class Child(DB.Model):
    __tablename__ = "Child"

    id_child = DB.Column(DB.Integer, primary_key=True)
    id_parent = DB.Column(DB.Integer, ForeignKey("Parent.id_parent"))
    name = DB.Column(DB.Unicode(50))


class Parent(DB.Model):
    __tablename__ = "Parent"

    id_parent = DB.Column(DB.Integer, primary_key=True)
    name = DB.Column(DB.Unicode(50))

    childrens = relationship("Child", lazy="joined", cascade="all, delete-orphan")

DB.create_all()

Я пытаюсь обновить Parent и Child из JSON, отправленного из моего API.В моем примере у родителя уже есть один ребенок, и я пытаюсь добавить к нему двух новых детей:

with app.app_context():
    first_json = {"name": "parent1", "childrens": [{"name": "john"}]}
    childrens = first_json.pop("childrens")
    parent = Parent(**first_json)
    for child in childrens:
        parent.childrens.append(Child(**child))

    DB.session.add(parent)
    DB.session.commit()
    DB.session.flush()

    second_json = {
        "id_parent": 1,
        "name": "parent1",
        "childrens": [
            {"id_child": 1, "name": "john"},
            {"id_child": None, "name": "foo"},
            {"id_child": None, "name": "bar"},
        ],
    }
    childrens = second_json.pop("childrens")
    parent = Parent(**second_json)
    for child in childrens:
        parent.childrens.append(Child(**child))

    DB.session.merge(parent)
    DB.session.commit()

Наконец, в моей базе данных есть только ребенок 1 и ребенок 3.Дочерний объект 2 никогда не добавляется.

Я пытался получить больше информации о фактическом SQL, выдаваемом с этой конфигурацией:

current_app.config["SQLALCHEMY_ECHO"] = True

, и действительно, для дочернего элемента 2. нет оператора INSERT.

1 Ответ

1 голос
/ 13 марта 2019

В конце концов я понял, что если я удалю 'id_child ", когда он отсутствует, слияние будет работать нормально. Вот так:

second_json = {
    "id_parent": 1,
    "name": "parent1",
    "childrens": [
        {"id_child": 1, "name": "john"},
        {"name": "foo"},
        {"name": "bar"},
    ],
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...