Created
January 3, 2012 20:21
-
-
Save jvanasco/1556734 to your computer and use it in GitHub Desktop.
Reflecting in Pyramid/SqlAlchemy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import logging | |
log = logging.getLogger(__name__) | |
from sqlalchemy import Table | |
from sqlalchemy import MetaData | |
from sqlalchemy.orm import mapper | |
from sqlalchemy.orm import scoped_session | |
from sqlalchemy.orm import sessionmaker | |
from zope.sqlalchemy import ZopeTransactionExtension | |
import app | |
import types | |
DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension())) | |
DBMetadata = MetaData() | |
class ReflectedTable(object): | |
"""Base class for database objects that are mapped to tables by reflection. | |
Have your various model classes inherit from this class. If class.__tablename__ is defined, it will reflect | |
Example: | |
class Useraccount(ReflectedTable): | |
__tablename__ = "useraccount" | |
""" | |
__tablename__ = None | |
def map_tables( app_model ): | |
""" | |
""" | |
to_reflect = [] | |
for content in dir( app_model ): | |
module = getattr( app_model , content ) | |
if not isinstance( module , types.ModuleType ): | |
continue | |
for module_element in dir( module ): | |
module_element = getattr( module, module_element ) | |
if not isinstance( module_element , types.TypeType ): | |
continue | |
if issubclass( module_element , ReflectedTable ): | |
to_reflect.append( module_element ) | |
for _class in to_reflect: | |
table_name = _class.__tablename__ | |
if table_name: | |
log.info("Reflecting : %s (table: %s)" % (_class , table_name) ) | |
table= Table( table_name, DBMetadata, autoload=True ) | |
mapper( _class , table) | |
def initialize_sql(engine): | |
"""Call this once per engine from app.__init__.main | |
engine = sqlalchemy.engine_from_config(settings, prefix="sqlalchemy.") | |
sqlahelper.add_engine(engine) | |
models.initialize_sql(engine) | |
""" | |
log.debug( "\ninitialize_sql" ) | |
DBSession.configure(bind=engine) | |
DBMetadata.bind = engine | |
map_tables( app.models ) | |
## import various classes here. | |
import models_1 | |
import models_2 | |
import models_3 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
For future readers.. The DeferredReflection mixin is now built in to sqlaclehemy and should remove the need for special handling.
See docs here: http://docs.sqlalchemy.org/en/rel_0_9/orm/extensions/declarative.html#using-reflection-with-declarative
and here: http://docs.sqlalchemy.org/en/rel_0_9/orm/extensions/declarative.html#sqlalchemy.ext.declarative.DeferredReflection