Skip to content

feat(django-google-spanner): support Django 6.0 - #18128

Draft
sakthivelmanii wants to merge 1 commit into
mainfrom
add-django-6.0-support
Draft

feat(django-google-spanner): support Django 6.0#18128
sakthivelmanii wants to merge 1 commit into
mainfrom
add-django-6.0-support

Conversation

@sakthivelmanii

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> 🦕

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

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.

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.

Comment on lines +763 to +766
def compile_json_path(self, key_transforms, fallback_to_null=False):
# Spanner specific JSON path formatting
path = "['%s']" % "']['".join(key_transforms)
return path

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 current implementation of compile_json_path has several critical issues:

  1. Missing $ Prefix: Spanner's JSON path syntax requires the path to start with a $ character (e.g., $.path or $["path"]). Without it, Spanner will raise an Invalid JSON path error at runtime.
  2. SQL Injection / Syntax Errors: Single quotes in key_transforms are not escaped, which can lead to SQL syntax errors or potential SQL injection vulnerabilities.
  3. TypeError on Integer Keys: If key_transforms contains integer indices (for array lookups), "']['".join(key_transforms) will raise a TypeError because join expects strings.

Using json.dumps (similar to Django's default implementation) solves all of these issues robustly by correctly prepending $, escaping special characters, and handling both string keys and integer indices.

Suggested change
def compile_json_path(self, key_transforms, fallback_to_null=False):
# Spanner specific JSON path formatting
path = "['%s']" % "']['".join(key_transforms)
return path
def compile_json_path(self, key_transforms, fallback_to_null=False):
import json
return "$" + "".join(f"[{json.dumps(key)}]" for key in key_transforms)

Comment on lines +220 to +221
async def _a_set_autocommit(self, autocommit):
return await sync_to_async(self._set_autocommit)(autocommit)

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

In Django, database operations executed asynchronously should be wrapped in self.execute_wrapper to ensure that any custom connection wrappers, instrumentation, or middleware hooks are correctly executed. Wrapping the call in async with self.execute_wrapper: aligns with Django's standard implementation of _a_set_autocommit.

Suggested change
async def _a_set_autocommit(self, autocommit):
return await sync_to_async(self._set_autocommit)(autocommit)
async def _a_set_autocommit(self, autocommit):
async with self.execute_wrapper:
return await sync_to_async(self._set_autocommit)(autocommit)

Comment on lines +1 to +7
#!/bin/sh

# Copyright (c) 2020 Google LLC. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.

set -x pipefail

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

There are two issues with the shell configuration here:

  1. set -x pipefail is invalid shell syntax. To enable the pipefail option, you must use set -o pipefail.
  2. The pipefail option is a bash/zsh extension and is not supported by POSIX-compliant /bin/sh (such as dash on Debian/Ubuntu). To guarantee support, the shebang should be changed to #!/bin/bash.
  3. It is highly recommended to enable set -e (errexit) so that the script exits immediately if any setup command (like pip3 install or git clone) fails, preventing silent failures in CI.
Suggested change
#!/bin/sh
# Copyright (c) 2020 Google LLC. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.
set -x pipefail
#!/bin/bash
# Copyright (c) 2020 Google LLC. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.
set -xe
set -o pipefail

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