Fixed #29719 -- Added introspection of foreign tables for PostgreSQL.

Thanks infinite-l00p for the initial patch.
This commit is contained in:
Nick Pope 2018-09-12 01:36:15 +01:00 committed by Tim Graham
parent 31edb106b5
commit 45ef3df7d0
4 changed files with 45 additions and 2 deletions

View File

@ -44,11 +44,11 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
SELECT c.relname, c.relkind SELECT c.relname, c.relkind
FROM pg_catalog.pg_class c FROM pg_catalog.pg_class c
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind IN ('r', 'v') WHERE c.relkind IN ('f', 'r', 'v')
AND n.nspname NOT IN ('pg_catalog', 'pg_toast') AND n.nspname NOT IN ('pg_catalog', 'pg_toast')
AND pg_catalog.pg_table_is_visible(c.oid) AND pg_catalog.pg_table_is_visible(c.oid)
""") """)
mapping = {'r': 't', 'v': 'v'} mapping = {'f': 't', 'r': 't', 'v': 'v'}
return [ return [
TableInfo(row[0], mapping[row[1]]) TableInfo(row[0], mapping[row[1]])
for row in cursor.fetchall() if row[0] not in self.ignored_tables for row in cursor.fetchall() if row[0] not in self.ignored_tables

View File

@ -395,6 +395,18 @@ table's lifecycle, you'll need to change the
:attr:`~django.db.models.Options.managed` option to ``True`` (or simply remove :attr:`~django.db.models.Options.managed` option to ``True`` (or simply remove
it because ``True`` is its default value). it because ``True`` is its default value).
Database-specific notes
~~~~~~~~~~~~~~~~~~~~~~~
PostgreSQL
^^^^^^^^^^
* Models are created for foreign tables.
.. versionchanged:: 2.2
Support for foreign tables was added.
.. django-admin-option:: --database DATABASE .. django-admin-option:: --database DATABASE
Specifies the database to introspect. Defaults to ``default``. Specifies the database to introspect. Defaults to ``default``.

View File

@ -177,6 +177,8 @@ Management Commands
* The new :option:`--force-color` option forces colorization of the command * The new :option:`--force-color` option forces colorization of the command
output. output.
* :djadmin:`inspectdb` now creates models for foreign tables on PostgreSQL.
Migrations Migrations
~~~~~~~~~~ ~~~~~~~~~~

View File

@ -309,3 +309,32 @@ class InspectDBTransactionalTests(TransactionTestCase):
finally: finally:
with connection.cursor() as cursor: with connection.cursor() as cursor:
cursor.execute('DROP VIEW inspectdb_people_view') cursor.execute('DROP VIEW inspectdb_people_view')
@skipUnless(connection.vendor == 'postgresql', 'PostgreSQL specific SQL')
def test_foreign_data_wrapper(self):
with connection.cursor() as cursor:
cursor.execute('CREATE EXTENSION IF NOT EXISTS file_fdw')
cursor.execute('CREATE SERVER inspectdb_server FOREIGN DATA WRAPPER file_fdw')
cursor.execute('''\
CREATE FOREIGN TABLE inspectdb_iris_foreign_table (
petal_length real,
petal_width real,
sepal_length real,
sepal_width real
) SERVER inspectdb_server OPTIONS (
filename '/dev/null'
)
''')
out = StringIO()
foreign_table_model = 'class InspectdbIrisForeignTable(models.Model):'
foreign_table_managed = 'managed = False'
try:
call_command('inspectdb', stdout=out)
output = out.getvalue()
self.assertIn(foreign_table_model, output)
self.assertIn(foreign_table_managed, output)
finally:
with connection.cursor() as cursor:
cursor.execute('DROP FOREIGN TABLE IF EXISTS inspectdb_iris_foreign_table')
cursor.execute('DROP SERVER IF EXISTS inspectdb_server')
cursor.execute('DROP EXTENSION IF EXISTS file_fdw')