AlchemyBackend do db insert or replace in policy_set and attribute_copy
authorSofia Papagiannaki <papagian@gmail.com>
Thu, 8 Sep 2011 12:39:26 +0000 (15:39 +0300)
committerSofia Papagiannaki <papagian@gmail.com>
Thu, 8 Sep 2011 12:39:26 +0000 (15:39 +0300)
pithos/backends/lib_alchemy/node.py
pithos/backends/lib_alchemy/policy.py

index 6b7dc1a..6e7c887 100644 (file)
@@ -648,22 +648,21 @@ class Node(DBWorker):
             self.conn.execute(s).close()
     
     def attribute_copy(self, source, dest):
             self.conn.execute(s).close()
     
     def attribute_copy(self, source, dest):
-        class InsertFromSelect(_UpdateBase):
-            def __init__(self, table, select):
-                self.table = table
-                self.select = select
-        
-        @compiles(InsertFromSelect)
-        def visit_insert_from_select(element, compiler, **kw):
-            return "INSERT INTO %s (%s)" % (
-                compiler.process(element.table, asfrom=True),
-                compiler.process(element.select)
-            )
-        
         s = select([dest, self.attributes.c.key, self.attributes.c.value],
             self.attributes.c.serial == source)
         s = select([dest, self.attributes.c.key, self.attributes.c.value],
             self.attributes.c.serial == source)
-        ins = InsertFromSelect(self.attributes, s)
-        self.conn.execute(ins).close()
+        rp = self.conn.execute(s)
+        attributes = rp.fetchall()
+        rp.close()
+        for dest, k, v in attributes:
+            s = self.attributes.update().where(and_(
+                self.attributes.c.serial == dest,
+                self.attributes.c.key == k))
+            rp = self.conn.execute(s, value=v)
+            rp.close()
+            if rp.rowcount == 0:
+                s = self.attributes.insert()
+                values = {'serial':dest, 'key':k, 'value':v}
+                self.conn.execute(s, values).close()
     
     def latest_attribute_keys(self, parent, before=inf, except_cluster=0, pathq=[]):
         """Return a list with all keys pairs defined
     
     def latest_attribute_keys(self, parent, before=inf, except_cluster=0, pathq=[]):
         """Return a list with all keys pairs defined
index 6fcb063..203bc7d 100644 (file)
@@ -33,6 +33,7 @@
 
 from sqlalchemy import Table, Column, String, MetaData
 from sqlalchemy.sql import select
 
 from sqlalchemy import Table, Column, String, MetaData
 from sqlalchemy.sql import select
+from sqlalchemy.sql import and_
 from dbworker import DBWorker
 
 
 from dbworker import DBWorker
 
 
@@ -51,10 +52,17 @@ class Policy(DBWorker):
         metadata.bind = self.engine
     
     def policy_set(self, path, policy):
         metadata.bind = self.engine
     
     def policy_set(self, path, policy):
-        s = self.policies.insert()
-        values = [{'path':path, 'key':k, 'value':v} for k,v in policy.iteritems()]
-        r = self.conn.execute(s, values)
-        r.close()
+        for k, v in policy.iteritems():
+            s = self.policies.update().where(and_(self.policies.c.path == path,
+                                                  self.policies.c.key == k))
+            s = s.values(value = v)
+            rp = self.conn.execute(s)
+            rp.close()
+            if rp.rowcount == 0:
+                s = self.policies.insert()
+                values = {'path':path, 'key':k, 'value':v}
+                r = self.conn.execute(s, values)
+                r.close()
     
     def policy_unset(self, path):
         s = self.policies.delete().where(self.policies.c.path==path)
     
     def policy_unset(self, path):
         s = self.policies.delete().where(self.policies.c.path==path)