Python 炼金术——一个模型有两种不同的关系

Python 炼金术——一个模型有两种不同的关系,python,flask-sqlalchemy,Python,Flask Sqlalchemy,我有三个模型:角色、用户和帖子。角色->用户是一对多,用户->帖子是一对多。当我有用户和帖子时,一切都正常。然而,我的网站将需要不同程度的授权 类别角色B.型号: id=db.Columndb.Integer,主键=True users=db.relationship'User',backref='role',lazy=True 类Userdb.Model,UserMixin: id=db.Columndb.Integer,主键=True role\u id=db.Columndb.Intege

我有三个模型:角色、用户和帖子。角色->用户是一对多,用户->帖子是一对多。当我有用户和帖子时,一切都正常。然而,我的网站将需要不同程度的授权

类别角色B.型号: id=db.Columndb.Integer,主键=True users=db.relationship'User',backref='role',lazy=True 类Userdb.Model,UserMixin: id=db.Columndb.Integer,主键=True role\u id=db.Columndb.Integer,db.ForeignKey'role.id',nullable=False posts=db.relationship'Post',backref='author',lazy=True 类Postdb.Model: id=db.Columndb.Integer,主键=True user\u id=db.Columndb.Integer,db.ForeignKey'user.id',nullable=False 以下是我收到的错误消息:

sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) 
no such column: user.role_id

谢谢

您不需要显式定义role_id字段-role中定义的关系和您指定的backref参数已经为您在用户对象上创建了向后关系。炼金术可能对你有帮助

同样地,如果您有一个实例化的用户对象u,那么您应该能够通过u.role获得关于用户角色的详细信息,它将为您提供一个角色实例和作为u.role.ID的角色ID

因此,您的全套模型定义只需如下所示:

class Role(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    users = db.relationship('User', backref='role', lazy=True)


class User(db.Model, UserMixin):
    id = db.Column(db.Integer, primary_key=True)
    posts = db.relationship('Post', backref='author', lazy=True)


class Post(db.Model):
    id = db.Column(db.Integer, primary_key=True)

如果您这样做,那么对于Post对象p,您可以获得Post作者角色的id,例如p.author.role.id。

Cool!好的,但是为什么后期模型中的用户id以前会工作呢?老实说?我不知道为什么一个案例有效,而另一个案例无效,但我也不会浪费太多时间试图弄清楚这一点,因为有一种更标准、更预期的方式来完成你正在尝试的事情也就是说,如果要向模型中添加新字段,是在其间擦除数据库,还是让SQLAlchemy更新其模式?可能是因为数据库中的实际表仍然具有最初创建用户模型时的模式,并且没有角色模型。因此我实际上尝试了更新它,它添加了角色模型,但它仍然说找不到User_Role.id列。。。。奇怪的不过我很感谢你的帮助,我在网上关注这个系列,因为我不擅长这个东西,所以我一字不差地关注他的教程。我现在写完了,还得到了一本更深入的书,所以我真的在努力理解事情是如何运作的,因为语法一直在变化。所以我拿出了你对我说的,但最终得到sqlalchemy.exc.NoForeignKeysError:无法确定关系Role.users上的父/子表之间的联接条件-没有外键链接这些表。确保引用列与ForeignKey或ForeignKeyConstraint关联,或指定“primaryjoin”表达式。有什么想法吗?