diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2008-05-09 16:34:10 +0000 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2008-05-09 16:34:10 +0000 |
commit | 4a6afd469fad170868554bf28578849bf3dfd5dd (patch) | |
tree | b396edc33d567ae19dd244e87137296450467725 /lib/sqlalchemy/ext/activemapper.py | |
parent | 46b7c9dc57a38d5b9e44a4723dad2ad8ec57baca (diff) | |
download | sqlalchemy-4a6afd469fad170868554bf28578849bf3dfd5dd.tar.gz |
r4695 merged to trunk; trunk now becomes 0.5.
0.4 development continues at /sqlalchemy/branches/rel_0_4
Diffstat (limited to 'lib/sqlalchemy/ext/activemapper.py')
-rw-r--r-- | lib/sqlalchemy/ext/activemapper.py | 298 |
1 files changed, 0 insertions, 298 deletions
diff --git a/lib/sqlalchemy/ext/activemapper.py b/lib/sqlalchemy/ext/activemapper.py deleted file mode 100644 index 02f4b5b35..000000000 --- a/lib/sqlalchemy/ext/activemapper.py +++ /dev/null @@ -1,298 +0,0 @@ -from sqlalchemy import ThreadLocalMetaData, util, Integer -from sqlalchemy import Table, Column, ForeignKey -from sqlalchemy.orm import class_mapper, relation, scoped_session -from sqlalchemy.orm import sessionmaker - -from sqlalchemy.orm import backref as create_backref - -import inspect -import sys - -# -# the "proxy" to the database engine... this can be swapped out at runtime -# -metadata = ThreadLocalMetaData() -Objectstore = scoped_session -objectstore = scoped_session(sessionmaker(autoflush=True, transactional=False)) - -# -# declarative column declaration - this is so that we can infer the colname -# -class column(object): - def __init__(self, coltype, colname=None, foreign_key=None, - primary_key=False, *args, **kwargs): - if isinstance(foreign_key, basestring): - foreign_key = ForeignKey(foreign_key) - - self.coltype = coltype - self.colname = colname - self.foreign_key = foreign_key - self.primary_key = primary_key - self.kwargs = kwargs - self.args = args - -# -# declarative relationship declaration -# -class relationship(object): - def __init__(self, classname, colname=None, backref=None, private=False, - lazy=True, uselist=True, secondary=None, order_by=False, viewonly=False): - self.classname = classname - self.colname = colname - self.backref = backref - self.private = private - self.lazy = lazy - self.uselist = uselist - self.secondary = secondary - self.order_by = order_by - self.viewonly = viewonly - - def process(self, klass, propname, relations): - relclass = ActiveMapperMeta.classes[self.classname] - - if isinstance(self.order_by, str): - self.order_by = [ self.order_by ] - - if isinstance(self.order_by, list): - for itemno in range(len(self.order_by)): - if isinstance(self.order_by[itemno], str): - self.order_by[itemno] = \ - getattr(relclass.c, self.order_by[itemno]) - - backref = self.create_backref(klass) - relations[propname] = relation(relclass.mapper, - secondary=self.secondary, - backref=backref, - private=self.private, - lazy=self.lazy, - uselist=self.uselist, - order_by=self.order_by, - viewonly=self.viewonly) - - def create_backref(self, klass): - if self.backref is None: - return None - - relclass = ActiveMapperMeta.classes[self.classname] - - if klass.__name__ == self.classname: - class_mapper(relclass).compile() - br_fkey = relclass.c[self.colname] - else: - br_fkey = None - - return create_backref(self.backref, remote_side=br_fkey) - - -class one_to_many(relationship): - def __init__(self, *args, **kwargs): - kwargs['uselist'] = True - relationship.__init__(self, *args, **kwargs) - -class one_to_one(relationship): - def __init__(self, *args, **kwargs): - kwargs['uselist'] = False - relationship.__init__(self, *args, **kwargs) - - def create_backref(self, klass): - if self.backref is None: - return None - - relclass = ActiveMapperMeta.classes[self.classname] - - if klass.__name__ == self.classname: - br_fkey = getattr(relclass.c, self.colname) - else: - br_fkey = None - - return create_backref(self.backref, foreignkey=br_fkey, uselist=False) - - -class many_to_many(relationship): - def __init__(self, classname, secondary, backref=None, lazy=True, - order_by=False): - relationship.__init__(self, classname, None, backref, False, lazy, - uselist=True, secondary=secondary, - order_by=order_by) - - -# -# SQLAlchemy metaclass and superclass that can be used to do SQLAlchemy -# mapping in a declarative way, along with a function to process the -# relationships between dependent objects as they come in, without blowing -# up if the classes aren't specified in a proper order -# - -__deferred_classes__ = {} -__processed_classes__ = {} -def process_relationships(klass, was_deferred=False): - # first, we loop through all of the relationships defined on the - # class, and make sure that the related class already has been - # completely processed and defer processing if it has not - defer = False - for propname, reldesc in klass.relations.items(): - found = (reldesc.classname == klass.__name__ or reldesc.classname in __processed_classes__) - if not found: - defer = True - break - - # next, we loop through all the columns looking for foreign keys - # and make sure that we can find the related tables (they do not - # have to be processed yet, just defined), and we defer if we are - # not able to find any of the related tables - if not defer: - for col in klass.columns: - if col.foreign_keys: - found = False - cn = col.foreign_keys[0]._colspec - table_name = cn[:cn.rindex('.')] - for other_klass in ActiveMapperMeta.classes.values(): - if other_klass.table.fullname.lower() == table_name.lower(): - found = True - - if not found: - defer = True - break - - if defer and not was_deferred: - __deferred_classes__[klass.__name__] = klass - - # if we are able to find all related and referred to tables, then - # we can go ahead and assign the relationships to the class - if not defer: - relations = {} - for propname, reldesc in klass.relations.items(): - reldesc.process(klass, propname, relations) - - class_mapper(klass).add_properties(relations) - if klass.__name__ in __deferred_classes__: - del __deferred_classes__[klass.__name__] - __processed_classes__[klass.__name__] = klass - - # finally, loop through the deferred classes and attempt to process - # relationships for them - if not was_deferred: - # loop through the list of deferred classes, processing the - # relationships, until we can make no more progress - last_count = len(__deferred_classes__) + 1 - while last_count > len(__deferred_classes__): - last_count = len(__deferred_classes__) - deferred = __deferred_classes__.copy() - for deferred_class in deferred.values(): - process_relationships(deferred_class, was_deferred=True) - - -class ActiveMapperMeta(type): - classes = {} - metadatas = util.Set() - def __init__(cls, clsname, bases, dict): - table_name = clsname.lower() - columns = [] - relations = {} - autoload = False - _metadata = getattr(sys.modules[cls.__module__], - "__metadata__", metadata) - version_id_col = None - version_id_col_object = None - table_opts = {} - - if 'mapping' in dict: - found_pk = False - - members = inspect.getmembers(dict.get('mapping')) - for name, value in members: - if name == '__table__': - table_name = value - continue - - if '__metadata__' == name: - _metadata= value - continue - - if '__autoload__' == name: - autoload = True - continue - - if '__version_id_col__' == name: - version_id_col = value - - if '__table_opts__' == name: - table_opts = value - - if name.startswith('__'): continue - - if isinstance(value, column): - if value.primary_key == True: found_pk = True - - if value.foreign_key: - col = Column(value.colname or name, - value.coltype, - value.foreign_key, - primary_key=value.primary_key, - *value.args, **value.kwargs) - else: - col = Column(value.colname or name, - value.coltype, - primary_key=value.primary_key, - *value.args, **value.kwargs) - columns.append(col) - continue - - if isinstance(value, relationship): - relations[name] = value - - if not found_pk and not autoload: - col = Column('id', Integer, primary_key=True) - cls.mapping.id = col - columns.append(col) - - assert _metadata is not None, "No MetaData specified" - - ActiveMapperMeta.metadatas.add(_metadata) - - if not autoload: - cls.table = Table(table_name, _metadata, *columns, **table_opts) - cls.columns = columns - else: - cls.table = Table(table_name, _metadata, autoload=True, **table_opts) - cls.columns = cls.table._columns - - if version_id_col is not None: - version_id_col_object = getattr(cls.table.c, version_id_col, None) - assert(version_id_col_object is not None, "version_id_col (%s) does not exist." % version_id_col) - - # check for inheritence - if hasattr(bases[0], "mapping"): - cls._base_mapper= bases[0].mapper - cls.mapper = objectstore.mapper(cls, cls.table, - inherits=cls._base_mapper, version_id_col=version_id_col_object) - else: - cls.mapper = objectstore.mapper(cls, cls.table, version_id_col=version_id_col_object) - cls.relations = relations - ActiveMapperMeta.classes[clsname] = cls - - process_relationships(cls) - - super(ActiveMapperMeta, cls).__init__(clsname, bases, dict) - - - -class ActiveMapper(object): - __metaclass__ = ActiveMapperMeta - - def set(self, **kwargs): - for key, value in kwargs.items(): - setattr(self, key, value) - - -# -# a utility function to create all tables for all ActiveMapper classes -# - -def create_tables(): - for metadata in ActiveMapperMeta.metadatas: - metadata.create_all() - -def drop_tables(): - for metadata in ActiveMapperMeta.metadatas: - metadata.drop_all() |