Невозможно добавить удаленный объект в новый сеанс - PullRequest
0 голосов
/ 07 октября 2019

Я пытаюсь переключить объект из одного сеанса в другой для лучшего контроля над каждым коммитом. Может ли кто-нибудь помочь мне понять, почему я могу добавить новый объект в новый сеанс, но я не могу добавить удаленный объект в тот же сеанс?

В следующем коде создается таблица, добавляется 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')


Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...