Flask-SQLAlchemy一对多关系报错:'Table'对象无'user_id'属性
解决Flask-SQLAlchemy中
AttributeError: 'Table' object has no attribute 'user_id'的问题 你的问题出在User模型里relationship的foreign_keys参数写法上。当你用字符串'game.user_id'时,SQLAlchemy会尝试访问名为game的Table对象的user_id属性,但Table对象的列是通过c属性来访问的,所以触发了这个错误。
修正后的代码
把User模型里的两个relationship的foreign_keys参数改成以下两种方式之一即可:
方式1:用模型类名+属性名的字符串形式(推荐,更直观)
class User(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(64), index=True, unique=True) # Games created by the user: created_games = db.relationship( 'Game', backref='author', lazy='dynamic', foreign_keys='Game.user_id') # Games as opponent: invitations = db.relationship( 'Game', backref='guest', lazy='dynamic', foreign_keys='Game.opponent_id')
方式2:用Table对象的列引用形式
class User(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(64), index=True, unique=True) # Games created by the user: created_games = db.relationship( 'Game', backref='author', lazy='dynamic', foreign_keys='game.c.user_id') # Games as opponent: invitations = db.relationship( 'Game', backref='guest', lazy='dynamic', foreign_keys='game.c.opponent_id')
原因解释
- 用
'Game.user_id'这种形式时,SQLAlchemy会识别这是模型Game的user_id属性,自动映射到对应的表列,这种写法更贴合ORM的使用习惯。 - 如果非要直接引用表对象,必须加上
.c前缀(比如game.c.user_id),因为Table对象的列集合是存储在c属性下的。
另外,由于你先定义User再定义Game,用字符串形式的模型类名是完全安全的,SQLAlchemy会在所有模型加载完成后自动解析这个引用。
修正后你就能正常实例化User对象了,之前的数据库迁移不需要重新执行——因为表结构本身没有变化,只是ORM层面的关系定义做了修正。
内容的提问来源于stack exchange,提问作者Julien A
相关产品推荐
相关产品推荐

