feat: migrate Django 5.2 upgrade and 3.2/4.2 deprecations#16624
feat: migrate Django 5.2 upgrade and 3.2/4.2 deprecations#16624sinhasubham wants to merge 3 commits intomainfrom
Conversation
There was a problem hiding this comment.
Code Review
This pull request updates the Spanner database backend to support Django 5.2 and Python 3.10+, while removing legacy support for Django 3.2 and 4.2. Key changes include the implementation of a global client cache to prevent initialization crashes, support for JSONArray, GeneratedField, and db_default, and a retry mechanism for flushing tables with foreign key constraints. Feedback highlights several critical issues: the use of a 32-bit mask for primary key generation significantly reduces the key space, and making GOOGLE_CLOUD_PROJECT mandatory is a breaking change for local development. Additionally, the package version was incorrectly decremented, and a minor version bump was recommended for this release. Finally, using WHERE 1=1 was suggested as a more idiomatic alternative to WHERE true for flush operations.
2b71c2a to
f6098f1
Compare
…bsolete workflows
f6098f1 to
4fc923b
Compare
|
|
||
| # Global cache for Spanner client to prevent multiple initializations | ||
| # which can cause OpenTelemetry 'MeterProvider override' crashes. | ||
| _SPANNER_CLIENT_CACHE = None |
There was a problem hiding this comment.
I dont understand why do we need this, ideally our Spanner client library should handle the override crash ?
| "project": os.environ.get("GOOGLE_CLOUD_PROJECT") | ||
| or self.settings_dict.get("project") | ||
| or self.settings_dict.get("PROJECT") | ||
| or "test-project", |
There was a problem hiding this comment.
This is being done in multiple places, better to extract in "init" method once and use it everywhere.
Also why do we support self.settings_dict.get("project") and self.settings_dict.get("PROJECT") now ?
| conn_params.pop("instance", None) | ||
| conn_params.pop("instance_id", None) | ||
| conn_params.pop("client", None) |
There was a problem hiding this comment.
Why this change is required ?
We are not using instance_id or client anywhere. We are only using instance.instance_id or instance._client
| # This method copies the complete code of this overridden method from | ||
| # Django core and modify it for Spanner by adding one line |
There was a problem hiding this comment.
This is duplicate comment
| except AttributeError: | ||
| # The test method might not exist in this version of Django. | ||
| pass |
There was a problem hiding this comment.
Why do we need this, we have already added an explicit list of skip tests
| # https://developers.google.com/open-source/licenses/bsd | ||
|
|
||
| __version__ = "4.0.3" | ||
| __version__ = "4.1.0" |
There was a problem hiding this comment.
Why are we modifying this version manually ? shouldn't this be updated automatically once we do the release ?
| self.assertEqual( | ||
| sql_compiled, | ||
| "SELECT tests_report.name FROM tests_report ORDER BY " | ||
| "SELECT tests_report.name AS name FROM tests_report ORDER BY " |
There was a problem hiding this comment.
For my knowledge why this change is required ?
|
|
||
| UNIT_TEST_PYTHON_VERSIONS = [ | ||
| "3.8", | ||
| "3.9", |
There was a problem hiding this comment.
I thought we received 3.9 support as well, as we removed 3.9 integration test suite file
| if session.python == "3.9": | ||
| session.skip("Python 3.9 is not supported for Django 5.2 tests") |
There was a problem hiding this comment.
Lets remove 3.9 from the list then ?
| # https://developers.google.com/open-source/licenses/bsd | ||
|
|
||
| __version__ = "4.0.3" | ||
| __version__ = "4.1.0" |
There was a problem hiding this comment.
Also this should go as a Major version release, since we are deprecating older vesion of Django.
PR title should be feat! to trigger a major version
| from django.db import DEFAULT_DB_ALIAS | ||
| from django.db.models.fields import ( | ||
|
|
||
| from django.db import DEFAULT_DB_ALIAS # noqa: E402 |
There was a problem hiding this comment.
why are you suppressing linting errors?
|
|
||
| def gen_rand_int64(): | ||
| # Credit to https://stackoverflow.com/a/3530326. | ||
| # Use 32-bit integer for Emulator compatibility (High-bit issues observed). |
There was a problem hiding this comment.
Is this a valid comment?
| method_name, | ||
| skip("unsupported by Spanner")(method), | ||
| ) | ||
| try: |
There was a problem hiding this comment.
Make you sure you clean up the method. Not suppress the error.
| "constraint": self.sql_check_constraint % {"check": check}, | ||
| } | ||
|
|
||
| def _unique_sql( |
There was a problem hiding this comment.
why are we removing it?
| @@ -28,7 +28,6 @@ | |||
| DEFAULT_PYTHON_VERSION = "3.14" | |||
|
|
|||
| UNIT_TEST_PYTHON_VERSIONS = [ | |||
There was a problem hiding this comment.
Remove support for 3.8 and 3.9
| else: | ||
| return [] | ||
|
|
||
| def execute_sql_flush(self, sql_list): |
There was a problem hiding this comment.
this looks so bruteforce. is there any other better approach?
| # Spanner does not support expression indexes | ||
| # example: CREATE INDEX index_name ON table (LOWER(column_name)) | ||
| supports_expression_indexes = False | ||
| supports_stored_generated_columns = True | ||
|
|
||
| # Django tests that aren't supported by Spanner. | ||
| skip_tests = ( |
There was a problem hiding this comment.
We need to group them by cause. Otherwise we will not know if we are doing it correctly or not.
| try: | ||
| cursor.execute(sql) | ||
| progress = True | ||
| except Exception as e: |
There was a problem hiding this comment.
catch more specific exception ?
Thank you for opening a Pull Request! Before submitting your PR, there are a few things you can do to make sure it goes smoothly:
Fixes #<issue_number_goes_here> 🦕