diff options
Diffstat (limited to 'lib/sqlalchemy/dialects/postgresql/base.py')
-rw-r--r-- | lib/sqlalchemy/dialects/postgresql/base.py | 44 |
1 files changed, 32 insertions, 12 deletions
diff --git a/lib/sqlalchemy/dialects/postgresql/base.py b/lib/sqlalchemy/dialects/postgresql/base.py index 5ff2f7c61..b3506f5d2 100644 --- a/lib/sqlalchemy/dialects/postgresql/base.py +++ b/lib/sqlalchemy/dialects/postgresql/base.py @@ -1669,11 +1669,12 @@ class PGDialect(default.DefaultDialect): "ops": {} }), (schema.Table, { - "ignore_search_path": False + "ignore_search_path": False, + "relkind": None }) ] - reflection_options = ('postgresql_ignore_search_path', ) + reflection_options = ('postgresql_ignore_search_path', 'postgresql_relkind') _backslash_escapes = True @@ -1898,7 +1899,7 @@ class PGDialect(default.DefaultDialect): return tuple([int(x) for x in m.group(1, 2, 3) if x is not None]) @reflection.cache - def get_table_oid(self, connection, table_name, schema=None, **kw): + def get_table_oid(self, connection, table_name, schema=None, postgresql_relkind=None, **kw): """Fetch the oid for schema.table_name. Several reflection methods require the table oid. The idea for using @@ -1911,13 +1912,28 @@ class PGDialect(default.DefaultDialect): schema_where_clause = "n.nspname = :schema" else: schema_where_clause = "pg_catalog.pg_table_is_visible(c.oid)" + + RELKIND_SYNONYMS = { + 'materialized': 'm', + 'foreign': 'f' + } + ACCEPTED_RELKINDS = ('r','v','m','f') + if postgresql_relkind is None: + postgresql_relkind = 'r' + else: + postgresql_relkind = postgresql_relkind.lower() + if postgresql_relkind in RELKIND_SYNONYMS: + postgresql_relkind = RELKIND_SYNONYMS[postgresql_relkind.lower()] + if postgresql_relkind not in ACCEPTED_RELKINDS: + raise exc.SQLAlchemyError('Invalid postgresql_relkind: %s' % postgresql_relkind) + query = """ SELECT c.oid FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE (%s) - AND c.relname = :table_name AND c.relkind in ('r','v') - """ % schema_where_clause + AND c.relname = :table_name AND c.relkind in ('%s', 'v') + """ % (schema_where_clause, postgresql_relkind) # Since we're binding to unicode, table_name and schema_name must be # unicode. table_name = util.text_type(table_name) @@ -2014,7 +2030,8 @@ class PGDialect(default.DefaultDialect): def get_columns(self, connection, table_name, schema=None, **kw): table_oid = self.get_table_oid(connection, table_name, schema, - info_cache=kw.get('info_cache')) + info_cache=kw.get('info_cache'), + postgresql_relkind=kw.get('postgresql_relkind')) SQL_COLS = """ SELECT a.attname, pg_catalog.format_type(a.atttypid, a.atttypmod), @@ -2164,7 +2181,8 @@ class PGDialect(default.DefaultDialect): @reflection.cache def get_pk_constraint(self, connection, table_name, schema=None, **kw): table_oid = self.get_table_oid(connection, table_name, schema, - info_cache=kw.get('info_cache')) + info_cache=kw.get('info_cache'), + postgresql_relkind=kw.get('postgresql_relkind')) if self.server_version_info < (8, 4): PK_SQL = """ @@ -2214,7 +2232,8 @@ class PGDialect(default.DefaultDialect): postgresql_ignore_search_path=False, **kw): preparer = self.identifier_preparer table_oid = self.get_table_oid(connection, table_name, schema, - info_cache=kw.get('info_cache')) + info_cache=kw.get('info_cache'), + postgresql_relkind=kw.get('postgresql_relkind')) FK_SQL = """ SELECT r.conname, @@ -2318,11 +2337,11 @@ class PGDialect(default.DefaultDialect): @reflection.cache def get_indexes(self, connection, table_name, schema, **kw): table_oid = self.get_table_oid(connection, table_name, schema, - info_cache=kw.get('info_cache')) + info_cache=kw.get('info_cache'), + postgresql_relkind=kw.get('postgresql_relkind')) # cast indkey as varchar since it's an int2vector, # returned as a list by some drivers such as pypostgresql - IDX_SQL = """ SELECT i.relname as relname, @@ -2336,7 +2355,7 @@ class PGDialect(default.DefaultDialect): pg_attribute a on t.oid=a.attrelid and %s WHERE - t.relkind = 'r' + t.relkind IN ('r', 'v', 'f', 'm') and t.oid = :table_oid and ix.indisprimary = 'f' ORDER BY @@ -2391,7 +2410,8 @@ class PGDialect(default.DefaultDialect): def get_unique_constraints(self, connection, table_name, schema=None, **kw): table_oid = self.get_table_oid(connection, table_name, schema, - info_cache=kw.get('info_cache')) + info_cache=kw.get('info_cache'), + postgresql_relkind=kw.get('postgresql_relkind')) UNIQUE_SQL = """ SELECT |