【问题标题】:Flask SQLalchemy many-to-many relationship, need secondaryjoin and primaryjoin for some reasonFlask SQLalchemy多对多关系,由于某种原因需要secondaryjoin和primaryjoin
【发布时间】:2015-01-20 03:53:38
【问题描述】:

在 SQLAlchemy 文档中,http://docs.sqlalchemy.org/en/rel_0_9/orm/relationships.html 一切正常,但我收到一个名为

的错误

最初的例外是:无法确定关系 User.rank_r 上的父/子表之间的连接条件。指定一个“primaryjoin”表达式。如果存在“secondary”,则还需要“secondaryjoin”。

class User(db.Model, UserMixin):

    __tablename__ = 'users'
    rank_r = db.relationship('Rank', 
                               secondary=ranks, 
                               backref=db.backref('users', lazy='dynamic'))


class Rank(db.Model):
    __tablename__ = 'rank'
    id = Column(db.Integer, primary_key=True)
    name = Column(db.String(STRING_LEN), nullable=False, unique=True)


ranks = db.Table('ranks',    
    db.Column('rank_id', db.Integer, db.ForeignKey('rank.id')),
    db.Column('user_id', db.Integer, db.ForeignKey('users.id'))
)

基本上我正在尝试这样做:

SELECT u.id, u.name, r.name users u INNER JOIN ranks r ON r.id=rr.rank_id INNER JOIN rank rr ON rr.user_id==u.id 

这将返回如下内容:

1 Bob Major
2 Joey Captain
3 Adam Brigadier General

这个关系代码似乎也失败了:

rank_r = db.relationship('Rank', 
                           primaryjoin="(rank.c.id==ranks.c.rank_id)",
                           secondary="ranks", 
                           secondaryjoin="(id==ranks.c.user_id)",
                           backref=db.backref('users', lazy='dynamic'))

有错误:

StatementError: No column rank.id is configured on mapper Mapper|User|users...(原始原因:UnmappedColumnError: No column rank.id is configured on mapper|User|users...)'SELECT rank. id AS rank_id, rank.name AS rank_name \nFROM rank, rank, users \nWHERE ? = ranks.rank_id AND users.id = ranks.user_id' [immutabledict({})]

这是我尝试在模板中调用“User.rank_r”时显示的内容。

【问题讨论】:

  • 一个人拥有多个等级并不常见——您确定需要多对多表,而不仅仅是一对多模式吗?
  • 我在想你是对的,船长不可能是少校。另一方面,我在考虑一个可能有更多模块/区域的系统,这意味着在某种程度上,你可以成为一个模块的队长,并在另一个模块中主修。

标签: flask sqlalchemy flask-sqlalchemy


【解决方案1】:

你的代码看起来不错,我删除了一些东西(只是为了减少我的导入),它似乎做了你想要的:

from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy


app = Flask(__name__)
app.secret_key = 'MOO.'
app.config["SQLALCHEMY_DATABASE_URI"] = 'sqlite://'  # In memory.
db = SQLAlchemy(app)


ranks = db.Table('ranks',
    db.Column('rank_id', db.Integer, db.ForeignKey('rank.id')),
    db.Column('user_id', db.Integer, db.ForeignKey('users.id'))
)

class User(db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String())
    ranks = db.relationship('Rank',secondary=ranks,
                               backref=db.backref('users', lazy='dynamic'))

    def __init__(self, name):
        self.name = name

    def __repr__(self):
        return self.name


class Rank(db.Model):
    __tablename__ = 'rank'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(), nullable=False, unique=True)

    def __repr__(self):
        return self.name

@app.route('/')
def hello_world():
    return 'Hello World!'


if __name__ == '__main__':
    with app.app_context():
        db.create_all()
        bob = User('Bob')
        joey = User('Joey')
        adam = User('Adam')

        major = Rank(name='Major')
        captain = Rank(name='Captain')
        general = Rank(name='General')

        db.session.add_all([bob, joey, adam, major, captain, general])

        bob.ranks.append(major)
        joey.ranks.append(captain)
        adam.ranks.append(general)
        adam.ranks.append(captain)

        db.session.commit()

        users = User.query.all()
        for user in users:
            for rank in user.ranks:
                print '{} {}'.format(user, rank)

                # Bob Major
                # Joey Captain
                # Adam Captain
                # Adam General

【讨论】:

  • 你介意描述一下你在这里做了什么吗?它可能在代码中工作,但阅读这个答案不是很好。
猜你喜欢
  • 2013-11-05
  • 2014-04-02
  • 1970-01-01
  • 1970-01-01
  • 2016-06-15
  • 2021-08-31
  • 1970-01-01
  • 1970-01-01
  • 2012-09-17
相关资源
最近更新 更多