feat(django-google-spanner): support Django 6.0 - #18128
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces support for Django 6.0, including dependency updates, tuple-casting for lookup parameters, an asynchronous autocommit setter, and a Spanner-specific JSON path compiler. The review feedback highlights critical improvements: resolving syntax, type, and SQL injection issues in compile_json_path by utilizing json.dumps; wrapping the async autocommit operation in self.execute_wrapper to align with Django standards; and fixing invalid shell syntax and compatibility issues in the new test suite script.
311d5d1 to
cfa5943
Compare
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces support for Django 6.0 in the django-google-spanner package. Key changes include updating supported versions and dependencies, implementing async autocommit handling, adding Django 6.0 test exclusions, and updating database features, operations, and schema editors to support index inclusion columns and returning columns from inserts. Feedback on these changes highlights two important issues: first, the _index_include_sql helper in schema.py should resolve actual database column names via model._meta.get_field(field).column rather than using str(field) directly; second, the async autocommit wrapper in base.py should use thread_sensitive=True with sync_to_async to ensure thread safety and prevent connection sharing issues.
cfa5943 to
b219da1
Compare
…d lookups parameter indexing
| "sqlparse >= 0.3.0", | ||
| "google-cloud-spanner >= 3.13.0", | ||
| "django >= 5.2, < 6.0", | ||
| "google-cloud-spanner >= 3.69.1", |
There was a problem hiding this comment.
Please can you clarify if we really need to bump google-cloud-spanner? Do tests fail with 3.13.0?
Is there a lower minimum that we can set here?
If 3.69.1 is yanked or has a regression, users may not be able to install/use the latest version of django-google-spanner
https://pypi.org/project/google-cloud-spanner/3.69.1/
There was a problem hiding this comment.
#18152 This fix is needed for can_return_columns_from_insert to work correctly. I will update this version to 3.69.2 once we have a new version released. I am planning to push this change to 3.70.0 or 3.69.3
| } | ||
|
|
||
| can_introspect_duration_field = False | ||
| can_return_columns_from_insert = True |
There was a problem hiding this comment.
We should also add this to the list to declare support for STORING:
supports_covering_indexes=True| CommitRequest, | ||
| CreateSessionRequest, | ||
| ExecuteSqlRequest, | ||
| TypeCode, |
There was a problem hiding this comment.
I don't think this test is actually used, at least not by default. The noxfile.py says this:
UNIT_TEST_DEPENDENCIES = [
"django~=5.2",
"sqlparse==0.3.1",
]
UNIT_TEST_MOCKSERVER_DEPENDENCIES = [
"django~=5.2",
"google-cloud-spanner>=3.55.0",
"sqlparse>=0.4.4",
]So I think that we should update noxfile.py as well to also run tests with Django 6.0
| USE_EMULATOR = os.getenv("SPANNER_EMULATOR_HOST") is not None | ||
|
|
||
| SUPPORTED_DJANGO_VERSIONS = [(5, 2)] | ||
| SUPPORTED_DJANGO_VERSIONS = [(6, 0), (5, 2)] |
There was a problem hiding this comment.
We should also update the README file to document support for 6.0
There was a problem hiding this comment.
Can we also do a full search of the project to look for other outdated references to Django versions? I think there are more than only those in the README in various docstrings and comments.
| } | ||
|
|
||
| can_introspect_duration_field = False | ||
| can_return_columns_from_insert = True |
There was a problem hiding this comment.
Note that setting this:
can_return_columns_from_insert = True
Can have an impact on existing applications. Django will now start generating THEN RETURN clauses for (some) insert statements. That means that:
- Those statements are not compatible with
ExecuteBatchDml(meaning:execute_manyin dbapi) - If anyone somehow manages to use this new Django provider with an older Spanner dbapi driver version that does not contain the fix for THEN RETURN in auto-commit, could suddenly see errors.
Considering the fact that we require the newest version of the dbapi driver for this Django provider, I think that this should be acceptable, but we should document this in the release notes.
There was a problem hiding this comment.
Not really part of this change, but it came up during the review: We should make this user_agent string dynamic like this:
f"django_spanner/{__version__}"| "VALUES (@a0, @a1, @a2)", | ||
| 1, | ||
| "VALUES (@a0, @a1, @a2) " | ||
| "THEN RETURN id", |
There was a problem hiding this comment.
I am starting to worry / think / wonder whether this is desired behavior for existing customers. Anyone currently using this provider with Django 5.2 will (by default) not get any DML statements that include THEN RETURN clauses. All of a sudden changing that default is a bit worrisome, because:
- It does not support ExecuteBatchDml (but it is highly unlikely that anyone is using that with generated SQL statements from Django, so not really an argument)
- It does not work with earlier versions of the dbapi driver when using AutoCommit=True.
- It changes the behavior for all GeneratedFields and db_default fields. These are now automatically updated when
save()is called. And while that in general is an improvement, it is also a behavior change for an existing application. If an application (implicitly) relied on a field with a default/generated value to remain unchanged after asave()operation, then that could fail now.
So I think that based on the above, the risk is low, but not zero, that it could affect existing applications. I think that we therefore should document this properly, and maybe also add an example for how an application can return to the previous behavior, for example like this:
from django.apps import AppConfig
class MyAppConfig(AppConfig):
name = 'myapp'
def ready(self):
from django_spanner.features import DatabaseFeatures
DatabaseFeatures.can_return_columns_from_insert = False…nd docs for Django 6.0
Description
This PR adds support for Django 6.0 in
django-google-spannerwhile maintaining full backwards compatibility with Django 5.2.Fixes #18053
Key Changes
STORING): Added support forincludeclauses in index creation, generating Cloud Spanner GoogleSQLSTORING (col1, col2)DDL; declaredsupports_covering_indexes = True.supports_composite_primary_keys = True).can_return_columns_from_insert = Trueand updatedreturning_columns()inoperations.pyto safely handle column names and expression objects, allowing Django to automatically populate database defaults andGeneratedFieldvalues onINSERT ... THEN RETURN.Behavioral Notes for Users
THEN RETURN: Withcan_return_columns_from_insert = True, Django will now generateTHEN RETURNclauses for models with database-generated defaults orGeneratedFieldcolumns upon.save(). Applications wishing to preserve legacy behavior can opt out viaAppConfig: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 #18053 🦕