Flask SQLAlchemy - 需要帮助将3个类映射到一起

时间:2013-07-16 06:07:36

标签: python sqlalchemy flask flask-sqlalchemy flask-extensions

所以我花了一些时间在这上面并继续在圈子里跑来跑去,所以我想我会来专家!

使用Flask 0.9SQLAlchemy 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 个答案:

答案 0 :(得分:3)

我认为你的数据库设置正确,你有两个一对多的关系,这看起来很好。

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