Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python SQLAlchemy对象已附加到会话_Python_Session_Python 2.7_Sqlalchemy_Flask Sqlalchemy - Fatal编程技术网

Python SQLAlchemy对象已附加到会话

Python SQLAlchemy对象已附加到会话,python,session,python-2.7,sqlalchemy,flask-sqlalchemy,Python,Session,Python 2.7,Sqlalchemy,Flask Sqlalchemy,我正在尝试让应用程序的服务器工作,但登录时出错: [!] Object '<User at 0x7f12bc185a90>' is already attached to session '2' (this is '3') 如您所见,在尝试添加任何内容之前,我正在打印sessions表中的内容,而它是空的!([]) 还有什么原因可能导致这种情况 以下是“会话”实现: class Session(Base): __tablename__ = "sessions" id = Colum

我正在尝试让应用程序的服务器工作,但登录时出错:

[!] Object '<User at 0x7f12bc185a90>' is already attached to session '2' (this is '3')
如您所见,在尝试添加任何内容之前,我正在打印sessions表中的内容,而它是空的!([])

还有什么原因可能导致这种情况

以下是“会话”实现:

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
课堂会话(基本):
__tablename=“sessions”
id=列(整数,主键=True)
user_id=Column(整数,ForeignKey('users.id'),unique=True)
用户=关系(用户)
key=Column(字符串(50),unique=True)
已创建=列(日期时间)
定义初始化(self,用户=None):
self.user=用户
self.key=base64.encodestring(os.uradom(24)).strip()
self.created=datetime.now()
定义报告(自我):
返回“”%(self.key)
@财产
def值(自身):
返回{“username”:self.user.username,
“键”:self.key,
“已创建”:str(自创建),
}
@类方法
def通过按键获取按键(cls,按键):
s=cls.query.filter(cls.key==key).first()
#打印datetime.now()-s.created
如果是s和datetime.now()-s.created>settings.SESSION\u生命周期:
s=无
返回s
@类方法
def按用户获取(cls,用户):
s=cls.query.filter(cls.user==user.first()
如果是s和datetime.now()-s.created>settings.SESSION\u生命周期:
s、 query.delete()
db_session.commit()
s=无
返回s

您试图修改的对象已附加到另一个会话。 可能您有错误的导入,而db_会话是一个新实例

一个很好的解决方法是提取当前绑定会话并使用它:

而不是:

db_session.add(s)
做:


如果让server.py和model.py相互导入,则会出现此db会话问题

server.py

from flask import Flask
import os
import models as appmod #################### importing models here in server.py<----------

app = Flask(__name__)                                  # L1
app.config.from_object(os.environ['APP_SETTINGS'])     # L2
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False   # L3
database = SQLAlchemy(app)                             # L4
db = database                                          # L5

@app.route('/item_delete/<id>', methods=['DELETE'])
def remove_method(id = None):
    data_rec = appmod.Employee.query.get(id)    
    db.session.delete(data_rec)
    db.session.commit()
    return "DELETE"

if __name__ == '__main__':

    app.run(port=5000, host='0.0.0.0',debug=True,threaded=True)
from flask import Flask
import os
import models as appmod 
from settings import app, db


@app.route('/item_delete/<id>', methods=['DELETE'])
def remove_method(id = None):
    data_rec = appmod.Employee.query.get(id)    
    db.session.delete(data_rec)
    db.session.commit()
    return "DELETE"

if __name__ == '__main__':

    app.run(port=5000, host='0.0.0.0',debug=True,threaded=True)
models.py

from server import db #################### importing server in models.py here <------------
from sqlalchemy.dialects.mysql import JSON


class Employee(db.Model):
    __tablename__ = 'employe_flask'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(128))
    datetime = db.Column(db.DateTime)
    designation = db.Column(db.String(128))


    def __init__(self, name, datetime, designation):
        self.name = name
        self.datetime = datetime
        self.designation = designation

    @staticmethod
    def delete_rec(data_rec):
        db.session.delete(data_rec)#.delete
        db.session.commit()

    def __repr__(self):
        record = {"name":self.name,"date":self.datetime.ctime(),"designation":self.designation}.__str__()
        return record
from settings import db
from sqlalchemy.dialects.mysql import JSON


class Employee(db.Model):
    __tablename__ = 'employe_flask'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(128))
    datetime = db.Column(db.DateTime)
    designation = db.Column(db.String(128))


    def __init__(self, name, datetime, designation):
        self.name = name
        self.datetime = datetime
        self.designation = designation

    @staticmethod
    def delete_rec(data_rec):
        db.session.delete(data_rec)#.delete
        db.session.commit()

    def __repr__(self):
        record = {"name":self.name,"date":self.datetime.ctime(),"designation":self.designation}.__str__()
        return record

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

我也有这个问题。 我创建了一个test_file.py并添加了以下代码:

from app import app
from models import Tovar  
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy(app)

tovardel = Tovar.query.filter(Tovar.region == 1 and Tovar.price == 12).first()
db.session.delete(tovardel)
tovar = Tovar.query.filter(Tovar.region == 1 and Tovar.price == 12).first()
print(tovar.description)
当我运行代码时,我得到了这个错误:

Object '<Tovar at 0x7f09cbf74208>' is already attached to session '1' (this is '2')
对象“”已附加到会话“1”(这是“2”)
解决问题:


例如,如果您在text_file.py和app.py中有
db=SQLAlchemy(app)
,您就会一直遇到这个问题。您应该del
db=SQLAlchemy(app)
,并从app
从app import db导入db
此错误表示您正在处理的记录附加到两个不同的会话(
db

其中一个原因是,您可以使用一个
db=SQLAlchemy(app)
定义您的模型,并使用另一个添加/插入/修改数据库

我的解决方案是统一数据库

试试这个:

u = db.session.query(User).filter(User.username == request.form["username"]).first()
与此相反:

u = User.query.filter(User.username == request.form["username"]).first()

在这种情况下,
s
是什么?正在插入的对象?我们如何通过传入一个对象来获取当前会话?s是查询中的一个对象,例如s=db_session.query(OrmObject)。首先()在执行此操作之前,您不需要确保自己处于同一线程中吗?这个答案还解决了不
update
问题,
db.session.commit()
update
util应用此解决方案
from app import app
from models import Tovar  
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy(app)

tovardel = Tovar.query.filter(Tovar.region == 1 and Tovar.price == 12).first()
db.session.delete(tovardel)
tovar = Tovar.query.filter(Tovar.region == 1 and Tovar.price == 12).first()
print(tovar.description)
Object '<Tovar at 0x7f09cbf74208>' is already attached to session '1' (this is '2')
u = db.session.query(User).filter(User.username == request.form["username"]).first()
u = User.query.filter(User.username == request.form["username"]).first()