Skip to content

feat: migrate Django 5.2 upgrade and 3.2/4.2 deprecations#16624

Draft
sinhasubham wants to merge 2 commits intomainfrom
django_upgrade_5_2
Draft

feat: migrate Django 5.2 upgrade and 3.2/4.2 deprecations#16624
sinhasubham wants to merge 2 commits intomainfrom
django_upgrade_5_2

Conversation

@sinhasubham
Copy link
Copy Markdown
Contributor

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:

  • Make sure to open an issue as a bug/issue before writing your code! That way we can discuss the change, evaluate designs, and agree on the general idea
  • Ensure the tests and linter pass
  • Code coverage does not decrease (if any source code was changed)
  • Appropriate docs were updated (if necessary)

Fixes #<issue_number_goes_here> 🦕

@sinhasubham sinhasubham changed the title Django upgrade 5 2 feat: migrate Django 5.2 upgrade and 3.2/4.2 deprecations Apr 13, 2026
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

# Credit to https://stackoverflow.com/a/3530326.
return uuid4().int & 0x7FFFFFFFFFFFFFFF
# Use 32-bit integer for Emulator compatibility (High-bit issues observed).
return uuid4().int & 0xFFFFFFFF
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

Using a 32-bit mask (0xFFFFFFFF) for a 64-bit integer field significantly reduces the key space for auto-generated primary keys. This could lead to key collisions much sooner than expected for an INT64 field. While the comment mentions emulator compatibility, this change could have serious implications in production. Could we use a 63-bit positive integer mask (0x7FFFFFFFFFFFFFFF) as before, and handle emulator-specific issues differently, perhaps with a configuration flag?

Suggested change
return uuid4().int & 0xFFFFFFFF
return uuid4().int & 0x7FFFFFFFFFFFFFFF


if _SPANNER_CLIENT_CACHE is None:
_SPANNER_CLIENT_CACHE = spanner.Client(
project=os.environ["GOOGLE_CLOUD_PROJECT"]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Changing os.environ.get("GOOGLE_CLOUD_PROJECT", "test-project") to os.environ["GOOGLE_CLOUD_PROJECT"] makes the GOOGLE_CLOUD_PROJECT environment variable mandatory, which will cause a KeyError if it's not set. This is a breaking change for users who might have relied on the fallback value, especially in local development or test environments not using the emulator. Was this change intended? It might be better to retain the fallback or raise a more informative ImproperlyConfigured exception if the project ID is missing.

Suggested change
project=os.environ["GOOGLE_CLOUD_PROJECT"]
project=os.environ.get("GOOGLE_CLOUD_PROJECT")

"""
return {
"project": os.environ.get("GOOGLE_CLOUD_PROJECT", "test-project"),
"project": os.environ["GOOGLE_CLOUD_PROJECT"],
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Similar to the change in the instance property, changing os.environ.get(...) to os.environ[...] here makes GOOGLE_CLOUD_PROJECT a mandatory environment variable. This is a breaking change. It would be better to handle the missing variable gracefully, for example by using os.environ.get() and then checking if the value is None.

Suggested change
"project": os.environ["GOOGLE_CLOUD_PROJECT"],
"project": os.environ.get("GOOGLE_CLOUD_PROJECT"),

# https://developers.google.com/open-source/licenses/bsd

__version__ = "4.0.3"
__version__ = "4.0.2"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The package version is being decremented from 4.0.3 to 4.0.2. This is unusual. Additionally, since this release includes an upgrade to a new major Django version (a breaking change in environment requirements), per repository rules, a minor version bump is preferred over a patch version bump to maintain the ability to provide patches for the previous minor version.

References
  1. When a release introduces breaking changes in environment requirements, such as dropping support for specific Python versions or major dependency versions (e.g., protobuf), prefer a minor version bump over a patch version bump.

Comment on lines +154 to 157
delete_sql = "%s %s %%s WHERE true" % (
style.SQL_KEYWORD("DELETE"),
style.SQL_KEYWORD("FROM"),
)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The DELETE statement in Spanner requires a WHERE clause. While adding WHERE true works, it might be slightly more idiomatic and potentially clearer to use a condition that is always true but references a column, like WHERE 1=1. However, WHERE true is valid. A minor point for consideration.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant