summaryrefslogtreecommitdiff
path: root/django/db/backends/postgresql/introspection.py
diff options
context:
space:
mode:
authorFlorian Apolloner <florian@apolloner.eu>2022-03-24 16:46:19 +0100
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2022-04-13 21:51:51 +0200
commit2eea361eff58dd98c409c5227064b901f41bd0d6 (patch)
treeb551c3b45c3d0f133d88ef346ec1657f937d2892 /django/db/backends/postgresql/introspection.py
parent62ffc9883afdc0a9f9674702661062508230d7bf (diff)
downloaddjango-2eea361eff58dd98c409c5227064b901f41bd0d6.tar.gz
Fixed #30511 -- Used identity columns instead of serials on PostgreSQL.
Diffstat (limited to 'django/db/backends/postgresql/introspection.py')
-rw-r--r--django/db/backends/postgresql/introspection.py51
1 files changed, 28 insertions, 23 deletions
diff --git a/django/db/backends/postgresql/introspection.py b/django/db/backends/postgresql/introspection.py
index 16d80663aa..921501a4a3 100644
--- a/django/db/backends/postgresql/introspection.py
+++ b/django/db/backends/postgresql/introspection.py
@@ -1,10 +1,12 @@
-from django.db.backends.base.introspection import (
- BaseDatabaseIntrospection,
- FieldInfo,
- TableInfo,
-)
+from collections import namedtuple
+
+from django.db.backends.base.introspection import BaseDatabaseIntrospection
+from django.db.backends.base.introspection import FieldInfo as BaseFieldInfo
+from django.db.backends.base.introspection import TableInfo
from django.db.models import Index
+FieldInfo = namedtuple("FieldInfo", BaseFieldInfo._fields + ("is_autofield",))
+
class DatabaseIntrospection(BaseDatabaseIntrospection):
# Maps type codes to Django Field types.
@@ -37,7 +39,11 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
def get_field_type(self, data_type, description):
field_type = super().get_field_type(data_type, description)
- if description.default and "nextval" in description.default:
+ if description.is_autofield or (
+ # Required for pre-Django 4.1 serial columns.
+ description.default
+ and "nextval" in description.default
+ ):
if field_type == "IntegerField":
return "AutoField"
elif field_type == "BigIntegerField":
@@ -84,7 +90,8 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
a.attname AS column_name,
NOT (a.attnotnull OR (t.typtype = 'd' AND t.typnotnull)) AS is_nullable,
pg_get_expr(ad.adbin, ad.adrelid) AS column_default,
- CASE WHEN collname = 'default' THEN NULL ELSE collname END AS collation
+ CASE WHEN collname = 'default' THEN NULL ELSE collname END AS collation,
+ a.attidentity != '' AS is_autofield
FROM pg_attribute a
LEFT JOIN pg_attrdef ad ON a.attrelid = ad.adrelid AND a.attnum = ad.adnum
LEFT JOIN pg_collation co ON a.attcollation = co.oid
@@ -118,23 +125,21 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
def get_sequences(self, cursor, table_name, table_fields=()):
cursor.execute(
"""
- SELECT s.relname as sequence_name, col.attname
- FROM pg_class s
- JOIN pg_namespace sn ON sn.oid = s.relnamespace
- JOIN
- pg_depend d ON d.refobjid = s.oid
+ SELECT
+ s.relname AS sequence_name,
+ a.attname AS colname
+ FROM
+ pg_class s
+ JOIN pg_depend d ON d.objid = s.oid
+ AND d.classid = 'pg_class'::regclass
AND d.refclassid = 'pg_class'::regclass
- JOIN
- pg_attrdef ad ON ad.oid = d.objid
- AND d.classid = 'pg_attrdef'::regclass
- JOIN
- pg_attribute col ON col.attrelid = ad.adrelid
- AND col.attnum = ad.adnum
- JOIN pg_class tbl ON tbl.oid = ad.adrelid
- WHERE s.relkind = 'S'
- AND d.deptype in ('a', 'n')
- AND pg_catalog.pg_table_is_visible(tbl.oid)
- AND tbl.relname = %s
+ JOIN pg_attribute a ON d.refobjid = a.attrelid
+ AND d.refobjsubid = a.attnum
+ JOIN pg_class tbl ON tbl.oid = d.refobjid
+ AND tbl.relname = %s
+ AND pg_catalog.pg_table_is_visible(tbl.oid)
+ WHERE
+ s.relkind = 'S';
""",
[table_name],
)