我使用orm将类映射到Plone站点的表。但是,当我需要更改引擎正在使用的dsn时遇到了麻烦,并且我认为由于我的方法,我需要在重新初始化映射时重新映射一个类。
class DBManager(Persistant):
implements(IDBManager)
def __init__(self):
self._engine = None
#...
#...
def engine(self):
if self._engine is None:
self.initEngine()
return self._engine
def initEngine(self):
self._engine = sa.create_engine(self.dsn,convert_unicode=True,encoding='utf-8')
metadata = sa.MetaData(self._engine)
tables = []
for k,v in self.tableNamePairs():
tables[k] = sa.Table(v,metadata,autoload=True)
for k,v in self.tableClassPairings():
orm.mapper(v,tables[k])
def reinit(self):
if self._engine:
self._engine.dispose() #right function?
self.initEngine()
这是表类的示例。
class IMyType(model.Schema):
form.hidden(My_ID='hidden')
My_ID = schema.Int(title=u"My Type ID",
description=u"Primary Key",
)
title = schema.TextLine(title="My Type Title",
description = u"Title of MyType"
)
class MyType(object):
implements(IMyType)
My_ID = None
title = None
def __init__(self,My_ID,title):
self.My_ID = My_ID
self.title = title
不幸的是,当从reinit调用initEngine时,尝试映射时会出错-> orm.mapper(v,tables [k])
我得到的错误是:
ArgumentError: Class '<class 'my.type.tables.my_type.MyType'>' already has a primary mapper defined. Use non_primary=True to create a non primary Mapper. clear_mappers() will remove *all* current mappers from all classes.
该错误似乎意味着我需要取消映射该类。 不幸的是,clear_mappers不是解决方案。它不仅会摆脱我不想摆脱的映射器,而且还应该仅根据文档在罕见的测试实例中使用。
停止并重新启动我正在处理的站点的实例是我目前正在做的事情,但是我只想更改DSN而不必重新启动实例。
我是否需要将映射器存储在列表中,并以某种方式将其设置为None? 我尝试过类似的方法,但没有任何效果。
def __init__(self):
#...
self.mappers = []
def initEngine(self):
#...
for k,v in self.tableClassPairings():
self.mappers.append(orm.mapper(v,tables[k]))
def reinit(self):
for i in self.mappers:
i = None
#...
self.initEngine()
是否可以取消映射/重新映射表?还是应该为停止/重新启动实例做好准备?