From 7a058403caa67d8393bb4837c8ae722d08050afb Mon Sep 17 00:00:00 2001 From: Daniele Varrazzo Date: Wed, 9 Feb 2011 02:20:25 +0100 Subject: [PATCH] Fixed mapping for composite types defined in a schema --- lib/extras.py | 13 ++++++++++--- tests/types_extras.py | 27 +++++++++++++++++++++++++-- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/lib/extras.py b/lib/extras.py index 137d6fbe..a25f4201 100644 --- a/lib/extras.py +++ b/lib/extras.py @@ -835,15 +835,22 @@ class CompositeCaster(object): # Store the transaction status of the connection to revert it after use conn_status = conn.status + # Use the correct schema + if '.' in name: + schema, tname = name.split('.', 1) + else: + tname = name + schema = 'public' + # get the type oid and attributes curs.execute("""\ SELECT t.oid, attname, atttypid FROM pg_type t JOIN pg_namespace ns ON typnamespace = ns.oid JOIN pg_attribute a ON attrelid = typrelid -WHERE typname = %s and nspname = 'public' +WHERE typname = %s and nspname = %s ORDER BY attnum; -""", (name, )) +""", (tname, schema)) recs = curs.fetchall() @@ -859,7 +866,7 @@ ORDER BY attnum; type_oid = recs[0][0] type_attrs = [ (r[1], r[2]) for r in recs ] - return CompositeCaster(name, type_oid, type_attrs) + return CompositeCaster(tname, type_oid, type_attrs) def register_composite(name, conn_or_curs, globally=False): """Register a typecaster to convert a composite type into a tuple. diff --git a/tests/types_extras.py b/tests/types_extras.py index bb763384..5a55c6ec 100755 --- a/tests/types_extras.py +++ b/tests/types_extras.py @@ -525,6 +525,24 @@ class AdaptTypeTestCase(unittest.TestCase): conn1.close() conn2.close() + @skip_if_no_composite + def test_composite_namespace(self): + curs = self.conn.cursor() + curs.execute(""" + select nspname from pg_namespace + where nspname = 'typens'; + """) + if not curs.fetchone(): + curs.execute("create schema typens;") + self.conn.commit() + + self._create_type("typens.typens_ii", + [("a", "integer"), ("b", "integer")]) + t = psycopg2.extras.register_composite( + "typens.typens_ii", self.conn) + curs.execute("select (4,8)::typens.typens_ii") + self.assertEqual(curs.fetchone()[0], (4,8)) + def _create_type(self, name, fields): curs = self.conn.cursor() try: @@ -534,11 +552,16 @@ class AdaptTypeTestCase(unittest.TestCase): curs.execute("create type %s as (%s);" % (name, ", ".join(["%s %s" % p for p in fields]))) + if '.' in name: + schema, name = name.split('.') + else: + schema = 'public' + curs.execute("""\ SELECT t.oid FROM pg_type t JOIN pg_namespace ns ON typnamespace = ns.oid - WHERE typname = %s and nspname = 'public'; - """, (name,)) + WHERE typname = %s and nspname = %s; + """, (name, schema)) oid = curs.fetchone()[0] self.conn.commit() return oid