From: Mike Bayer Date: Tue, 13 Sep 2005 06:59:04 +0000 (+0000) Subject: (no commit message) X-Git-Tag: rel_0_1_0~746 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a556559a549929c577b1241bb98023c1aeeefe0e;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git --- diff --git a/lib/sqlalchemy/mapper.py b/lib/sqlalchemy/mapper.py index 03d5190589..9b3106b9a9 100644 --- a/lib/sqlalchemy/mapper.py +++ b/lib/sqlalchemy/mapper.py @@ -170,6 +170,7 @@ class Mapper(object): def put(self, instance): key = objectstore.get_instance_key(instance, self.class_, self.table, self.selectable) + instance._instance_key = key objectstore.put(key, instance, self.scope) return key @@ -218,9 +219,17 @@ class Mapper(object): # so they can be combined into a multiple execute for table in self.tables: params = {} + if hasattr(obj, "_instance_key"): + isinsert = False + else: + isinsert = True + + needs_primaries = False for primary_key in table.primary_keys: if self._getattrbycolumn(obj, primary_key) is None: - statement = table.insert() + needs_primaries = True + #statement = table.insert() + if isinsert: for col in table.columns: params[col.key] = self._getattrbycolumn(obj, col) break @@ -231,10 +240,17 @@ class Mapper(object): clause.clauses.append(col == self._getattrbycolumn(obj, col)) else: params[col.key] = self._getattrbycolumn(obj, col) + #statement = table.update(clause) + + if not isinsert: statement = table.update(clause) + else: + statement = table.insert() + statement.echo = self.echo statement.execute(**params) - if isinstance(statement, sql.Insert): + + if needs_primaries and isinstance(statement, sql.Insert): primary_keys = table.engine.last_inserted_ids() index = 0 for col in table.primary_keys: @@ -254,15 +270,15 @@ class Mapper(object): """removes the object. traverse indicates attached objects should be removed as well.""" pass - def _compile(self, whereclause = None, **options): - statement = sql.select([self.selectable], whereclause) + def _compile(self, whereclause = None, order_by = None, **options): + statement = sql.select([self.selectable], whereclause, order_by = order_by) for key, value in self.props.iteritems(): value.setup(key, statement, **options) statement.use_labels = True return statement - def _select_whereclause(self, whereclause = None, **params): - statement = self._compile(whereclause) + def _select_whereclause(self, whereclause = None, order_by = None, **params): + statement = self._compile(whereclause, order_by = order_by) return self._select_statement(statement, **params) def _select_statement(self, statement, **params): diff --git a/lib/sqlalchemy/objectstore.py b/lib/sqlalchemy/objectstore.py index 3057f7ef0d..02d0f70b80 100644 --- a/lib/sqlalchemy/objectstore.py +++ b/lib/sqlalchemy/objectstore.py @@ -77,6 +77,8 @@ def put(key, obj, scope='thread'): if isinstance(obj, dict): raise "cant put a dict in the object store" + + obj._instance_key = key if scope == 'thread': try: @@ -156,13 +158,19 @@ class UnitOfWork(object): if usehistory: self.register_attribute(obj, key).setattr(value) obj.__dict__[key] = value - self.register_dirty(obj) + if hasattr(obj, '_instance_key'): + self.register_dirty(obj) + else: + self.register_new(obj) def delete_attribute(self, obj, key, value, usehistory = False): if usehistory: self.register_attribute(obj, key).delattr(value) del obj.__dict__[key] - self.register_dirty(obj) + if hasattr(obj, '_instance_key'): + self.register_dirty(obj) + else: + self.register_new(obj) def register_attribute(self, obj, key): try: @@ -252,6 +260,9 @@ class UnitOfWork(object): (processor, stuff_to_process) = dep processor.process_dependencies(stuff_to_process, self) + for obj in self.new: + mapper = sqlalchemy.mapper.object_mapper(obj) + mapper.put(obj) self.new.clear() self.dirty.clear() for item in self.modified_lists: diff --git a/test/mapper.py b/test/mapper.py index 0075af8a92..9149aca7b6 100644 --- a/test/mapper.py +++ b/test/mapper.py @@ -490,12 +490,12 @@ class SaveTest(AssertMixin): keywordmapper = mapper(Keyword, keywords) data = [Item, - {'item_name': 'item1', 'keywords' : (Keyword,[{'name': 'green'}, {'name': 'purple'},{'name': 'big'},{'name': 'round'}])}, - {'item_name': 'item2', 'keywords' : (Keyword,[{'name':'blue'}, {'name':'small'}, {'name':'imnew'},{'name':'round'}])}, + {'item_name': 'item1', 'keywords' : (Keyword,[{'name': 'big'},{'name': 'green'}, {'name': 'purple'},{'name': 'round'}])}, + {'item_name': 'item2', 'keywords' : (Keyword,[{'name':'blue'}, {'name':'imnew'},{'name':'round'}, {'name':'small'}])}, {'item_name': 'item3', 'keywords' : (Keyword,[])}, - {'item_name': 'item4', 'keywords' : (Keyword,[{'name':'blue'},{'name':'big'}])}, - {'item_name': 'item5', 'keywords' : (Keyword,[{'name':'green'},{'name':'big'},{'name':'exacting'}])}, - {'item_name': 'item6', 'keywords' : (Keyword,[{'name':'red'},{'name':'small'},{'name':'round'}])}, + {'item_name': 'item4', 'keywords' : (Keyword,[{'name':'big'}, {'name':'blue'},])}, + {'item_name': 'item5', 'keywords' : (Keyword,[{'name':'big'},{'name':'exacting'},{'name':'green'}])}, + {'item_name': 'item6', 'keywords' : (Keyword,[{'name':'red'},{'name':'round'},{'name':'small'}])}, ] objects = [] for elem in data[1:]: @@ -520,8 +520,8 @@ class SaveTest(AssertMixin): objectstore.uow().commit() print "OK!" - l = m.select(items.c.item_name.in_(*[e['item_name'] for e in data[1:]])) - self.assert_result(l, data) + l = m.select(items.c.item_name.in_(*[e['item_name'] for e in data[1:]]), order_by=[items.c.item_name, keywords.c.name]) + self.assert_result(l, *data) print "OK!" objects[4].item_name = 'item4updated' @@ -536,5 +536,60 @@ class SaveTest(AssertMixin): print "added: " + repr(objects[2].keywords.added_items()) objectstore.uow().commit() + def testassociation(self): + class IKAssociation(object): + def __repr__(self): + return "\nIKAssociation " + repr(self.item) + " " + repr(self.keyword) + + itemkeywords = Table('itemkeywords', db, + Column('item_id', INT, primary_key = True), + Column('keyword_id', INT, primary_key = True) + ) + + items = orderitems + + keywordmapper = mapper(Keyword, keywords) + + m = mapper(IKAssociation, itemkeywords, properties = dict( + keyword = relation(Keyword, keywords, primaryjoin = itemkeywords.c.keyword_id==keywords.c.keyword_id, foreignkey = itemkeywords.c.keyword_id, lazy = False, uselist = False), + item = relation(Item, items, primaryjoin = itemkeywords.c.item_id==items.c.item_id, foreignkey = itemkeywords.c.item_id, lazy = False, uselist = False) + ), echo = True) + + # TODO: spiff up the assertion thing so this can be what its supposed to be + data = [Item, + {'item_name': 'item1', 'keywords' : (Keyword,[{'name': 'big'},{'name': 'green'}, {'name': 'purple'},{'name': 'round'}])}, + {'item_name': 'item2', 'keywords' : (Keyword,[{'name':'blue'}, {'name':'imnew'},{'name':'round'}, {'name':'small'}])}, + {'item_name': 'item3', 'keywords' : (Keyword,[])}, + {'item_name': 'item4', 'keywords' : (Keyword,[{'name':'big'}, {'name':'blue'},])}, + {'item_name': 'item5', 'keywords' : (Keyword,[{'name':'big'},{'name':'exacting'},{'name':'green'}])}, + {'item_name': 'item6', 'keywords' : (Keyword,[{'name':'red'},{'name':'round'},{'name':'small'}])}, + ] + objects = [] + for elem in data[1:]: + if len(elem['keywords'][1]): + klist = keywordmapper.select(keywords.c.name.in_(*[e['name'] for e in elem['keywords'][1]])) + else: + klist = [] + + khash = {} + for k in klist: + khash[k.name] = k + for kname in [e['name'] for e in elem['keywords'][1]]: + try: + k = khash[kname] + except KeyError: + k = Keyword() + k.name = kname + + ik = IKAssociation() + ik.item = Item() + ik.item.item_name = elem['item_name'] + ik.keyword = k + + objectstore.uow().commit() + + l = m.select(sql.and_(items.c.item_id==itemkeywords.c.item_id, items.c.item_name.in_(*[e['item_name'] for e in data[1:]])), order_by=[items.c.item_name, keywords.c.name]) + print repr(l) + if __name__ == "__main__": unittest.main()