我正在尝试在此关联表中插入角色数据:
class Association(db.Model):
__tablename__ = 'associations'
user_id = db.Column(db.Integer, db.ForeignKey('users.id'), primary_key=True)
team_id = db.Column(db.Integer, db.ForeignKey('teams.id'), primary_key=True)
role = db.Column(db.String)
user = db.relationship("User", back_populates="teams")
team = db.relationship("Team", back_populates="users")
它与另外两个表相关联:
class User(db.Model, UserMixin):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String)
username = db.Column(db.String, nullable=False, unique=True, index=True)
password_hash = db.Column(db.String)
teams = db.relationship("Association", back_populates="user")
class Team(db.Model):
__tablename__ = 'teams'
id = db.Column(db.Integer, primary_key = True)
name = db.Column(db.String)
player = db.Column(db.String)
users = db.relationship("Association", back_populates="team")
但是,当我尝试在关联表中插入角色时:
t = Team.query.filter_by(id=team_name1_id).first()
a = Association(role=form.role.data)
a.user = User.query.filter_by(id=current_user.id).first()
t.users.append(a)
db.session.add(t)
db.session.commit()
我收到此错误:
IntegrityError :(由于Query-invoked autoflush引发; 如果发生此刷新,请考虑使用session.no_autoflush块 过早地)(sqlite3.IntegrityError)NOT NULL约束失败: association.team_id [SQL:u'INSERT INTO关联(user_id,role) VALUES(?,?)'] [参数:(1,u'point guard')]
你知道我该怎么办呢?
答案 0 :(得分:5)
导致autoflush的行是
education: *defaultEd
您尚未定义relationship loading strategies,因此默认为"select"
。由于您是第一次访问t.users.append(a)
关系属性,它将发出SELECT以获取相关对象。
您还在
中间接更改了会话Team.users
由save-update cascade引起,默认情况下为on,将新的a.user = User.query.filter_by(id=current_user.id).first()
实例放置到会话中。
为了保持数据库和会话的状态一致,SQLAlchemy必须flush在发出查询之前对数据库进行Temporarily disable the autoflush feature更改,因此在关联之前将半数初始化Association
发送到数据库使用Association
实例。
可能的解决方案:
eager load针对该特定附加内容,因为您知道自己正在添加新的Team
:
Association
但仍会发出SELECT。
撤消操作。不是将with db.session.no_autoflush:
t.users.append(a)
个实例附加到Association
集合,而是将Team.users
分配给Team
:
Association.team
当您获取# Instead of t.users.append(a):
a.team = t # Mr.
实例时,一个不太明显的解决方案是db.noload(Team.users)
关系的内容,因此不需要SELECT:
Team
或者根本不使用could not have proceeded选项加载它们。
请注意
t = db.session.query(Team).options(db.joinedload(Team.users)).first()
是多余的。提取的db.session.add(t)
实例已在会话中 - 否则首先是Team
{{3}}的延迟加载。