Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/330.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_Sqlalchemy - Fatal编程技术网

Python SQLAlchemy-对象“;已出席本次会议”;对旧对象使用新会话时

Python SQLAlchemy-对象“;已出席本次会议”;对旧对象使用新会话时,python,sqlalchemy,Python,Sqlalchemy,一些背景: 我有一组从基表继承的表,称为thingsthings有一个名为objecttypes的表的外键objecttypes为每个子表提供polymorphic_identity值 我发现,当我创建一个新会话时,在某些情况下,旧会话中的数据不会合并到新会话中 如果我有: eastGate=Gate(name=“eastGate”,起点=东京,终点输入=行李,objectType=typeDict['Gate'])) 如果origin、destinationInput和objectType都

一些背景: 我有一组从基表继承的表,称为
things
things
有一个名为
objecttypes
的表的外键
objecttypes
为每个子表提供
polymorphic_identity

我发现,当我创建一个新会话时,在某些情况下,旧会话中的数据不会合并到新会话中

如果我有:

eastGate=Gate(name=“eastGate”,起点=东京,终点输入=行李,objectType=typeDict['Gate']))
如果
origin
destinationInput
objectType
都是以前定义过对象的关系,我会看到以下错误:

sqlalchemy.exc.InvalidRequestError: Can't attach instance <ObjectType at 0x10592fe50>; another instance with key (
<class '__main__.ObjectType'>, (1,), None) is already present in this session.
现在我已经重现了这个问题,我不太确定根本原因是什么。在这个特定的例子中,我可以使用相同的会话,但我希望能够缩短一些会话的寿命

环境: Python:2.7.14(也发生在3.7.x上) SqlAlchemy:1.3.20

完整示例如下:

将sqlalchemy作为sa导入
从sqlalchemy导入create_引擎、inspect、Column、Integer、String、DateTime、ForeignKey
从sqlalchemy.orm导入sessionmaker,关系,别名,包含\u渴望,范围\u会话
从sqlalchemy.ext.declarative导入声明性基础
Base=声明性_Base()
类ObjectType(基):
__tablename_=“objecttypes”
id=列(整数,主键=True)
名称=列(字符串)
定义报告(自我):
返回“ObjectType({},id={})”.format(self.name,self.id)
engine=create_engine('sqlite://:memory:',echo=False)
Base.metadata.create_all(引擎)#稍后我们将再次调用此函数
sessionFactory=sessionmaker(bind=engine,expire\u on\u commit=False)
scopedSessionFactory=作用域_会话(sessionFactory)
def startScope():
返回范围SessionFactory()
def endScope():
scopedSessionFactory().close()
scopedSessionFactory.remove()
返回
def addObjectTypes():
"""
在不使用会话的情况下将所有对象类型添加到数据库中
"""
值=[“('location')”、“('locationinput')、“('gate')”]
q=“”插入到对象类型(名称)值{}”“”。格式(“,”。连接(值))
引擎执行(q)
返回
def buildObjectTypes():
addObjectTypes()
session=startScope()
types=session.query(ObjectType).all()
endScope()
返回dict([(objType.name,objType)用于类型中的objType])
#保存所有类型
typeDict=buildObjectTypes()
类事物(基本):
__tablename_u=“things”
id=列(整数,主键=True)
名称=列(字符串)
object\u type\u id=列(整数,ForeignKey('objecttypes.id'))
objectType=关系(objectType)
版本=列(整数,可空=False)
timeCreated=列(DateTime)
__映射器参数={
“version\u id\u col”:版本,
“多态性”:对象类型id,
'带多态':'*',
“多态加载”:“内联”,
}
定义报告(自我):
返回“{},id={},type={},version={}”。格式(self.name,self.id,self.objectType,self.version)
课程地点(物品):
__tablename_=“位置”
id=列(整数,ForeignKey('things.id'),primary_key=True)
__映射器参数={
“多态标识”:typeDict['location'].id
}
类位置输入(对象):
__tablename=“locationinputs”
id=列(整数,ForeignKey('things.id'),primary_key=True)
previousGateId=列(整数,ForeignKey('gates.id'))
__映射器参数={
“多态_标识”:typeDict['locationinput'].id
}
班门(东西):
__tablename_u=“盖茨”
id=列(整数,ForeignKey('things.id'),primary_key=True)
originId=列(整数,ForeignKey('locations.id'))
原点=关系(位置,外键=[originId],backref=“originGates”)
originInputId=列(整数,ForeignKey('locationinputs.id'))
originInput=关系(LocationInput,外键=[originInputId],backref=“originInputGates”)
destinationId=列(整数,ForeignKey('locations.id'))
目的地=关系(位置,外键=[destinationId],backref=“destinationGates”)
destinationInputId=列(整数,ForeignKey('locationinputs.id'))
destinationInput=关系(LocationInput,外键=[destinationInputId],backref=“destinationInputGates”)
__映射器参数={
“多态标识”:typeDict['gate'].id
}
LocationInput.previousGate=关系(Gate,外键=[LocationInput.previousGateId])
Base.metadata.create_all(引擎)
def写入(obj):
会话=scopedSessionFactory()
返回会话合并(obj)
def REPLACEERROR():
东京=位置(name=“tokyo”,objectType=typeDict['Location'])
东京=写作(东京)
#如果我在这里清除当前会话,将发生错误
scopedSessionFactory().close()
scopedSessionFactory.remove()
westGate=Gate(name=“westGate”,destination=tokyo,objectType=typeDict['Gate'])
西门=写入(西门)
luggage=LocationInput(name=“luggage”,objectType=typeDict['LocationInput'])
行李=书写(行李)
#这是发生错误的行
eastGate=Gate(name=“eastGate”,起点=东京,终点输入=行李,objectType=typeDict['Gate']))
eastGate=写入(eastGate)
印刷品(东门)
返回
复制错误()