xdjango-postgres-extra 2.1.2__tar.gz → 2.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. {xdjango_postgres_extra-2.1.2/xdjango_postgres_extra.egg-info → xdjango_postgres_extra-2.2.0}/PKG-INFO +2 -1
  2. xdjango_postgres_extra-2.2.0/psqlextra/_version.py +1 -0
  3. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/backend/introspection.py +16 -2
  4. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/backend/migrations/operations/create_partitioned_model.py +10 -4
  5. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/backend/schema.py +10 -2
  6. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/setup.py +1 -0
  7. xdjango_postgres_extra-2.2.0/tests/test_django_61_compatibility.py +79 -0
  8. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/tests/test_make_migrations.py +6 -1
  9. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/tests/test_schema_editor_clone_model_to_schema.py +11 -3
  10. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0/xdjango_postgres_extra.egg-info}/PKG-INFO +2 -1
  11. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/xdjango_postgres_extra.egg-info/SOURCES.txt +1 -0
  12. xdjango_postgres_extra-2.1.2/psqlextra/_version.py +0 -1
  13. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/LICENSE +0 -0
  14. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/README.md +0 -0
  15. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/__init__.py +0 -0
  16. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/apps.py +0 -0
  17. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/backend/__init__.py +0 -0
  18. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/backend/base.py +0 -0
  19. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/backend/base_impl.py +0 -0
  20. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/backend/migrations/__init__.py +0 -0
  21. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/backend/migrations/operations/__init__.py +0 -0
  22. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/backend/migrations/operations/add_default_partition.py +0 -0
  23. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/backend/migrations/operations/add_hash_partition.py +0 -0
  24. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/backend/migrations/operations/add_list_partition.py +0 -0
  25. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/backend/migrations/operations/add_range_partition.py +0 -0
  26. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/backend/migrations/operations/apply_state.py +0 -0
  27. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/backend/migrations/operations/create_materialized_view_model.py +0 -0
  28. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/backend/migrations/operations/create_view_model.py +0 -0
  29. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/backend/migrations/operations/delete_default_partition.py +0 -0
  30. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/backend/migrations/operations/delete_hash_partition.py +0 -0
  31. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/backend/migrations/operations/delete_list_partition.py +0 -0
  32. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/backend/migrations/operations/delete_materialized_view_model.py +0 -0
  33. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/backend/migrations/operations/delete_partition.py +0 -0
  34. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/backend/migrations/operations/delete_partitioned_model.py +0 -0
  35. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/backend/migrations/operations/delete_range_partition.py +0 -0
  36. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/backend/migrations/operations/delete_view_model.py +0 -0
  37. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/backend/migrations/operations/partition.py +0 -0
  38. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/backend/migrations/patched_autodetector.py +0 -0
  39. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/backend/migrations/patched_migrations.py +0 -0
  40. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/backend/migrations/patched_project_state.py +0 -0
  41. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/backend/migrations/state/__init__.py +0 -0
  42. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/backend/migrations/state/materialized_view.py +0 -0
  43. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/backend/migrations/state/model.py +0 -0
  44. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/backend/migrations/state/partitioning.py +0 -0
  45. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/backend/migrations/state/view.py +0 -0
  46. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/backend/operations.py +0 -0
  47. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/backend/side_effects/__init__.py +0 -0
  48. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/backend/side_effects/hstore_required.py +0 -0
  49. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/backend/side_effects/hstore_unique.py +0 -0
  50. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/compiler.py +0 -0
  51. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/contrib/__init__.py +0 -0
  52. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/contrib/expressions.py +0 -0
  53. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/contrib/model_data_migrator.py +0 -0
  54. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/contrib/static_row.py +0 -0
  55. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/contrib/transaction.py +0 -0
  56. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/error.py +0 -0
  57. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/expressions.py +0 -0
  58. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/fields/__init__.py +0 -0
  59. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/fields/hstore_field.py +0 -0
  60. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/indexes/__init__.py +0 -0
  61. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/indexes/case_insensitive_unique_index.py +0 -0
  62. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/indexes/conditional_unique_index.py +0 -0
  63. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/indexes/unique_index.py +0 -0
  64. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/introspect/__init__.py +0 -0
  65. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/introspect/fields.py +0 -0
  66. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/introspect/models.py +0 -0
  67. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/locking.py +0 -0
  68. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/lookups.py +0 -0
  69. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/management/__init__.py +0 -0
  70. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/management/commands/__init__.py +0 -0
  71. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/management/commands/pgmakemigrations.py +0 -0
  72. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/management/commands/pgpartition.py +0 -0
  73. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/management/commands/pgrefreshmv.py +0 -0
  74. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/manager/__init__.py +0 -0
  75. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/manager/manager.py +0 -0
  76. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/models/__init__.py +0 -0
  77. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/models/base.py +0 -0
  78. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/models/options.py +0 -0
  79. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/models/partitioned.py +0 -0
  80. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/models/view.py +0 -0
  81. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/partitioning/__init__.py +0 -0
  82. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/partitioning/config.py +0 -0
  83. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/partitioning/constants.py +0 -0
  84. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/partitioning/current_time_strategy.py +0 -0
  85. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/partitioning/error.py +0 -0
  86. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/partitioning/manager.py +0 -0
  87. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/partitioning/partition.py +0 -0
  88. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/partitioning/plan.py +0 -0
  89. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/partitioning/range_partition.py +0 -0
  90. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/partitioning/range_strategy.py +0 -0
  91. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/partitioning/shorthands.py +0 -0
  92. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/partitioning/strategy.py +0 -0
  93. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/partitioning/time_partition.py +0 -0
  94. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/partitioning/time_partition_size.py +0 -0
  95. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/partitioning/time_strategy.py +0 -0
  96. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/py.typed +0 -0
  97. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/query.py +0 -0
  98. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/schema.py +0 -0
  99. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/settings.py +0 -0
  100. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/sql.py +0 -0
  101. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/type_assertions.py +0 -0
  102. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/types.py +0 -0
  103. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/psqlextra/util.py +0 -0
  104. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/pyproject.toml +0 -0
  105. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/setup.cfg +0 -0
  106. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/tests/test_append_caller_to_sql.py +0 -0
  107. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/tests/test_case_insensitive_unique_index.py +0 -0
  108. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/tests/test_conditional_unique_index.py +0 -0
  109. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/tests/test_db_backend.py +0 -0
  110. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/tests/test_django_6_compatibility.py +0 -0
  111. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/tests/test_hstore_autodetect.py +0 -0
  112. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/tests/test_hstore_field.py +0 -0
  113. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/tests/test_hstore_required.py +0 -0
  114. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/tests/test_hstore_unique.py +0 -0
  115. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/tests/test_insert.py +0 -0
  116. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/tests/test_introspect.py +0 -0
  117. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/tests/test_locking.py +0 -0
  118. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/tests/test_lookups.py +0 -0
  119. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/tests/test_management_command_partition.py +0 -0
  120. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/tests/test_manager.py +0 -0
  121. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/tests/test_manager_context.py +0 -0
  122. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/tests/test_materialized_view_model.py +0 -0
  123. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/tests/test_migration_operations.py +0 -0
  124. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/tests/test_on_conflict.py +0 -0
  125. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/tests/test_on_conflict_nothing.py +0 -0
  126. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/tests/test_on_conflict_update.py +0 -0
  127. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/tests/test_partitioned_model.py +0 -0
  128. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/tests/test_partitioned_model_state.py +0 -0
  129. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/tests/test_partitioning_manager.py +0 -0
  130. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/tests/test_partitioning_time.py +0 -0
  131. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/tests/test_query.py +0 -0
  132. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/tests/test_query_values.py +0 -0
  133. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/tests/test_schema.py +0 -0
  134. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/tests/test_schema_editor_alter_schema.py +0 -0
  135. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/tests/test_schema_editor_partitioning.py +0 -0
  136. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/tests/test_schema_editor_storage_settings.py +0 -0
  137. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/tests/test_schema_editor_vacuum.py +0 -0
  138. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/tests/test_schema_editor_view.py +0 -0
  139. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/tests/test_settings.py +0 -0
  140. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/tests/test_unique_index.py +0 -0
  141. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/tests/test_upsert.py +0 -0
  142. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/tests/test_view_models.py +0 -0
  143. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/xdjango_postgres_extra.egg-info/dependency_links.txt +0 -0
  144. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/xdjango_postgres_extra.egg-info/requires.txt +0 -0
  145. {xdjango_postgres_extra-2.1.2 → xdjango_postgres_extra-2.2.0}/xdjango_postgres_extra.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: xdjango-postgres-extra
