Logick
Logick

Reputation: 331

Error with dynamic classes and sqlalchemy

I am trying to write a logging system, which uses dynamic classes to make tables. Getting the classes created, and the tables created seems to be working fine, but trying to put entries into them is lead to an error message regarding mapping, below is the sample code and the error message.

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

The error:

UnmappedInstanceError: Class 'newTable' is mapped, but this instance lacks instrumentation. This occurs when the instance is created before sqlalchemy.orm.mapper(module.newTable) was called.

Upvotes: 1

Views: 3464

Answers (2)

fandyst
fandyst

Reputation: 2830

This problem is caused by lack of instruments function interfaces for the orm as the error description says. And it is actually caused by self.__dict__ = dict(keyargs) I think. So this can be solved by reconstruct the init, which do not modify the injected functions by ORM.

Turn this

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

To

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

Upvotes: 1

underrun
underrun

Reputation: 6841

This is easier if you create a function to return a class that you set up normally. I've tried something like this and it works:

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

    return NewTable

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

Upvotes: 2

Related Questions