SQLAlchemy 对象已附加到会话

新手上路,请多包涵

我试图让一个应用程序的服务器正常工作,但我在登录时遇到错误:

 [!] Object '<User at 0x7f12bc185a90>' is already attached to session '2' (this is '3')

看来我要添加的会话已经在数据库中了。这是导致问题的代码片段:

 @app.route('/login', methods=['POST'])
def login():
    u = User.query.filter(User.username == request.form["username"]).first()
    if not u or u.password != request.form["password"]:
        return error("E1")

    s = Session.get_by_user(u)
    if s is not None:
         db_session.delete(s)
         db_session.commit()

     print db_session.execute("SELECT * FROM sessions").fetchall()

     s = Session(u)
     db_session.add(s)
     db_session.commit()

     return jsonify(s.values)

如您所见,在尝试添加任何内容之前,我正在打印会话表中的内容,但它是空的! ([])

还有什么可能导致这个?

这是“会话”的实现:

 class Session(Base):
__tablename__ = "sessions"
id = Column(Integer, primary_key=True)
user_id = Column(Integer, ForeignKey('users.id'), unique=True)
user = relationship(User)
key = Column(String(50), unique=True)
created = Column(DateTime)

def __init__(self, user=None):
    self.user = user
    self.key = base64.encodestring(os.urandom(24)).strip()
    self.created = datetime.now()

def __repr__(self):
    return '<Session %r>' % (self.key)

@property
def values(self):
    return {"username" : self.user.username,
            "key" : self.key,
            "created" : str(self.created),
            }
@classmethod
def get_by_key(cls, key):
    s = cls.query.filter(cls.key == key).first()
    #print datetime.now() - s.created
    if s and datetime.now() - s.created > settings.SESSION_LIFETIME:
        s = None
    return s

@classmethod
def get_by_user(cls, user):
    s = cls.query.filter(cls.user == user).first()
    if s and datetime.now() - s.created > settings.SESSION_LIFETIME:
        s.query.delete()
        db_session.commit()
        s = None
    return s

原文由 sazr 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 637
1 个回答

正如@marcinkuzminski 提到的,您不能添加已附加到另一个会话的对象。但是,如果您不确定该会话起源于您当前正在操作的同一线程上下文,那么仅使用 object_session() 从对象中拉入原始会话是有风险的。线程安全的方法是使用 合并()

     local_object = db_session.merge(original_object)
    db_session.add(local_object)
    db_session.commit()

原文由 Turn 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