添加到关系集合的SQLAlchemy InvalidRequest

时间:2013-05-20 09:11:11

标签: 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 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没有添加到数据库中。

我需要这个逻辑,因为其他一些记录可能在表中,所以我不能保证数据库中不存在特定的角色。

如何处理此错误?

1 个答案:

答案 0 :(得分:0)

我找到了解决方案。由于内部Flask架构知识不足,我似乎踩到了耙子。

在我的迁移文件的顶部(我使用Flask-Evolution),有一行:

db = SQLAlchemy(current_app)
db.metadata.bind = main.db.engine

我使用此变量db来操作我的记录,但由于未知的原因,它有自己的不同于我(我在main.py中定义了我自己的数据库处理程序:db = SQLAlchemy(app) ) 。当我用db.session....替换像main.db.session...这样的行时,一切正常。如果有人能解释这种情况,我会很高兴。