Skip to content

fix(django-google-spanner): fix column check constraint DDL - #19070

Open
olavloite wants to merge 2 commits into
mainfrom
spanner-django-constraint-name
Open

olavloite wants to merge 2 commits into
mainfrom
spanner-django-constraint-name

Conversation

@olavloite

Copy link
Copy Markdown
Contributor

Creating models or adding fields with column-level check constraints (such as positive integer fields) previously produced invalid Spanner SQL in several ways:

  • Constraint names interpolated the quoted field name inside an unquoted identifier, embedding backticks in the middle of the name whenever the field needed quoting, while leaving the table name unquoted.
  • Check expressions referenced the column name without quoting, breaking columns named after reserved keywords or containing special characters.
  • Adding a field with a check constraint appended the constraint inline to the ADD COLUMN statement, which Spanner does not allow.

This change fixes these issues by:

  • Generating deterministic check constraint names using Django's standard naming convention, sanitizing dots, respecting Spanner's identifier length limit, and quoting the full constraint name as a single identifier.
  • Quoting column names inside generated check constraint expressions.
  • Issuing a separate ALTER TABLE ... ADD CONSTRAINT statement when adding a field with a check constraint.
  • Adding unit tests covering reserved-keyword columns, special characters in table names, unconditional identifier quoting, custom database column names, long dotted names, column renames, and adding fields across all positive integer field types.

Creating models or adding fields with column-level check constraints (such as
positive integer fields) previously produced invalid Spanner SQL in several
ways:

- Constraint names interpolated the quoted field name inside an unquoted
  identifier, embedding backticks in the middle of the name whenever the
  field needed quoting, while leaving the table name unquoted.
- Check expressions referenced the column name without quoting, breaking
  columns named after reserved keywords or containing special characters.
- Adding a field with a check constraint appended the constraint inline to the
  ADD COLUMN statement, which Spanner does not allow.

This change fixes these issues by:
- Generating deterministic check constraint names using Django's standard
  naming convention, sanitizing dots, respecting Spanner's identifier length
  limit, and quoting the full constraint name as a single identifier.
- Quoting column names inside generated check constraint expressions.
- Issuing a separate ALTER TABLE ... ADD CONSTRAINT statement when adding a
  field with a check constraint.
- Adding unit tests covering reserved-keyword columns, special characters in
  table names, unconditional identifier quoting, custom database column names,
  long dotted names, column renames, and adding fields across all positive
  integer field types.
@olavloite
olavloite requested a review from a team as a code owner November 13, 2026 15:41

@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 updates the Django Google Spanner backend to use deterministic check constraint names and handles adding check constraints separately when adding new fields, as Spanner does not support inline constraints during column additions. It also adds comprehensive unit tests for these changes. The reviewer feedback points out that Cloud Spanner does not allow renaming columns referenced by check constraints. To prevent database errors, the reviewer suggests overriding _rename_field to drop the old check constraint before renaming and recreate it afterward, and updating the corresponding test to assert this drop-and-recreate behavior.

@olavloite

Copy link
Copy Markdown
Contributor Author

The build failures should be auto-fixed once #19069 has been merged and this PR has been rebased.

This branch has not been deployed

No deployments
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