Flask-SQLAlchemy: обновить отношения один ко многим

У меня есть две модели:

class Project(db.Model):
    __tablename__ = 'project'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64))
    timestamp = db.Column(db.DateTime)
    info = db.Column(db.Text(255))

    post = db.relationship('Post', backref=db.backref('projects'))

class Post(db.Model):
    __tablename__ = 'post'

    id = db.Column(db.Integer, primary_key=True)
    headline = db.Column(db.String(64))
    content = db.Column(db.Text(255))
    timestamp = db.Column(db.DateTime)

    projectId = db.Column(db.Integer, db.ForeignKey('project.id'))

Если я, например, создаю экземпляр сообщения и добавляю его в проект через projectInstance.append(post(headline="...", content="..."))
Теперь я хочу обновить проект, к которому должен принадлежать пост. Есть ли более простой способ помимо запроса нужного проекта, добавить к нему сообщение и удалить его из старого проекта?

oldProject.remove(post)
newProject.append(post)

1 ответ

Решение

Сделайте это наоборот: используйте обратную ссылку в Post:

post.projects = newProject

Это будет обрабатывать необходимое управление сеансом. Вот минимальный пример:

In [2]: class A(Base):
   ...:     __tablename__ = 'a'
   ...:     id = Column(Integer, primary_key=True, autoincrement=True)
   ...:     bs = relationship('B', backref='a')
   ...:

In [3]: class B(Base):
   ...:     __tablename__ = 'b'
   ...:     id = Column(Integer, primary_key=True, autoincrement=True)
   ...:     a_id = Column(Integer, ForeignKey('a.id'))
   ...:

In [5]: a1 = A()

In [6]: a2 = A()

In [7]: b = B()

In [8]: a1.bs.append(b)

In [9]: a1.bs
Out[9]: [<__main__.B at 0x7f7322fb52b0>]

In [10]: b.a = a2

In [11]: a1.bs, a2.bs
Out[11]: ([], [<__main__.B at 0x7f7322fb52b0>])

Также просто добавив post экземпляр к newProject.post дескрипторы коллекции удаляются автоматически, как видно из наших as и bs:

In [9]: a1.bs.append(b)

In [10]: a1.bs, a2.bs
Out[10]: ([<__main__.B at 0x7f26702565f8>], [])

In [11]: a2.bs.append(b)

In [12]: a1.bs, a2.bs
Out[12]: ([], [<__main__.B at 0x7f26702565f8>])
Другие вопросы по тегам