SQLAlchemy InvalidRequest 添加到关系集合
Posted
技术标签:
【中文标题】SQLAlchemy InvalidRequest 添加到关系集合【英文标题】:SQLAlchemy InvalidRequest on adding to relationship collection 【发布时间】:2013-05-20 09:11:11 【问题描述】:我在我的 Flask 项目中添加了一种“迁移”功能。最初我想添加与以下多对多相关的用户和角色:
users_to_roles_association_table = db.Table('users_to_roles',
db.Column('user_id', db.Integer, db.ForeignKey('users.id')),
db.Column('role_id', db.Integer, db.ForeignKey('roles.id')))
class User(db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, db.Sequence('user_id_seq'), primary_key=True)
..................
roles = relationship('Role', secondary=users_to_roles_association_table, lazy='dynamic')
class Role(db.Model):
__tablename__ = 'roles'
id = db.Column(db.Integer, db.Sequence('role_id_seq'), primary_key=True)
rolename = db.Column(db.String(128), unique=False)
..................
这是我的迁移up
方法:
def up(self):
try:
user = User.query.filter_by(nickname='alp').first()
if not user:
user = User(email='some@email.com', nickname='admin', status=USER.Active)
password = raw_input("Input password for user %s: " % user.nickname)
user.set_password(password)
db.session.add(user)
role = Role.query.filter_by(rolename='Admin').first()
if not role:
role = Role(rolename='Admin')
db.session.add(role) //HERE
if not user.is_in_role('Admin'):
user.roles.append(role)
except Exception, e:
print "Rolling back changes"
db.session.rollback()
raise
当我运行它时,我遇到了一个异常:sqlalchemy.exc.InvalidRequestError: Object '<Role at 0x331db50>' is already attached to session '3' (this is '2')
如果我注释掉db.session.add(role)
行,错误就消失了,但Role
不会添加到数据库中。
我需要这个逻辑,因为其他一些记录可能在表中,所以我不能保证数据库中不存在特定角色。
如何处理这个错误?
【问题讨论】:
在向会话中添加任何内容之前尝试执行您的选择查询(即将role = Role.query...
行移到user = User.query
下方)- 有帮助吗?
@DazWorrall,比你的建议,但我试过了。无论如何 - 我找到了解决方案,它与 db
变量有关。
【参考方案1】:
我找到了解决方案。由于对内部 Flask 架构的了解不足,我似乎踩到了耙子。
在我的迁移文件(我使用Flask-Evolution
)的顶部有几行:
db = SQLAlchemy(current_app)
db.metadata.bind = main.db.engine
我使用这个变量db
来操作我的记录,但由于未知原因,它有自己的会话与我的不同(我在main.py
中定义了我自己的数据库处理程序:db = SQLAlchemy(app)
)。当我用main.db.session...
替换像db.session....
这样的行时,一切都变得正常了。如果有人能解释这种情况,我会很高兴。
【讨论】:
你现在可能已经明白了,但是SQLAlchemy
来自 Flask-SQLAlchemy,它与 SQLAlchemy 本身不同。虽然第二行可能会让您的绑定正确排列,但当您实例化 (Flask-)SQLAlchemy
两次时,您可能仍会获得第二个会话。在我们的应用程序中,我们在配置期间实例化一次SQLAlchemy
,并在应用程序的其余部分使用相同的 db 变量。我会把from main import db
放在你需要SQLAlchemy
对象的任何地方,而不是db = SQLAlchemy(current_app)
。以上是关于SQLAlchemy InvalidRequest 添加到关系集合的主要内容,如果未能解决你的问题,请参考以下文章
flask-sqlalchemy 和sqlalchemy的区别
sqlalchemy.exc.NoSuchModuleError:无法加载插件:sqlalchemy.dialects:postgres