Я пытаюсь переключить объект из одного сеанса в другой для лучшего контроля над каждым коммитом. Может ли кто-нибудь помочь мне понять, почему я могу добавить новый объект в новый сеанс, но я не могу добавить удаленный объект в тот же сеанс?
В следующем коде создается таблица, добавляется 1-я запись, фиксируется, извлекаетсязапись, удалить запись из сеанса, создать новый сеанс, добавить запись в новый сеанс и проверить, находится ли запись в новом сеансе. В качестве контроля я также добавляю 2-ю запись в новый сеанс и подтверждаю, что 2-я запись может быть добавлена в 2-й сеанс. Но результат показывает, что в сеансе 2 я могу найти только запись 2, но не запись 1.
import datetime as dt
from sqlalchemy import Column, Integer, String, BigInteger
from sqlalchemy import Sequence, ForeignKey
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker, relationship, backref
from sqlalchemy.dialects.sqlite import DATETIME
from sqlalchemy.sql.sqltypes import Float
from sqlalchemy.ext.declarative import declarative_base
from com.MneCommon import BigIntegerType
from geopy.units import nm
mneDBName='sqlite:///..\\db\\test3.db'
from abc import ABC, abstractmethod
class FactoryBase(ABC):
_Session=None
_session=None
_engine=None
_instance=None
_mneDBName=None
@property
def _cls(self):
raise NotImplementedError
# @property
# def _mneDBName(self):
# raise NotImplementedError
def __new__(cls, dbName):
if not FactoryBase._instance:
if dbName != None:
cls._mneDBName = dbName
print('** Factory: switching DB to [{}]'.format(dbName))
#_personFactory=dbName
FactoryBase._instance = super().__new__(cls)
## try:
## sess=getSession()
## except Exception as e:
## raise e ('PersonFactory.__new__: fail to establish session with [{}]'.format(_configDBName))
return FactoryBase._instance
@classmethod
def getInstance(cls):
if not FactoryBase._instance:
raise ValueError ('** Factory: trying to getInstance before create an instance. ')
else:
return FactoryBase._instance
# def __del__(self):
# FactoryBase._instance.remove(self)
def getSession(self):
if not FactoryBase._Session:
try:
self._engine=create_engine(self._mneDBName)
self._Session=sessionmaker(bind=self._engine)
# self._session=self._Session()
except Exception as e:
raise e ('PersonFactory.getSession: fail to establish session with {}'.format(self._mneDBName))
else:
pass
return self._Session
def calDateRange(inD,inU='d',inR=1):
if type(inD) is dt.datetime:
if inU=='d':
dt1=dt.datetime.strptime(str(inD)[:10],'%Y-%m-%d')-dt.timedelta(days=inR)
dt2=dt1+dt.timedelta(days=inR)
else:
raise ValueError ('calDateRange: unit {} not supported'.format(inU))
else:
raise ValueError ('calDateRange: input is not type of datetime')
return dt1, dt2
Base=declarative_base()
class MediaMap(Base):
__tablename__='mneTbl'
uID = Column('mneID', BigIntegerType, Sequence('media_id_seq'), autoincrement=True,
primary_key=True, unique=True, nullable=False)
mneName = Column('mneName',String)
mneType = Column('mneType',String)
createDate = Column('createDate',DATETIME)
updateDate = Column('updateDate',DATETIME)
inTakeDate = Column('inTakeDate',DATETIME)
archID = Column('archID',BigIntegerType)
archDate = Column('archDate',DATETIME)
perInMediaList = relationship("PersonMap",
secondary='perInMediaTbl'
)
def __init__(self,mediaName,intakeDate,mediaType=None,createDate=None):
self.createDate=createDate
self.updateDate=createDate
self.inTakeDate=intakeDate
self.mneName=mediaName
self.mneType=mediaType
self.archID=None
self.archDate=None
self.uID=None
# self.fact=MneFactory()
#self.archID=None
#self.mneID=None
def __repr__(self):
return '<Media (id=[{}], mediaName=[{}], mediaType=[{}], createDate=[{}], inTakeDate=[{}], updateDate=[{}], archID=[{}], archDate=[{}]>'.\
format(self.uID, self.mneName, self.mneType, self.createDate, self.inTakeDate, self.updateDate, self.archID, self.archDate)
class MediaMapFactory(FactoryBase):
_cls=MediaMap
# _mneDBName=mneDBName
class PersonMap(Base):
__tablename__='personTbl'
uID = Column('personID', BigIntegerType, Sequence('person_id_seq'), autoincrement=True,
primary_key=True, nullable=False, unique=True)
firstName = Column('firstName',String)
middleName = Column('middleName',String)
lastName = Column('lastName', String)
createDate = Column('createDate',DATETIME)
updateDate = Column('updateDate',DATETIME)
archID = Column('archID', BigIntegerType)
archDate= Column('archDate',DATETIME)
perInMediaList = relationship ('MediaMap', secondary='perInMediaTbl')
# perInGroupList = relationship ('GroupMap', secondary='perInGroupTbl')
def __init__(self,lastName,firstName,middleName=None):
self.firstName=firstName
self.middleName=middleName
self.lastName=lastName
self.createDate=None
self.updateDate=None
self.archID=None
self.mnePerIn=None
self.uID=None
# self.fact=PersonFactory()
#self.uID=None
def __repr__(self):
return '<Person (id=[{}], lastName=[{}], firstName=[{}], middleName=[{}], createDate=[{}], updateDate=[{}], archID=[{}], archDate=[{}]>'.format(self.uID,
self.lastName, self.firstName, self.middleName, self.createDate, self.updateDate, self.archID, self.archDate)
class PersonMapFactory(FactoryBase):
_cls=PersonMap
# _mneDBName=mneDBName
class PersonInMediaMap (Base):
__tablename__='perInMediaTbl'
mneID = Column('mneID',BigIntegerType, ForeignKey('mneTbl.mneID'),primary_key=True)
personID = Column('personID',BigIntegerType, ForeignKey('personTbl.personID'), primary_key=True)
def createDB(mneDBName):
engine=create_engine(mneDBName)
Base.metadata.create_all(engine, checkfirst=True)
return
def removeDB(mneBName):
engine=create_engine(mneBName)
Base.metadata.drop_all(engine)
return
def table_exists(dbName,tName):
engine=create_engine(dbName)
ret = engine.dialect.has_table(engine, tName)
print('Table "{}" exists: {}'.format(tName, ret))
return ret
if __name__ == '__main__':
"""prepare table"""
if table_exists(mneDBName, 'mneTbl'):
print ('\tTable mneTbl already exist.')
else:
print ('\tCreating all tables')
createDB(mneDBName)
print ('Done')
print('---Table ready.')
"""Insert record"""
print('---Create media')
mf=MediaMapFactory(mneDBName)
nM=MediaMap('test media file name',dt.datetime.now(),'jpg',dt.datetime.now())
Session=mf.getSession()
sess1=Session()
sess1.add(nM)
sess1.commit()
print ('---New media created and saved: ',nM)
mID=nM.uID
print('---Record ID: ',mID)
"""Retrieve the record from DB"""
query=sess1.query(MediaMap).filter(MediaMap.uID==mID)
mrsLst=query.all()
if len(mrsLst)<1:
print('---Cannot retrieve record ID: ', mID)
else:
print('---Record retrieved : ', mrsLst[0])
"""create a new session"""
tarM=mrsLst[0]
print('---Disconnect record from session 1: ',tarM)
sess1.expunge(tarM)
if tarM in sess1:
print('---Record still in session 1')
else:
print('---Record not in session 1')
"""Add record to session 2 """
sess2=Session()
m2=MediaMap('2nd object',dt.datetime.now(),'jpg',dt.datetime.now())
sess2.add(m2)
if m2 in sess2:
print('---2nd new record is in session 2')
else:
print('---2nd record is not in session 2')
sess2.add(tarM)
if tarM in sess2:
print('---1st record not in session 2')
else:
print('---1st record added to session 2: ', tarM)
"""Change record content"""
tarM.mneType = tarM.mneType + '.' + tarM.mneType
print('---Record modified to : ',tarM)
print('---Ready to commit change')
sess2.commit()
print('---Record added to session 2: ', tarM)
print('---Retrieve Data from DB')
query2=sess2.query(MediaMap).filter(MediaMap.uID==mID)
mrs2Lst = query2.all()
if len(mrs2Lst)<1:
print('---No record found')
else:
print('---Record returned : ',mrs2Lst[0])
print('---End')