Мне нужна помощь с запросом модели, чтобы получить более глубокую связь. Животные это основной стол. Это должно легко загрузить imgs и истории, и это довольно просто. Но AnimalsStories имеет собственные imgs в той же таблице AnimalsImgs. AnimalsImgs имеет imgs для обоих классов Animals и AnimalsStories, и оба класса имеют с ним отношения. Так что я должен иметь возможность загружать всех Animals и их истории в AnimalsStories, а затем из этого класса я могу использовать .img attrubute, который ссылается на AnimalsImgs и содержит imgs для историй. SqlAlchemy говорят, что это возможно с подзапросом. И это. Но только два уровня вниз. AnimalsStories.img никогда не загружается.
class Animals(db.Model):
__tablename__ = 'animals'
id = db.Column(db.BigInteger, primary_key=True)
imgs = db.relationship("AnimalsImgs", backref=db.backref('animals',lazy=False))
stories= db.relationship("AnimalsStories",lazy='joined')
class AnimalsImgs(db.Model):
__tablename__ = 'animals_imgs'
id = db.Column(db.BigInteger, primary_key=True,autoincrement='auto')
id_animal = db.Column(db.BigInteger, db.ForeignKey('animals.id'),nullable=False)
class AnimalsStories(db.Model):
__tablename__='animals_stories'
id = db.Column(db.BigInteger, primary_key=True)
id_animal= db.Column(db.BigInteger,db.ForeignKey('animals.id'), nullable=False)
id_animal_img = db.Column(db.BigInteger,db.ForeignKey('animals_imgs.id'))
img=db.relationship("AnimalsImgs", uselist=False)
Я пробовал что-то вроде этого:
query = Animals.query.options(subqueryload(Animals.stories).subqueryload(AnimalsStories.img))
result = query.all()
print(result)
for res in result:
print(res.rescue.img)
И закончился "AttributeError: у объекта" InstrumentedList "нет атрибута" img "" Запрос должен быть довольно простымболее глубокие объекты. Я думаю, что проблема где-то в модельных структурах.
Правка # 1 Я закончил с решением. Это было не так сложно. Животные относятся к истории как один ко многим. Истории ссылаются на Imgs как один к одному. Таким образом, с запросом, который я разместил (с подзапросом), это может быть сделано:
query = Animals.query.options(subqueryload(Animals.stories).subqueryload(AnimalsStories.img))
result = query.all()
print(result)
for res in result:
print(res.stories)
for r in res.stories: # stories appears as array so they are iterable
print(r.img)
И он печатает все уровни довольно ясно. с присоединением. Мы уверены, что в результате не будет отсутствующих или пустых массивов.
query = Animals.query.join(AnimalsStories).join(AnimalsImgs)