Flask 在炼金术多对多关系中,出于某种原因需要二次连接和一次连接

Flask 在炼金术多对多关系中,出于某种原因需要二次连接和一次连接,flask,sqlalchemy,flask-sqlalchemy,Flask,Sqlalchemy,Flask Sqlalchemy,在SQLAlchemy文档中,一切都应该正常工作,但我得到一个名为 原始异常是:无法确定关系User.rank\r上的父/子表之间的联接条件。指定“primaryjoin”表达式。如果存在“secondary”,则还需要“secondaryjoin” class User(db.Model, UserMixin): __tablename__ = 'users' rank_r = db.relationship('Rank',

在SQLAlchemy文档中,一切都应该正常工作,但我得到一个名为

原始异常是:无法确定关系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'))
有误:

语句错误:映射器映射器|用户|用户上未配置列rank.id。。。(原始原因:未映射列错误:映射器上未配置列rank.id映射器|用户|用户…'选择rank.id作为rank | id,rank.name作为rank |名称\n从rank,ranks,users\n位置?=ranks.rank_id和users.id=ranks.user_id'[immutabledict({})]


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

您的代码似乎没问题,我删除了一些内容(只是为了减少导入),它似乎完成了您想要的操作:

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

一个人拥有多个军衔是不常见的——你确定你需要一个多对多的表格,而不仅仅是一对多的模式吗?我想你是对的,上尉不可能是少校。另一方面,我在考虑一个可能有更多模块/区域的系统,这意味着在某种程度上,你可以在一个模块中担任船长,在另一个模块中担任少校。你介意描述一下你在这里做了什么吗?它可能在代码中工作,但是阅读这个答案不是很好。