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
Другие вопросы по тегам