11import functools
22
33import psycopg2
4- from psycopg2 import ProgrammingError
54from psycopg2 .extras import register_hstore
65
76from django .db import connections
87from django .db .backends .base .base import NO_DB_ALIAS
98
109
11- @functools .lru_cache
12- def get_hstore_oids (connection_alias ):
13- """Return hstore and hstore array OIDs."""
10+ def get_type_oids (connection_alias , type_name ):
1411 with connections [connection_alias ].cursor () as cursor :
1512 cursor .execute (
16- "SELECT t.oid, typarray "
17- "FROM pg_type t "
18- "JOIN pg_namespace ns ON typnamespace = ns.oid "
19- "WHERE typname = 'hstore'"
13+ "SELECT oid, typarray FROM pg_type WHERE typname = %s" , (type_name ,)
2014 )
2115 oids = []
2216 array_oids = []
@@ -26,43 +20,42 @@ def get_hstore_oids(connection_alias):
2620 return tuple (oids ), tuple (array_oids )
2721
2822
23+ @functools .lru_cache
24+ def get_hstore_oids (connection_alias ):
25+ """Return hstore and hstore array OIDs."""
26+ return get_type_oids (connection_alias , "hstore" )
27+
28+
2929@functools .lru_cache
3030def get_citext_oids (connection_alias ):
31- """Return citext array OIDs."""
32- with connections [connection_alias ].cursor () as cursor :
33- cursor .execute ("SELECT typarray FROM pg_type WHERE typname = 'citext'" )
34- return tuple (row [0 ] for row in cursor )
31+ """Return citext and citext array OIDs."""
32+ return get_type_oids (connection_alias , "citext" )
3533
3634
3735def register_type_handlers (connection , ** kwargs ):
3836 if connection .vendor != "postgresql" or connection .alias == NO_DB_ALIAS :
3937 return
4038
41- try :
42- oids , array_oids = get_hstore_oids (connection .alias )
39+ oids , array_oids = get_hstore_oids (connection .alias )
40+ # Don't register handlers when hstore is not available on the database.
41+ #
42+ # If someone tries to create an hstore field it will error there. This is
43+ # necessary as someone may be using PSQL without extensions installed but
44+ # be using other features of contrib.postgres.
45+ #
46+ # This is also needed in order to create the connection in order to install
47+ # the hstore extension.
48+ if oids :
4349 register_hstore (
4450 connection .connection , globally = True , oid = oids , array_oid = array_oids
4551 )
46- except ProgrammingError :
47- # Hstore is not available on the database.
48- #
49- # If someone tries to create an hstore field it will error there.
50- # This is necessary as someone may be using PSQL without extensions
51- # installed but be using other features of contrib.postgres.
52- #
53- # This is also needed in order to create the connection in order to
54- # install the hstore extension.
55- pass
5652
57- try :
58- citext_oids = get_citext_oids (connection .alias )
53+ oids , citext_oids = get_citext_oids (connection .alias )
54+ # Don't register handlers when citext is not available on the database.
55+ #
56+ # The same comments in the above call to register_hstore() also apply here.
57+ if oids :
5958 array_type = psycopg2 .extensions .new_array_type (
6059 citext_oids , "citext[]" , psycopg2 .STRING
6160 )
6261 psycopg2 .extensions .register_type (array_type , None )
63- except ProgrammingError :
64- # citext is not available on the database.
65- #
66- # The same comments in the except block of the above call to
67- # register_hstore() also apply here.
68- pass
0 commit comments