Browse Source

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

Thanks infinite-l00p for the initial patch.
Nick Pope 6 years ago
parent
commit
45ef3df7d0

+ 2 - 2
django/db/backends/postgresql/introspection.py

@@ -44,11 +44,11 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
             SELECT c.relname, c.relkind
             FROM pg_catalog.pg_class c
             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 pg_catalog.pg_table_is_visible(c.oid)
         """)
-        mapping = {'r': 't', 'v': 'v'}
+        mapping = {'f': 't', 'r': 't', 'v': 'v'}
         return [
             TableInfo(row[0], mapping[row[1]])
             for row in cursor.fetchall() if row[0] not in self.ignored_tables

+ 12 - 0
docs/ref/django-admin.txt

@@ -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
 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
 
 Specifies the database to introspect. Defaults to ``default``.

+ 2 - 0
docs/releases/2.2.txt

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

+ 29 - 0
tests/inspectdb/tests.py

@@ -309,3 +309,32 @@ class InspectDBTransactionalTests(TransactionTestCase):
         finally:
             with connection.cursor() as cursor:
                 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')