mirror of
https://github.com/django/django.git
synced 2025-11-17 10:43:25 +00:00
Refs #24928 -- Added introspection support for PostgreSQL HStoreField.
This commit is contained in:
parent
0eec2a163a
commit
35f86b641a
6 changed files with 37 additions and 2 deletions
|
|
@ -65,6 +65,11 @@ class PostgresConfig(AppConfig):
|
|||
3910: "django.contrib.postgres.fields.DateTimeRangeField",
|
||||
3912: "django.contrib.postgres.fields.DateRangeField",
|
||||
3926: "django.contrib.postgres.fields.BigIntegerRangeField",
|
||||
# PostgreSQL OIDs may vary depending on the
|
||||
# installation, especially for datatypes from
|
||||
# extensions, e.g. "hstore". In such cases, the
|
||||
# type_display attribute (psycopg 3.2+) should be used.
|
||||
"hstore": "django.contrib.postgres.fields.HStoreField",
|
||||
}
|
||||
)
|
||||
if conn.connection is not None:
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import asyncio
|
|||
import threading
|
||||
import warnings
|
||||
from contextlib import contextmanager
|
||||
from functools import lru_cache
|
||||
|
||||
from django.conf import settings
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
|
|
@ -29,6 +30,7 @@ except ImportError:
|
|||
raise ImproperlyConfigured("Error loading psycopg2 or psycopg module")
|
||||
|
||||
|
||||
@lru_cache
|
||||
def psycopg_version():
|
||||
version = Database.__version__.split(" ", 1)[0]
|
||||
return get_version_tuple(version)
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ 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 as BaseTableInfo
|
||||
from django.db.backends.postgresql.base import psycopg_version
|
||||
from django.db.models import DB_CASCADE, DB_SET_DEFAULT, DB_SET_NULL, DO_NOTHING, Index
|
||||
|
||||
FieldInfo = namedtuple("FieldInfo", [*BaseFieldInfo._fields, "is_autofield", "comment"])
|
||||
|
|
@ -120,10 +121,19 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
|
|||
cursor.execute(
|
||||
"SELECT * FROM %s LIMIT 1" % self.connection.ops.quote_name(table_name)
|
||||
)
|
||||
|
||||
# PostgreSQL OIDs may vary depending on the installation, especially
|
||||
# for datatypes from extensions, e.g. "hstore". In such cases, the
|
||||
# type_display attribute (psycopg 3.2+) should be used.
|
||||
type_display_available = psycopg_version() >= (3, 2)
|
||||
return [
|
||||
FieldInfo(
|
||||
line.name,
|
||||
line.type_code,
|
||||
(
|
||||
line.type_display
|
||||
if type_display_available and line.type_display == "hstore"
|
||||
else line.type_code
|
||||
),
|
||||
# display_size is always None on psycopg2.
|
||||
line.internal_size if line.display_size is None else line.display_size,
|
||||
line.internal_size,
|
||||
|
|
|
|||
|
|
@ -126,7 +126,9 @@ Minor features
|
|||
:mod:`django.contrib.postgres`
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* ...
|
||||
* :djadmin:`inspectdb` now introspects
|
||||
:class:`~django.contrib.postgres.fields.HStoreField` when ``psycopg`` 3.2+ is
|
||||
installed and ``django.contrib.postgres`` is in :setting:`INSTALLED_APPS`.
|
||||
|
||||
:mod:`django.contrib.redirects`
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
|
|
|||
|
|
@ -517,8 +517,11 @@ class Tests(TestCase):
|
|||
def test_correct_extraction_psycopg_version(self):
|
||||
from django.db.backends.postgresql.base import Database, psycopg_version
|
||||
|
||||
psycopg_version.cache_clear()
|
||||
with mock.patch.object(Database, "__version__", "4.2.1 (dt dec pq3 ext lo64)"):
|
||||
self.addCleanup(psycopg_version.cache_clear)
|
||||
self.assertEqual(psycopg_version(), (4, 2, 1))
|
||||
psycopg_version.cache_clear()
|
||||
with mock.patch.object(
|
||||
Database, "__version__", "4.2b0.dev1 (dt dec pq3 ext lo64)"
|
||||
):
|
||||
|
|
|
|||
|
|
@ -33,3 +33,16 @@ class InspectDBTests(PostgreSQLTestCase):
|
|||
"null=True)",
|
||||
],
|
||||
)
|
||||
|
||||
def test_hstore_field(self):
|
||||
from django.db.backends.postgresql.base import psycopg_version
|
||||
|
||||
if psycopg_version() < (3, 2):
|
||||
self.skipTest("psycopg 3.2+ is required.")
|
||||
self.assertFieldsInModel(
|
||||
"postgres_tests_hstoremodel",
|
||||
[
|
||||
"field = django.contrib.postgres.fields.HStoreField(blank=True, "
|
||||
"null=True)",
|
||||
],
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue