Modify the _get_element() wrapper to work with psycopg

A lot of non-obvious code here. so comment heavily

Change-Id: I240023274b3453f8931c5b72a1651560ee94c9d2
diff --git a/db/db.py b/db/db.py
index 7350704..8cde634 100644
--- a/db/db.py
+++ b/db/db.py
@@ -101,9 +101,25 @@
         self._delete_row("vlan", "vlan_id", vlan_id)
 
     def _get_element(self, select_field, table, compare_field, value):
-        sql = "SELECT %s FROM %s WHERE %s = %s"
-        data = (select_field, table, compare_field, value)
+
+        # We really want to use psycopg's type handling deal with the
+        # (potentially) user-supplied data in the value field, so we
+        # have to pass (sql,data) through to cursor.execute. However,
+        # we can't have psycopg do all the argument substitution here
+        # as it will quote all the params like the table name. That
+        # doesn't work. So, we substitute a "%s" for "%s" here so we
+        # keep it after python's own string substitution.
+        sql = "SELECT %s FROM %s WHERE %s = %s" % (select_field, table, compare_field, "%s")
+
+        # Now, the next icky thing: we need to make sure that we're
+        # passing a dict so that psycopg2 can pick it apart properly
+        # for its own substitution code. We force this with the
+        # trailing comma here
+        data = (value, )
         self.cursor.execute(sql, data)
+
+        # Will raise an exception here if there are no rows that
+        # match. That's OK - the caller needs to deal with that.
         return self.cursor.fetchone()[0]
 
     def get_switch_id(self, name):