Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic Class Creation in SQLAlchemy

We have a need to create SQLAlchemy classes to access multiple external data sources that will increase in number over time. We use the declarative base for our core ORM models and I know we can manually specify new ORM classes using the autoload=True to auto generate the mapping.

The problem is that we need to be able generate them dynamically taking something like this:

from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()

stored={}
stored['tablename']='my_internal_table_name'
stored['objectname']='MyObject'

and turning it into something like this dynamically:

class MyObject(Base):
    __tablename__ = 'my_internal_table_name'
    __table_args__ = {'autoload':True}

We don't want the classes to persist longer than necessary to open a connection, perform the queries, and then closing the connection. Therefore, ideally, we can put the items in the "stored" variable above into a database and pull them as needed. The other challenge is that the object name (e.g. "MyObject") may be used on different connections so we cannot define it once and keep it around.

Any suggestions on how this might be accomplished would be greatly appreciated.

Thanks...

like image 553
PlaidFan Avatar asked May 04 '10 20:05

PlaidFan


1 Answers

You can dynamically create MyObject using the 3-argument call to type:

type(name, bases, dict)

    Return a new type object. This is essentially a dynamic form of the 
    class statement... 

For example:

mydict={'__tablename__':stored['tablename'],
        '__table_args__':{'autoload':True},}

MyObj=type(stored['objectname'],(Base,),mydict)
print(MyObj)
# <class '__main__.MyObject'>
print(MyObj.__base__)
# <class '__main__.Base'>
print(MyObj.__tablename__)
# my_internal_table_name
print(MyObj.__table_args__)
# {'autoload': True}
like image 81
unutbu Avatar answered Nov 04 '22 08:11

unutbu