3
- Version: 2.1.2
3
+ Version: 2.2.0
4
4
  Summary: Bringing all of PostgreSQL's awesomeness to Django.
5
5
  Home-page: https://github.com/SectorLabs/django-postgres-extra
6
6
  Author: Sector Labs
@@ -10,6 +10,7 @@ Keywords: django,postgres,extra,hstore,upsert,partioning,materialized,view
10
10
  Classifier: Environment :: Web Environment
11
11
  Classifier: Framework :: Django
12
12
  Classifier: Framework :: Django :: 6.0
13
+ Classifier: Framework :: Django :: 6.1
13
14
  Classifier: Intended Audience :: Developers
14
15
  Classifier: License :: OSI Approved :: MIT License
15
16
  Classifier: Operating System :: OS Independent
@@ -0,0 +1 @@
1
+ __version__ = "2.2.0"
@@ -1,6 +1,8 @@
1
1
  from dataclasses import dataclass
2
2
  from typing import TYPE_CHECKING, Dict, List, Optional, Tuple
3
3
 
4
+ import django
5
+
4
6
  from django.db.backends.postgresql.introspection import ( # type: ignore[import]
5
7
  DatabaseIntrospection,
6
8
  )
@@ -305,13 +307,16 @@ class PostgresIntrospection(Introspection):
305
307
  """Gets a dictionary {field_name: (field_name_other_table,
306
308
  other_table)} representing all relations in the specified table.
307
309
 
310
+ Django 6.1 and newer expect a third element in the value tuple
311
+ that describes the database-level ON DELETE behaviour.
312
+
308
313
  This is overriden because the query in Django does not handle
309
314
  relations between tables in different schemas properly.
310
315
  """
