]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
(no commit message)
authorMike Bayer <mike_mp@zzzcomputing.com>
Tue, 13 Sep 2005 06:59:04 +0000 (06:59 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Tue, 13 Sep 2005 06:59:04 +0000 (06:59 +0000)
lib/sqlalchemy/mapper.py
lib/sqlalchemy/objectstore.py
test/mapper.py

index 03d5190589642d9f0427689d658e1338bf105d06..9b3106b9a9bc5c16881c29b556c219ee13eac9aa 100644 (file)
@@ -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):
index 3057f7ef0d2fff8cea520bcc44f3fa72aab1a99c..02d0f70b8082db288e00ce04efb265ef5dd30765 100644 (file)
@@ -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:
index 0075af8a92918db4c48da2988ed33077d2604b36..9149aca7b63988b9a6c61ba3301e5ff83814e0e7 100644 (file)
@@ -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()