#python #sqlalchemy #flask-sqlalchemy
Вопрос:
В следующих примерах кода ChatMessage
модель имеет обязательное поле converstaion_id
, которое определяет связь с ChatConversation
этой моделью. ChatConverstation
модель имеет поле last_message_id
, которое является ссылкой на последнее ChatMessage
.
Я получаю следующее сообщение об ошибке sqlalchemy
и не знаю, как решить эту проблему. Пожалуйста, помогите.
sqlalchemy.exc.InvalidRequestError: При инициализации сопоставления сопоставленного класса ChatConversation->chat_conversation выражению «ChatMessage» не удалось найти имя («ChatMessage»). Если это имя класса, подумайте о добавлении этой связи() вChatConversation’> класс после определения обоих зависимых классов.
Как я должен определить схему для этих моделей, чтобы я мог установить обе взаимосвязи (т. Е. conversation
отношения в ChatMessage
модели и last_message
отношения в ChatConversation
модели) ?
class ChatConversation(db.Model):
__tablename__ = 'chat_conversation'
id = db.Column(db.Integer, primary_key=True)
last_message_id = db.Column(
db.Integer,
db.ForeignKey("chat_message.id", ondelete='SET NULL'),
nullable = True
)
last_message = db.relationship('ChatMessage')
class ChatMessage(db.Model):
__tablename__ = 'chat_message'
id = db.Column(db.Integer, primary_key=True)
conversation_id = db.Column(
db.Integer,
db.ForeignKey("chat_conversation.id", ondelete='CASCADE'),
nullable=False
)
conversation = db.relationship('ChatConversation')
Комментарии:
1. У вас не может быть циклических ссылок на внешние ключи. Не допускается. Отчасти это сделало бы невозможным безопасное удаление некоторых записей. Вы можете сделать его целым числом.
2. Если я удалю ограничение внешнего ключа
last_message_id
, смогу ли я заполнять данные вlast_message
отношениях без каких-либо проблем?3. Я верю в это, но вам придется делать это как целое число, а не как
ChatMessage
экземпляр.4. Спасибо, что предупредили. Я определил отношения с помощью
hybrid_propery
.
Ответ №1:
Решение состоит в том, чтобы использовать hybrid_property
декоратор метода из sqlalchemy
и foreign_keys
явно определить, чтобы устранить неоднозначность ForeignKey
.
from sqlalchemy.ext.hybrid import hybrid_property
class ChatConversation(db.Model):
__tablename__ = 'chat_conversation'
id = db.Column(db.Integer, primary_key=True)
last_message_id = db.Column(
db.Integer,
db.ForeignKey("chat_message.id", ondelete='SET NULL'),
nullable = True
)
@hybrid_property
def last_message(self):
return False if not self.last_message_id else ChatMessage.query.get(self.last_message_id)
class ChatMessage(db.Model):
__tablename__ = 'chat_message'
id = db.Column(db.Integer, primary_key=True)
conversation_id = db.Column(
db.Integer,
db.ForeignKey("chat_conversation.id", ondelete='CASCADE'),
nullable=False
)
conversation = db.relationship('ChatConversation', foreign_keys = [conversation_id])