Orm SQLAlchemy InvalidRequest关于添加到关系集合
我正在为我的Flask项目添加某种“迁移”功能。最初,我希望通过以下方式添加与多对多相关的用户和角色:Orm SQLAlchemy InvalidRequest关于添加到关系集合,orm,sqlalchemy,flask,Orm,Sqlalchemy,Flask,我正在为我的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
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:对象“”已附加到会话“3”(这是“2”)
如果我注释掉了行db.session.add(role)
错误消失了,但role
没有添加到数据库中
我需要这种逻辑,因为表中可能有其他一些记录,所以我无法保证数据库中不存在特定的角色
如何处理这个错误?我找到了解决方法。我似乎是因为对内部烧瓶架构的了解不足而踩上了耙子 在迁移文件的顶部(我使用
Flask Evolution
),有几行:
db = SQLAlchemy(current_app)
db.metadata.bind = main.db.engine
我使用这个变量db
来操作我的记录,但由于未知的原因,它有自己不同于我的sesion(我在main.py
中定义了自己的数据库处理程序:db=SQLAlchemy(app)
)。当我用main.db.session…
替换像db.session…
这样的行时,所有这些都可以正常工作。如果有人能解释这种情况,我会很高兴的。在向会话添加任何内容之前尝试执行您的选择查询(即将role=role.query…
行移到user=user.query
)下面-这有帮助吗?@DazWorrall,比您寻求建议,但我试过了。无论如何-我找到了解决方案,它与db
变量有关。您现在可能已经明白了这一点,但SQLAlchemy
来自Flask-SQLAlchemy,它与SQLAlchemy本身不同。虽然第二行可以正确地排列绑定,但是当您实例化(Flask-SQLAlchemy
两次时,您可能仍然会得到第二个会话。在我们的应用程序中,我们在配置期间实例化一次SQLAlchemy
,并在应用程序的其余部分使用相同的db变量。我会把主导入数据库中的放到需要SQLAlchemy
对象的任何地方,而不是db=SQLAlchemy(当前的应用程序)
。