Skip to content
This repository was archived by the owner on Mar 20, 2026. It is now read-only.

Commit b163ed2

Browse files
vi3k6i5asthamohtabusunkim96gcf-owl-bot[bot]release-please[bot]
authored
fix!: update Stable/3.2.x to work with django 3.2 tests (#710)
* performance files * test_benchmark * performance testing changes * changes in benchmark performance for prod * changes to number of runs * adding comments * linting changes * 3.2 changes * adding version change * lint changes and resmoving performance changes * version changes * chore: fix release build (#659) * chore: fix release build Fix release build by migrating to secret manager secrets and use templated kokoro configs for docs/ and release/ * fix: fix config names * chore: add populate secrets script * docs: fix license * chore: preserve original year * chore: revert years in manually committed files * 🦉 Updates from OwlBot See https://github.com/googleapis/repo-automation-bots/blob/master/packages/owl-bot/README.md * chore: update lockfile * chore: add .kokoro/docker directory Co-authored-by: Owl Bot <gcf-owl-bot[bot]@users.noreply.github.com> * feat: Added support for check constraint (#679) * feat: Added support for check constraint * fix: change decimal out of scale ProgramingError to ValueError * fix: skip check_constraints tests when running on emmulator * fix: remove check constraint for emulator * docs: update docs to show decimal field support and check constraints but no support for unsigned data type (#683) * test: Performance Testing (#675) * performance files * test_benchmark * performance testing changes * changes in benchmark performance for prod * changes to number of runs * adding comments * linting changes * changes for 3.2 * Revert "changes for 3.2" This reverts commit 488035c. * adding licence * chore: release 2.2.1b2 (#685) Release-As: 2.2.1b2 * chore: release 2.2.1b2 (#687) * chore: release 2.2.1b2 * Updated CHANGELOG.md Corrected the change log msg. Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> Co-authored-by: Vikash Singh <3116482+vi3k6i5@users.noreply.github.com> * fix: Bump version number after 2.2.1b2 release (#688) * chor: Update repo to say beta release instead of alpha (#691) * fix: Bump version number after 2.2.1b2 release * Update setup.py Current release is beta so updating the same in setup.py * chore: release 2.2.1b3 (#693) Release-As: 2.2.1b3 * chore: release 2.2.1b3 (#694) * chore: release 2.2.1b3 * Updated CHANGELOG.md Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> Co-authored-by: Vikash Singh <3116482+vi3k6i5@users.noreply.github.com> * fix: Bump version number after 2.2.1b3 release (#696) * chore: release 2.2.1b3 Release-As: 2.2.1b3 * fix: Bump version number after 2.2.1b3 release * fix: add test samples script and related kokoro files * fix: correct repo name from python-spanner to python-spanner-django * fix: correct license from Apache to BSD style * docs: lint fix for samples (#697) * Docs: fix changelog link and sample examples. (#700) * docs: update docs to show decimal field support and check constraints but no support for unsigned data type * docs: linked changelog correctly * docs: fix doc links for sample examples * fix: skip test cursor_executemany_with_empty_params_list as spanner support is not there * docs: update dbapi location in overview asset file (#702) * chore: migrate to main branch (#706) * chore: migrate to main branch * 🦉 Updates from OwlBot See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * use latest post processor image * remove obsolete replacements in owlbot.py * update post processor image Co-authored-by: Owl Bot <gcf-owl-bot[bot]@users.noreply.github.com> Co-authored-by: Anthonios Partheniou <partheniou@google.com> * fix: added fixes for latest feature changes in django 3.2 * fix: fixes for running tests for django3.2 * fix: change django repo path * test: test fixes for order by nulls first and last * docs: fix readme link target * test: set default auto field type in test settings * fix: update features to skip tests that are not support by spanner * fix: remove choices module from django3.2 as it has been removed from django 3.2 Co-authored-by: Astha Mohta <asthamohta@gmail.com> Co-authored-by: Astha Mohta <35952883+asthamohta@users.noreply.github.com> Co-authored-by: Bu Sun Kim <8822365+busunkim96@users.noreply.github.com> Co-authored-by: Owl Bot <gcf-owl-bot[bot]@users.noreply.github.com> Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> Co-authored-by: Dan Lee <71398022+dandhlee@users.noreply.github.com> Co-authored-by: Anthonios Partheniou <partheniou@google.com>
1 parent 736a84a commit b163ed2

19 files changed

Lines changed: 531 additions & 204 deletions

.github/workflows/django_tests_against_emulator0.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,4 @@ jobs:
2929
GOOGLE_CLOUD_TESTS_CREATE_SPANNER_INSTANCE: true
3030
RUNNING_SPANNER_BACKEND_TESTS: 1
3131
SPANNER_TEST_INSTANCE: google-cloud-django-backend-tests
32-
DJANGO_TEST_APPS: admin_changelist admin_ordering aggregation choices distinct_on_fields expressions_window fixtures_model_package datetimes custom_methods generic_inline_admin field_defaults datatypes empty m2o_recursive many_to_one_null migration_test_data_persistence admin_docs invalid_models_tests migrate_signals model_forms.test_uuid model_forms.test_modelchoicefield syndication_tests view_tests update test_utils select_related_onetoone sessions_tests
32+
DJANGO_TEST_APPS: admin_changelist admin_ordering aggregation distinct_on_fields expressions_window fixtures_model_package datetimes custom_methods generic_inline_admin field_defaults datatypes empty m2o_recursive many_to_one_null migration_test_data_persistence admin_docs invalid_models_tests migrate_signals model_forms.test_uuid model_forms.test_modelchoicefield syndication_tests view_tests update test_utils select_related_onetoone sessions_tests

README.rst

Lines changed: 5 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -253,118 +253,11 @@ Please note that this project is released with a Contributor Code of Conduct.
253253
By participating in this project you agree to abide by its terms. See the `Code
254254
of Conduct <https://github.com/googleapis/python-spanner-django/blob/main/CODE_OF_CONDUCT.md>`_ for more information.
255255

256-
Current limitations
257-
-------------------
258256

259-
``AutoField`` generates random IDs
260-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
261-
262-
Spanner doesn't have support for auto-generating primary key values.
263-
Therefore, ``django-google-spanner`` monkey-patches ``AutoField`` to generate a
264-
random UUID4. It generates a default using ``Field``'s ``default`` option which
265-
means ``AutoField``\ s will have a value when a model instance is created. For
266-
example:
267-
268-
::
269-
270-
>>> ExampleModel()
271-
>>> ExampleModel.pk
272-
4229421414948291880
273-
274-
To avoid
275-
`hotspotting <https://cloud.google.com/spanner/docs/schema-design#uuid_primary_key>`__,
276-
these IDs are not monotonically increasing. This means that sorting
277-
models by ID isn't guaranteed to return them in the order in which they
278-
were created.
279-
280-
``ForeignKey`` constraints aren't created (`#313 <https://github.com/googleapis/python-spanner-django/issues/313>`__)
281-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
282-
283-
Spanner does not support ``ON DELETE CASCADE`` when creating foreign-key
284-
constraints, so this is not supported in ``django-google-spanner``.
285-
286-
``Unsigned`` datatypes are not supported
287-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
288-
289-
Spanner does not support ``Unsigned`` datatypes so `PositiveIntegerField
290-
<https://docs.djangoproject.com/en/stable/ref/models/fields/#positiveintegerfield>`__
291-
and `PositiveSmallIntegerField
292-
<https://docs.djangoproject.com/en/3.2/ref/models/fields/#positivesmallintegerfield>`__
293-
are both stored as `Integer type
294-
<https://cloud.google.com/spanner/docs/data-types#integer_type>`__
295-
.
296-
297-
``Meta.order_with_respect_to`` model option isn't supported
298-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
299-
300-
This feature uses a column name that starts with an underscore
301-
(``_order``) which Spanner doesn't allow.
302-
303-
Random ``QuerySet`` ordering isn't supported
304-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
305-
306-
Spanner does not support it and will throw an exception. For example:
307-
308-
::
309-
310-
>>> ExampleModel.objects.order_by('?')
311-
...
312-
django.db.utils.ProgrammingError: 400 Function not found: RANDOM ... FROM
313-
example_model ORDER BY RANDOM() ASC
314-
315-
Schema migrations
316-
~~~~~~~~~~~~~~~~~
317-
318-
There are some limitations on schema changes to consider:
319-
320-
- No support for renaming tables and columns;
321-
- A column's type can't be changed;
322-
- A table's primary key can't be altered.
323-
324-
``DurationField`` arithmetic doesn't work with ``DateField`` values (`#253 <https://github.com/googleapis/python-spanner-django/issues/253>`__)
325-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
326-
327-
Spanner requires using different functions for arithmetic depending on
328-
the column type:
329-
330-
- ``TIMESTAMP`` columns (``DateTimeField``) require ``TIMESTAMP_ADD``
331-
or ``TIMESTAMP_SUB``
332-
- ``DATE`` columns (``DateField``) require ``DATE_ADD`` or ``DATE_SUB``
333-
334-
Django does not provide ways to determine which database function to
335-
use. ``DatabaseOperations.combine_duration_expression()`` arbitrarily uses
336-
``TIMESTAMP_ADD`` and ``TIMESTAMP_SUB``. Therefore, if you use a
337-
``DateField`` in a ``DurationField`` expression, you'll likely see an error
338-
such as:
339-
340-
::
341-
342-
"No matching signature for function TIMESTAMP\_ADD for argument types:
343-
DATE, INTERVAL INT64 DATE\_TIME\_PART."
344-
345-
Computations that yield FLOAT64 values cannot be assigned to INT64 columns
346-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
347-
348-
Spanner does not support this (`#331
349-
<https://github.com/googleapis/python-spanner-django/issues/331>`__) and will
350-
throw an error:
351-
352-
::
353-
354-
>>> ExampleModel.objects.update(integer=F('integer') / 2)
355-
...
356-
django.db.utils.ProgrammingError: 400 Value of type FLOAT64 cannot be
357-
assigned to integer, which has type INT64 [at 1:46]\nUPDATE
358-
example_model SET integer = (example_model.integer /...
359-
360-
Addition with null values crash
361-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
362-
363-
Additions cannot include ``None`` values. For example:
257+
LIMITATIONS
258+
-----------------
364259

365-
::
260+
Spanner has certain limitations of it's own and a full set of limitations are documented over `here <https://cloud.google.com/spanner/quotas#schema_limits>`_
261+
It is recommended that you go through that list.
366262

367-
>>> Book.objects.annotate(adjusted_rating=F('rating') + None)
368-
...
369-
google.api_core.exceptions.InvalidArgument: 400 Operands of + cannot be literal
370-
NULL ...
263+
Django spanner has a set of limitations as well, please go through the `list <https://googleapis.dev/python/django-google-spanner/latest/limitations.html>`_.

django_spanner/__init__.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,12 @@
1212
from uuid import uuid4
1313

1414
import pkg_resources
15-
from django.db.models.fields import AutoField, Field
15+
from django.db.models.fields import (
16+
AutoField,
17+
SmallAutoField,
18+
BigAutoField,
19+
Field,
20+
)
1621

1722
# Monkey-patch google.DatetimeWithNanoseconds's __eq__ compare against
1823
# datetime.datetime.
@@ -45,6 +50,14 @@ def autofield_init(self, *args, **kwargs):
4550

4651

4752
AutoField.__init__ = autofield_init
53+
SmallAutoField.__init__ = autofield_init
54+
BigAutoField.__init__ = autofield_init
55+
AutoField.db_returning = False
56+
SmallAutoField.db_returning = False
57+
BigAutoField.db_returning = False
58+
AutoField.validators = []
59+
SmallAutoField.validators = []
60+
BigAutoField.validators = []
4861

4962
old_datetimewithnanoseconds_eq = getattr(
5063
DatetimeWithNanoseconds, "__eq__", None

django_spanner/base.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ class DatabaseWrapper(BaseDatabaseWrapper):
4545
"GenericIPAddressField": "STRING(39)",
4646
"NullBooleanField": "BOOL",
4747
"OneToOneField": "INT64",
48+
"PositiveBigIntegerField": "INT64",
4849
"PositiveIntegerField": "INT64",
4950
"PositiveSmallIntegerField": "INT64",
5051
"SlugField": "STRING(%(max_length)s)",
@@ -96,6 +97,12 @@ class DatabaseWrapper(BaseDatabaseWrapper):
9697
"iendswith": "",
9798
}
9899

100+
data_type_check_constraints = {
101+
"PositiveBigIntegerField": "%(column)s >= 0",
102+
"PositiveIntegerField": "%(column)s >= 0",
103+
"PositiveSmallIntegerField": "%(column)s >= 0",
104+
}
105+
99106
Database = spanner_dbapi
100107
SchemaEditorClass = DatabaseSchemaEditor
101108
creation_class = DatabaseCreation

0 commit comments

Comments
 (0)