Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
04a7745
performance files
asthamohta Jun 29, 2021
7a99ca1
test_benchmark
asthamohta Jul 5, 2021
79d94f7
performance testing changes
asthamohta Jul 7, 2021
aad550c
changes in benchmark performance for prod
asthamohta Jul 7, 2021
cd8d080
Merge branch 'googleapis:master' into performance
asthamohta Jul 7, 2021
ba0faee
changes to number of runs
asthamohta Jul 7, 2021
974f690
Merge branch 'performance' of github.com:asthamohta/python-spanner-dj…
asthamohta Jul 7, 2021
155aa13
adding comments
asthamohta Jul 7, 2021
25f9a75
linting changes
asthamohta Jul 7, 2021
8cdd431
Merge branch 'googleapis:master' into stable/3.2.x
asthamohta Jul 21, 2021
bd2ae62
3.2 changes
asthamohta Jul 21, 2021
2ebb7a9
Merge branch 'stable/3.2.x' of github.com:asthamohta/python-spanner-d…
asthamohta Jul 21, 2021
9a81474
adding version change
asthamohta Jul 21, 2021
069fcc4
lint changes and resmoving performance changes
asthamohta Jul 21, 2021
853526e
version changes
asthamohta Jul 21, 2021
11bc9c2
chore: fix release build (#659)
busunkim96 Jul 22, 2021
42352c0
feat: Added support for check constraint (#679)
vi3k6i5 Jul 23, 2021
74f2269
docs: update docs to show decimal field support and check constraints…
vi3k6i5 Jul 26, 2021
f3e8fc2
test: Performance Testing (#675)
asthamohta Jul 27, 2021
96a809d
chore: release 2.2.1b2 (#685)
vi3k6i5 Jul 27, 2021
f5bf523
chore: release 2.2.1b2 (#687)
release-please[bot] Jul 28, 2021
5f9750e
fix: Bump version number after 2.2.1b2 release (#688)
vi3k6i5 Jul 29, 2021
2144d09
chor: Update repo to say beta release instead of alpha (#691)
vi3k6i5 Jul 30, 2021
e1caf28
chore: release 2.2.1b3 (#693)
vi3k6i5 Jul 30, 2021
c86dd26
chore: release 2.2.1b3 (#694)
release-please[bot] Jul 30, 2021
a8f2aac
fix: Bump version number after 2.2.1b3 release (#696)
vi3k6i5 Aug 3, 2021
ed404f5
docs: lint fix for samples (#697)
vi3k6i5 Aug 6, 2021
08b80ce
Docs: fix changelog link and sample examples. (#700)
vi3k6i5 Aug 19, 2021
4643876
docs: update dbapi location in overview asset file (#702)
vi3k6i5 Aug 21, 2021
9d9d360
chore: migrate to main branch (#706)
dandhlee Sep 2, 2021
578f5bc
fix: added fixes for latest feature changes in django 3.2
vi3k6i5 Sep 13, 2021
c9c1019
fix: fixes for running tests for django3.2
vi3k6i5 Sep 16, 2021
393fe0d
Merge branch 'main' of github.com:googleapis/python-spanner-django in…
vi3k6i5 Sep 16, 2021
012fc99
Merge branch 'stable/3.2.x' of github.com:googleapis/python-spanner-d…
vi3k6i5 Sep 16, 2021
a2ae17a
fix: change django repo path
vi3k6i5 Sep 16, 2021
97c7ea0
test: test fixes for order by nulls first and last
vi3k6i5 Sep 17, 2021
d5b567c
docs: fix readme link target
vi3k6i5 Sep 17, 2021
22c4131
test: set default auto field type in test settings
vi3k6i5 Sep 20, 2021
69c3c08
fix: update features to skip tests that are not support by spanner
vi3k6i5 Sep 20, 2021
9d53a06
fix: remove choices module from django3.2 as it has been removed from…
vi3k6i5 Sep 20, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/django_tests_against_emulator0.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,4 @@ jobs:
GOOGLE_CLOUD_TESTS_CREATE_SPANNER_INSTANCE: true
RUNNING_SPANNER_BACKEND_TESTS: 1
SPANNER_TEST_INSTANCE: google-cloud-django-backend-tests
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
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
117 changes: 5 additions & 112 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -253,118 +253,11 @@ Please note that this project is released with a Contributor Code of Conduct.
By participating in this project you agree to abide by its terms. See the `Code
of Conduct <https://github.com/googleapis/python-spanner-django/blob/main/CODE_OF_CONDUCT.md>`_ for more information.

Current limitations
-------------------

``AutoField`` generates random IDs
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Spanner doesn't have support for auto-generating primary key values.
Therefore, ``django-google-spanner`` monkey-patches ``AutoField`` to generate a
random UUID4. It generates a default using ``Field``'s ``default`` option which
means ``AutoField``\ s will have a value when a model instance is created. For
example:

::

>>> ExampleModel()
>>> ExampleModel.pk
4229421414948291880

To avoid
`hotspotting <https://cloud.google.com/spanner/docs/schema-design#uuid_primary_key>`__,
these IDs are not monotonically increasing. This means that sorting
models by ID isn't guaranteed to return them in the order in which they
were created.

``ForeignKey`` constraints aren't created (`#313 <https://github.com/googleapis/python-spanner-django/issues/313>`__)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Spanner does not support ``ON DELETE CASCADE`` when creating foreign-key
constraints, so this is not supported in ``django-google-spanner``.

``Unsigned`` datatypes are not supported
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Spanner does not support ``Unsigned`` datatypes so `PositiveIntegerField
<https://docs.djangoproject.com/en/stable/ref/models/fields/#positiveintegerfield>`__
and `PositiveSmallIntegerField
<https://docs.djangoproject.com/en/3.2/ref/models/fields/#positivesmallintegerfield>`__
are both stored as `Integer type
<https://cloud.google.com/spanner/docs/data-types#integer_type>`__
.

``Meta.order_with_respect_to`` model option isn't supported
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

This feature uses a column name that starts with an underscore
(``_order``) which Spanner doesn't allow.

Random ``QuerySet`` ordering isn't supported
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Spanner does not support it and will throw an exception. For example:

::

>>> ExampleModel.objects.order_by('?')
...
django.db.utils.ProgrammingError: 400 Function not found: RANDOM ... FROM
example_model ORDER BY RANDOM() ASC

Schema migrations
~~~~~~~~~~~~~~~~~

There are some limitations on schema changes to consider:

- No support for renaming tables and columns;
- A column's type can't be changed;
- A table's primary key can't be altered.

``DurationField`` arithmetic doesn't work with ``DateField`` values (`#253 <https://github.com/googleapis/python-spanner-django/issues/253>`__)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Spanner requires using different functions for arithmetic depending on
the column type:

- ``TIMESTAMP`` columns (``DateTimeField``) require ``TIMESTAMP_ADD``
or ``TIMESTAMP_SUB``
- ``DATE`` columns (``DateField``) require ``DATE_ADD`` or ``DATE_SUB``

Django does not provide ways to determine which database function to
use. ``DatabaseOperations.combine_duration_expression()`` arbitrarily uses
``TIMESTAMP_ADD`` and ``TIMESTAMP_SUB``. Therefore, if you use a
``DateField`` in a ``DurationField`` expression, you'll likely see an error
such as:

::

"No matching signature for function TIMESTAMP\_ADD for argument types:
DATE, INTERVAL INT64 DATE\_TIME\_PART."

Computations that yield FLOAT64 values cannot be assigned to INT64 columns
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Spanner does not support this (`#331
<https://github.com/googleapis/python-spanner-django/issues/331>`__) and will
throw an error:

::

>>> ExampleModel.objects.update(integer=F('integer') / 2)
...
django.db.utils.ProgrammingError: 400 Value of type FLOAT64 cannot be
assigned to integer, which has type INT64 [at 1:46]\nUPDATE
example_model SET integer = (example_model.integer /...

Addition with null values crash
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Additions cannot include ``None`` values. For example:
LIMITATIONS
-----------------

::
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>`_
It is recommended that you go through that list.

>>> Book.objects.annotate(adjusted_rating=F('rating') + None)
...
google.api_core.exceptions.InvalidArgument: 400 Operands of + cannot be literal
NULL ...
Django spanner has a set of limitations as well, please go through the `list <https://googleapis.dev/python/django-google-spanner/latest/limitations.html>`_.
15 changes: 14 additions & 1 deletion django_spanner/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@
from uuid import uuid4

import pkg_resources
from django.db.models.fields import AutoField, Field
from django.db.models.fields import (
AutoField,
SmallAutoField,
BigAutoField,
Field,
)

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


AutoField.__init__ = autofield_init
SmallAutoField.__init__ = autofield_init
BigAutoField.__init__ = autofield_init
AutoField.db_returning = False
SmallAutoField.db_returning = False
BigAutoField.db_returning = False
AutoField.validators = []
SmallAutoField.validators = []
BigAutoField.validators = []

old_datetimewithnanoseconds_eq = getattr(
DatetimeWithNanoseconds, "__eq__", None
Expand Down
7 changes: 7 additions & 0 deletions django_spanner/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class DatabaseWrapper(BaseDatabaseWrapper):
"GenericIPAddressField": "STRING(39)",
"NullBooleanField": "BOOL",
"OneToOneField": "INT64",
"PositiveBigIntegerField": "INT64",
"PositiveIntegerField": "INT64",
"PositiveSmallIntegerField": "INT64",
"SlugField": "STRING(%(max_length)s)",
Expand Down Expand Up @@ -96,6 +97,12 @@ class DatabaseWrapper(BaseDatabaseWrapper):
"iendswith": "",
}

data_type_check_constraints = {
"PositiveBigIntegerField": "%(column)s >= 0",
"PositiveIntegerField": "%(column)s >= 0",
"PositiveSmallIntegerField": "%(column)s >= 0",
}

Database = spanner_dbapi
SchemaEditorClass = DatabaseSchemaEditor
creation_class = DatabaseCreation
Expand Down
Loading