From: Jonathan LaCour Date: Sun, 23 Apr 2006 21:41:36 +0000 (+0000) Subject: Got the unit tests running again, apart from the two that were not working in X-Git-Tag: rel_0_1_7~19 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e008839e81e377e7a82fdfe9778fe849dd212e6f;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git Got the unit tests running again, apart from the two that were not working in the first place. The changes to process_relationships and to sqlachemy itself were causing a double 'assign_mapper' call to cause issues. Now, we basically defer calling assign_mapper until process_relationships in cases where there are defined relationships. Also, I moved ActiveMapper to always use the default engine, as there were a lot of hacks inside ActiveMapper to allow for engine swapping. The use of the default engine and the "global_connect" functionality significantly improves the usability of ActiveMapper. ActiveMapper will be getting a bit of a refactor/cleanup at some point in the nearish future, as it has drifted a bit to complexity with the addition of some features. For now, this should do the trick! --- diff --git a/lib/sqlalchemy/ext/activemapper.py b/lib/sqlalchemy/ext/activemapper.py index 4b2b9055a8..f875b30b33 100644 --- a/lib/sqlalchemy/ext/activemapper.py +++ b/lib/sqlalchemy/ext/activemapper.py @@ -1,18 +1,9 @@ -from sqlalchemy import objectstore, create_engine, assign_mapper, relation, mapper, join -from sqlalchemy import and_, or_ +from sqlalchemy import assign_mapper, relation, exceptions from sqlalchemy import Table, Column, ForeignKey -from sqlalchemy.ext.proxy import ProxyEngine import inspect import sys -# -# the "proxy" to the database engine... this can be swapped out at runtime -# -engine = ProxyEngine() - - - # # declarative column declaration - this is so that we can infer the colname # @@ -87,22 +78,21 @@ def check_relationships(klass): def process_relationships(klass): defer = False for propname, reldesc in klass.relations.items(): - #We require that every related table has been processed first + # we require that every related table has been processed first if not reldesc.classname in __processed_classes__: if not klass._classname in __deferred_classes__: __deferred_classes__.append(klass._classname) defer = True - - - #Check every column item to see if it points to an existing table - #if it does not, defer... + + # check every column item to see if it points to an existing table + # if it does not, defer... if not defer: - if not check_relationships(klass): - if not klass._classname in __deferred_classes__: __deferred_classes__.append(klass._classname) - defer = True - + if not check_relationships(klass): + if not klass._classname in __deferred_classes__: __deferred_classes__.append(klass._classname) + defer = True + if not defer: relations = {} - __processed_classes__.append(klass._classname) + for propname, reldesc in klass.relations.items(): relclass = ActiveMapperMeta.classes[reldesc.classname] relations[propname] = relation(relclass.mapper, @@ -111,17 +101,23 @@ def process_relationships(klass): private=reldesc.private, lazy=reldesc.lazy, uselist=reldesc.uselist) - if len(relations)>0: - assign_mapper(klass, klass.table, properties=relations) - - if klass._classname in __deferred_classes__: __deferred_classes__.remove(klass._classname) + if len(relations) > 0: + assign_ok = True + try: + assign_mapper(klass, klass.table, properties=relations) + except exceptions.ArgumentError: + assign_ok = False + + if assign_ok: + __processed_classes__.append(klass._classname) + if klass._classname in __deferred_classes__: __deferred_classes__.remove(klass._classname) + else: + __processed_classes__.append(klass._classname) for deferred_class in __deferred_classes__: process_relationships(ActiveMapperMeta.classes[deferred_class]) - - class ActiveMapperMeta(type): classes = {} @@ -129,7 +125,6 @@ class ActiveMapperMeta(type): table_name = clsname.lower() columns = [] relations = {} - _engine = getattr( sys.modules[cls.__module__], "__engine__", engine ) if 'mapping' in dict: members = inspect.getmembers(dict.get('mapping')) @@ -138,10 +133,6 @@ class ActiveMapperMeta(type): table_name = value continue - if '__engine__' == name: - _engine= value - continue - if name.startswith('__'): continue if isinstance(value, column): @@ -161,13 +152,14 @@ class ActiveMapperMeta(type): if isinstance(value, relationship): relations[name] = value - assert _engine is not None, "No engine specified" - cls.table = Table(table_name, _engine, *columns) + + cls.table = Table(table_name, redefine=True, *columns) + # check for inheritence - if hasattr( bases[0], "mapping" ): - cls._base_mapper= bases[0].mapper + if hasattr(bases[0], "mapping"): + cls._base_mapper = bases[0].mapper assign_mapper(cls, cls.table, inherits=cls._base_mapper) - else: + elif len(relations) == 0: assign_mapper(cls, cls.table) cls.relations = relations cls._classname = clsname @@ -191,4 +183,11 @@ class ActiveMapper(object): def create_tables(): for klass in ActiveMapperMeta.classes.values(): - klass.table.create() \ No newline at end of file + klass.table.create() + +# +# a utility function to drop all tables for all ActiveMapper classes +# +def drop_tables(): + for klass in ActiveMapperMeta.classes.values(): + klass.table.drop() \ No newline at end of file diff --git a/test/activemapper.py b/test/activemapper.py index edb49fea34..7edb414880 100644 --- a/test/activemapper.py +++ b/test/activemapper.py @@ -1,11 +1,11 @@ -from activemapper import ActiveMapper, column, one_to_many, one_to_one -from sqlalchemy import objectstore -from sqlalchemy import and_, or_ -from sqlalchemy import ForeignKey, String, Integer, DateTime -from datetime import datetime +from sqlalchemy.ext.activemapper import ActiveMapper, column, one_to_many, one_to_one +from sqlalchemy.ext import activemapper +from sqlalchemy import objectstore, global_connect +from sqlalchemy import and_, or_ +from sqlalchemy import ForeignKey, String, Integer, DateTime +from datetime import datetime import unittest -import activemapper # # application-level model objects @@ -130,6 +130,9 @@ class testcase(unittest.TestCase): def test_create(self): + global_connect('sqlite:///', echo=False) + activemapper.create_tables() + p1 = self.create_person_one() objectstore.commit() @@ -222,9 +225,4 @@ class testcase(unittest.TestCase): if __name__ == '__main__': - # go ahead and setup the database connection, and create the tables - activemapper.engine.connect('sqlite:///', echo=False) - activemapper.create_tables() - - # launch the unit tests unittest.main() \ No newline at end of file