311
316
 
312
317
  cursor.execute(
313
318
  """
314
- SELECT a1.attname, c2.relname, a2.attname
319
+ SELECT a1.attname, c2.relname, a2.attname, con.confdeltype
315
320
  FROM pg_constraint con
316
321
  LEFT JOIN pg_class c1 ON con.conrelid = c1.oid
317
322
  LEFT JOIN pg_class c2 ON con.confrelid = c2.oid
@@ -324,4 +329,13 @@ class PostgresIntrospection(Introspection):
324
329
  """,
325
330
  [table_name],
326
331
  )
327
- return {row[0]: (row[2], row[1]) for row in cursor.fetchall()}
332
+
333
+ rows = cursor.fetchall()
334
+
335
+ if django.VERSION >= (6, 1):
336
+ return {
337
+ row[0]: (row[2], row[1], self.on_delete_types.get(row[3]))
338
+ for row in rows
339
+ }
340
+
341
+ return {row[0]: (row[2], row[1]) for row in rows}
@@ -74,13 +74,19 @@ class PostgresCreatePartitionedModel(CreateModel):
74
74
  result = super().reduce(*args, **kwargs)
75
75
 
76
76
  # replace CreateModel operation with PostgresCreatePartitionedModel
77
+ #
78
+ # Django >= 6.0 reduces through `copy.replace()`, which rebuilds the
79
+ # operation as its own class, partitioning options included. Only a
80
+ # plain CreateModel still has to be converted.
77
81
  if isinstance(result, list) and result:
78
82
  for i, op in enumerate(result):
