Я уверен, что есть простое решение этой проблемы, но я не смог его найти или подумать. У меня есть модель «Запись», которая должна быть последовательной друг с другом (например, запись 1 может быть первой частью сообщения в блоге, запись 2 — второй частью и т. д.)
class Entry(db.Model):
__tablename__ = "entry"
id = db.Column(db.Integer, primary_key=True)
...
prev_entry_id = db.Column(db.Integer, db.ForeignKey('entry.id'))
next_entry_id = db.Column(db.Integer, db.ForeignKey('entry.id'))
prev_entry = db.relationship("Entry", backref='next', remote_side='entry.id', foreign_keys=[prev_entry_id]) #previous_entry object
next_entry = db.relationship("Entry", backref = "previous", uselist=False, foreign_keys=[next_entry_id]) #next_entry object
Идея состоит в том, что если вы получаете одну запись, скажем, запись-56, вы можете перемещаться вперед (57) и назад (55), шаг за шагом, до конца, как если бы это был указатель.
Однако я получаю массу ошибок от sqlalchemy:
Table has no attribute 'id'
Если я закомментирую "prev_entry", я получу:
sqlalchemy.exc.InvalidRequestError: One or more mappers failed to initialize - can't proceed with initialization of other mappers. Triggering mapper: 'mapped class Entry->entry'. Original exception was: 'Table' object has no attribute 'id'
Если я закомментирую обе "next_*entry", я получу: Table has no attribute 'id'
Если я закомментирую и «next_entry»*, и «prev_entry», он как минимум загрузится.
Короче говоря, кто-нибудь знает, как правильно настроить это в Flask-SqlAlchemy?
Ошибка «нет идентификатора атрибута» возникает из-за того, что SQLAlchemy интерпретирует 'entry.id'
как ссылку на базовый Table
объект, а не на модель. Исправьте это, используя 'Entry.id'
(ссылка на модель) или 'entry.c.id'
(ссылка на таблицу).
Кроме того, используйте back_populates
вместо backref
для настройки обратных отношений:
prev_entry = db.relationship(
'Entry',
back_populates='next_entry',
remote_side='Entry.id',
foreign_keys=[prev_entry_id],
) # previous_entry object
next_entry = db.relationship(
'Entry',
back_populates='prev_entry',
uselist=False,
foreign_keys=[next_entry_id],
) # next_entry object