Flask SQLAlchemy - нужна помощь в сопоставлении 3 классов
Так что я потратил некоторое время на это и продолжаю бегать кругами и никуда не денусь, поэтому решил, что приду к экспертам!
С помощью Flask 0.9
а также SQLAlchemy 0.7.9
Я пытаюсь создать страницу галереи с коллекцией галерей. Каждая галерея имеет коллекцию под-галерей, и каждая под-галерея имеет коллекцию фотографий. Моя первая попытка, показанная ниже, явно не работает:
class Gallery(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(64))
subgals = db.relationship('SubGallery', backref='author', lazy='dynamic')
def __repr__(self):
return '<Gallery - %r>' % (self.title)
class SubGallery(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(64))
photos = db.relationship('Photo', backref='author', lazy='dynamic')
gallery_id = db.Column(db.Integer, db.ForeignKey('gallery.id'))
def __repr__(self):
return '<Gallery - %r>' % (self.title)
class Photo(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(64))
href = db.Column(db.String(128))
subgallery_id = db.Column(db.Integer, db.ForeignKey('subgallery.id'))
def __repr__(self):
return '<Photo - %r>' % (self.title)
и возвращает эту ошибку:
sqlalchemy.exc.ArgumentError: Could not determine join condition between parent/child tables on relationship SubGallery.photos. Specify a 'primaryjoin' expression. If 'secondary' is present, 'secondaryjoin' is needed as well.
Я изучал альтернативные конфигурации отношений, но не уверен на 100%, что мне нужно. Моя кишка говорит мне, что мне нужно Adjacency Relationship
но я не смог далеко продвинуться с этим. Я пробовал много-много картирование, но я не видел много материала, как сопоставить 3 класса вместе.
Я ДЕЙСТВИТЕЛЬНО ценю любой вклад и понимание, которое вы все можете предложить с этим, и спасибо!!
1 ответ
Я думаю, что ваша база данных настроена правильно, у вас есть два отношения "один ко многим", и это выглядит нормально.
Ошибка "не удалось определить..." в SQLAlchemy просто говорит о том, что в вашей модели недостаточно информации для SQLAlchemy, чтобы выяснить, каково условие соединения для отношений между подгалереей и таблицами фотографий.
SQLAlchemy пытается многое угадать, исходя из того, как вы называете вещи, она ожидает согласованности. Я считаю, что в этом случае он не находит то, что ему нужно из-за использования вами верблюжьего чехла SubGallery
,
Как можно предположить в сообщении об ошибке, можно добавить primaryjoin
аргумент отношения и тогда SQLAlchemy будет счастлив, иначе вы можете изменить свои имена, чтобы помочь SQLAlchemy понять это самому.
Я изменил ваши определения, переименовав SubGallery
в "Subgallery", и это, кажется, работает. Ниже представлены модифицированные модели:
class Gallery(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(64))
subgals = db.relationship('Subgallery', backref='author', lazy='dynamic')
def __repr__(self):
return '<Gallery - %r>' % (self.title)
class Subgallery(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(64))
photos = db.relationship('Photo', backref='author', lazy='dynamic')
gallery_id = db.Column(db.Integer, db.ForeignKey('gallery.id'))
def __repr__(self):
return '<Gallery - %r>' % (self.title)
class Photo(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(64))
href = db.Column(db.String(128))
subgallery_id = db.Column(db.Integer, db.ForeignKey('subgallery.id'))
def __repr__(self):
return '<Photo - %r>' % (self.title)
И я использовал этот маленький быстрый и грязный тестовый скрипт, чтобы убедиться, что отношения работали:
db.create_all()
g = Gallery(title = "a")
db.session.add(g)
db.session.commit()
sg = Subgallery(title = "a1", author = g)
db.session.add(sg)
db.session.commit()
p = Photo(title = "a1p", href="href", author = sg)
db.session.add(p)
db.session.commit()
for subgal in g.subgals.all():
print subgal
print subgal.author
for photo in subgal.photos.all():
print photo
print photo.author