79
- if isinstance(op, CreateModel):
80
- _, args, kwargs = op.deconstruct()
83
+ if isinstance(op, CreateModel) and not isinstance(
84
+ op, PostgresCreatePartitionedModel
85
+ ):
86
+ _, op_args, op_kwargs = op.deconstruct()
81
87
  result[i] = PostgresCreatePartitionedModel(
82
- *args,
83
- **kwargs,
88
+ *op_args,
89
+ **op_kwargs,
84
90
  partitioning_options=self.partitioning_options
85
91
  )
86
92
 
@@ -295,8 +295,7 @@ class PostgresSchemaEditor(SchemaEditor):
295
295
  model, [field.column], foreign_key=True
296
296
  )
297
297
 
298
- sql = Statement(
299
- self.sql_create_fk_not_valid,
298
+ fk_parts = dict(
300
299
  table=self.quote_name(model._meta.db_table),
301
300
  name=self.quote_name(fk_name),
302
301
  column=self.quote_name(field.column),
@@ -307,6 +306,15 @@ class PostgresSchemaEditor(SchemaEditor):
307
306
  deferrable=self.connection.ops.deferrable_sql(),
308
307
  )
309
308
 
309
+ # Django 6.1 added a database-level ON DELETE clause to
310
+ # the foreign key statement we borrow the template from.
311
+ if django.VERSION >= (6, 1):
312
+ fk_parts["on_delete_db"] = self._create_on_delete_sql( # type: ignore[attr-defined]
313
+ model, field
314
+ )
315
+
316
+ sql = Statement(self.sql_create_fk_not_valid, **fk_parts)
317
+
310
318
  self.execute(sql)
311
319
 
312
320
  # It's hard to alter a field's check because it is defined
@@ -37,6 +37,7 @@ setup(
37
37
  "Environment :: Web Environment",
38
38
  "Framework :: Django",
39
39
  "Framework :: Django :: 6.0",
40
+ "Framework :: Django :: 6.1",
40
41
  "Intended Audience :: Developers",
41
42
  "License :: OSI Approved :: MIT License",
42
43
  "Operating System :: OS Independent",
@@ -0,0 +1,79 @@
1
+ import io
2
+
3
+ import django
4
+ import pytest
5
+
6
+ from django.core.management import call_command
7
+ from django.db import models
8
+
9
+ from . import db_introspection
10
+ from .fake_model import delete_fake_model, get_fake_model
11
+
12
+ pytestmark = pytest.mark.skipif(
13
+ django.VERSION < (6, 1),
14
+ reason="Django < 6.1 does not report database level ON DELETE behaviour",
15
+ )
16
+
17
+
18
+ @pytest.fixture
19
+ def fk_target():
20
+ model = get_fake_model({"name": models.TextField()})
21
+
22
+ yield model
23
+
24
+ delete_fake_model(model)
25
+
26
+
27
+ @pytest.fixture
28
+ def fk_source(fk_target):
29
+ model = get_fake_model(
30
+ {
31
+ "python_cascade": models.ForeignKey(
32
+ fk_target, on_delete=models.CASCADE, related_name="+"
33
+ ),
34
+ "db_cascade": models.ForeignKey(
35
+ fk_target, on_delete=models.DB_CASCADE, related_name="+"
36
+ ),
37
+ }
38
+ )
39
+
40
+ yield model
41
+
42
+ delete_fake_model(model)
43
+
44
+
45
+ def test_get_relations_reports_db_on_delete(fk_target, fk_source):
46
+ """Django 6.1 and newer expect the values of the dict returned by
47
+ `get_relations` to carry the database level ON DELETE behaviour as a third
48
+ element."""
49
+
50
+ relations = db_introspection.get_relations(fk_source._meta.db_table)
51
+
52
+ assert relations == {
53
+ # a Python level on_delete leaves no ON DELETE clause behind
54
+ "python_cascade_id": (
55
+ "id",
56
+ fk_target._meta.db_table,
57
+ models.DO_NOTHING,
58
+ ),
59
+ "db_cascade_id": (
60
+ "id",
61
+ fk_target._meta.db_table,
62
+ models.DB_CASCADE,
63
+ ),
64
+ }
65
+
66
+
67
+ def test_inspectdb_unpacks_relations(fk_target, fk_source):
68
+ """`inspectdb` is the one command that unpacks the value tuples returned by
69
+ `get_relations`, so it breaks loudly when their shape is wrong."""
70
+
71
+ stdout = io.StringIO()
72
+ call_command(
73
+ "inspectdb",
74
+ fk_target._meta.db_table,
75
+ fk_source._meta.db_table,
76
+ stdout=stdout,
77
+ )
78
+
79
+ assert "ForeignKey" in stdout.getvalue()
@@ -174,7 +174,12 @@ def test_make_migration_field_operations_view_models(
174
174
  last_name_field = models.TextField(null=True)
175
175
  last_name_field.contribute_to_class(model, "last_name")
176
176
 
177
- migration = make_migration(model._meta.app_label, from_state=state_1)
177
+ # a clone, because Django >= 6.0 strips `indexes`/`constraints` out of
178
+ # the options of the state it detects changes against, and `state_1` is
179
+ # re-used as the target state further down
180
+ migration = make_migration(
181
+ model._meta.app_label, from_state=state_1.clone()
182
+ )
178
183
  assert len(migration.operations) == 1
179
184
  assert isinstance(migration.operations[0], operations.ApplyState)
180
185
  assert isinstance(migration.operations[0].state_operation, AddField)
@@ -156,6 +156,16 @@ def fake_model_fk_target_2():
156
156
 
157
157
  @pytest.fixture
158
158
  def fake_model(fake_model_fk_target_1, fake_model_fk_target_2):
159
+ # `check` was renamed to `condition` in Django 5.1 and dropped in 6.0
160
+ if django.VERSION >= (5, 1):
161
+ age_height_check = models.CheckConstraint(
162
+ condition=Q(age__gt=0, height__gt=0), name="age_height_check"
163
+ )
164
+ else:
165
+ age_height_check = models.CheckConstraint(
166
+ check=Q(age__gt=0, height__gt=0), name="age_height_check"
167
+ )
168
+
159
169
  meta_options = {
160
170
  "indexes": [
161
171
  models.Index(fields=["age", "height"]),
@@ -167,9 +177,7 @@ def fake_model(fake_model_fk_target_1, fake_model_fk_target_2):
167
177
  fields=["first_name", "last_name"],
168
178
  name="first_last_name_uniq",
169
179
  ),
170
- models.CheckConstraint(
171
- check=Q(age__gt=0, height__gt=0), name="age_height_check"
172
- ),
180
+ age_height_check,
173
181
  ],
174
182
  "unique_together": (
175
183
  "first_name",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: xdjango-postgres-extra
3
- Version: 2.1.2
3
+ Version: 2.2.0
4
4
  Summary: Bringing all of PostgreSQL's awesomeness to Django.
5
5
  Home-page: https://github.com/SectorLabs/django-postgres-extra
6
6
  Author: Sector Labs
@@ -10,6 +10,7 @@ Keywords: django,postgres,extra,hstore,upsert,partioning,materialized,view
10
10
  Classifier: Environment :: Web Environment
11
11
  Classifier: Framework :: Django
12
12
  Classifier: Framework :: Django :: 6.0
13
+ Classifier: Framework :: Django :: 6.1
13
14
  Classifier: Intended Audience :: Developers
14
15
  Classifier: License :: OSI Approved :: MIT License
15
16
  Classifier: Operating System :: OS Independent
@@ -100,6 +100,7 @@ tests/test_append_caller_to_sql.py
100
100
  tests/test_case_insensitive_unique_index.py
101
101
  tests/test_conditional_unique_index.py
102
102
  tests/test_db_backend.py
103
+ tests/test_django_61_compatibility.py
103
104
  tests/test_django_6_compatibility.py
104
105
  tests/test_hstore_autodetect.py
105
106
  tests/test_hstore_field.py
@@ -1 +0,0 @@
1
- __version__ = "2.1.2"