动态类与SQLAlchemy的错误

1 投票
2 回答
3042 浏览
提问于 2025-04-16 20:15

我正在尝试写一个日志系统,这个系统使用动态类来创建表格。创建类和表格的部分似乎都没问题,但在往表格里添加数据时却出现了一个关于映射的错误信息。下面是示例代码和错误信息。

Base = declarative_base()

#my init function
def tableinit(self,keyargs):
    self.__dict__ = dict(keyargs)

#table creation
tableName = "newTable"
columnsDict["__tablename__"] = tableName
columnsDict["__init__"] = tableinit
columnsDict["id"] = Column("id",Integer, autoincrement = True, nullable = False, primary_key=True)
columnsDict["pid"] = Column("pid",Integer, ForeignKey('someparenttable.id'))  #someparenttable is created with a hard coded class
newTable = type(tableName,(Base,),columnsDict)
tableClassDict[tableName]=newTable

#when doing an entry
newClassInst = subEntryClassDict[tableName]
newEntry = newClassInst(dataDict)
entryList.append(newEntry)  # this is called in a for loop with the entries for someparenttable's entries also

self.session.add_all(entryList) # at this point the error occurs

错误信息:

UnmappedInstanceError: 类 'newTable' 已经被映射,但这个实例缺少必要的设置。这个问题发生在实例创建的时间早于 sqlalchemy.orm.mapper(module.newTable) 被调用的时候。

2 个回答

1

这个问题是因为缺少一些工具函数的接口,正如错误信息所说的那样。实际上,这个问题是由 self.__dict__ = dict(keyargs) 这行代码引起的。我认为。

所以可以通过重新构建 init 方法来解决这个问题,这样就不会修改 ORM 注入的函数。

把这个

#my init function
def tableinit(self,keyargs):
    self.__dict__ = dict(keyargs)

改成

#my init function
def tableinit(self,**kwargs):
    self.__dict__.update(kwargs)
2

如果你创建一个函数来返回一个你正常设置的类,这样会简单很多。我试过类似的做法,效果很好:

def getNewTable( db, table ):
    class NewTable( Base ):
        __tablename__ = table
        __table_args__ = { 'schema': db }
        id = Column( ...

    return NewTable

newClassInst = getNewTable( 'somedb', 'sometable' )
newRow = newClassInst( data )

撰写回答