Orm SQLAlchemy InvalidRequest关于添加到关系集合

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

我正在为我的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:对象“”已附加到会话“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(当前的应用程序)