Bridge to enable using Django with Spanner.
Project description
ORM plugin for using Cloud Spanner as a database backend for Django.
Installation
To use this library you’ll need a Google Cloud Platform project with the Cloud Spanner API enabled. See the Cloud Spanner Python client docs for details.
Use the version of python-spanner-django that corresponds to your version of Django. For example, python-spanner-django 2.2.x works with Django 2.2.y. (This is the only supported version at this time.)
The minor release number of Django doesn’t correspond to the minor release number of python-spanner-django. Use the latest minor release of each.
To install from PyPI:
pip3 install django-google-spanner
To install from source:
git clone git@github.com:googleapis/python-spanner-django.git
cd python-spanner-django
pip3 install -e .
Useage
After installattion, you’ll need to edit your Django settings.py file:
Add django_spanner as the very first entry in the INSTALLED_APPS setting
INSTALLED_APPS = [ 'spanner_django', ... ]
Edit the DATABASES setting to point to an EXISTING database
Format
DATABASES = {
'default': {
'ENGINE': 'spanner_django',
'PROJECT': '<project_id>',
'INSTANCE': '<instance_id>',
'NAME': '<database_name>',
# Only include this if you need to specify where to retrieve the
# service account JSON for the credentials to connect to Cloud Spanner.
'OPTIONS': {
'credentials_uri': '<credentials_uri>',
},
},
}
Example
For example:
DATABASES = {
'default': {
'ENGINE': 'spanner_django',
'PROJECT': 'appdev-soda-spanner-staging', # Or the GCP project-id
'INSTANCE': 'django-dev1', # Or the Cloud Spanner instance
'NAME': 'db1', # Or the Cloud Spanner database to use
}
}
Limitations
Transaction management isn’t supported
python-spanner-django always works in autocommit mode, which is Django’s default behavior even for backends that support manual transaction management. Transactions cannot be controlled manually with calls like django.db.transaction.atomic().
AutoField generates random IDs
Spanner doesn’t have support for auto-generating primary key values. Therefore, python-spanner-django monkey-patches AutoField to generate a random UUID4. It generates a default using Field’s default option which means AutoFields will have a value when a model instance is created. For example:
>>> ExampleModel() >>> ExampleModel.pk 4229421414948291880
To avoid hotspotting, 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
Spanner doesn’t support ON DELETE CASCADE when creating foreign-key constraints so python-spanner-django doesn’t support foreign key constraints.
Check constraints aren’t supported
Spanner doesn’t support CHECK constraints so one isn’t created for PositiveIntegerField and CheckConstraint can’t be used.
DecimalField isn’t supported
Spanner doesn’t support a NUMERIC data type that allows storing high precision decimal values without the possibility of data loss.
Variance and StdDev database functions aren’t supported
Spanner doesn’t support these functions.
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 doesn’t support it. For example:
>>> ExampleModel.objects.order_by('?') ... django.db.utils.ProgrammingError: 400 Function not found: RANDOM ... FROM example_model ORDER BY RANDOM() ASC
Schema migrations
Spanner has some limitations on schema changes which you must respect:
Renaming tables and columns isn’t supported.
A column’s type can’t be changed.
A table’s primary key can’t be altered.
Migrations aren’t atomic since python-spanner-django doesn’t support transactions.
DurationField arithmetic doesn’t work with DateField values (#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 doesn’t provide a way to determine which database function to use. DatabaseOperations.combine_duration_expression() arbitrary uses TIMESTAMP_ADD and TIMESTAMP_SUB. Therefore, if you use a DateField in a DurationField expression, you’ll see an error like: “No matching signature for function TIMESTAMP_ADD for argument types: DATE, INTERVAL INT64 DATE_TIME_PART.”
Computations that yield FLOAT64 values can’t be assigned to INT64 columns
Spanner doesn’t support this.
For example, if integer is IntegerField:
>>> 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
For example:
>>> Book.objects.annotate(adjusted_rating=F('rating') + None) ... google.api_core.exceptions.InvalidArgument: 400 Operands of + cannot be literal NULL ...
How it works
Overall design
Internals
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file django-google-spanner-2.2.0a1.tar.gz
.
File metadata
- Download URL: django-google-spanner-2.2.0a1.tar.gz
- Upload date:
- Size: 60.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/50.3.0 requests-toolbelt/0.9.1 tqdm/4.49.0 CPython/3.8.2
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | f0baf27f2463a9c21739e0aa5831f48029fe61212884662e319099a530dedc46 |
|
MD5 | 600faed15602d05fd322141cb57c040f |
|
BLAKE2b-256 | d26877bf51b365bebbc40e66ca9abcb2e3c905318a19bbaf6c59218fb486f210 |
Provenance
File details
Details for the file django_google_spanner-2.2.0a1-py3-none-any.whl
.
File metadata
- Download URL: django_google_spanner-2.2.0a1-py3-none-any.whl
- Upload date:
- Size: 74.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.24.0 setuptools/50.3.0 requests-toolbelt/0.9.1 tqdm/4.49.0 CPython/3.8.2
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 93af93b356a38f93776bd0b653e1821774bf1498aa6bcc7b994552c7c736f457 |
|
MD5 | 4d7e43497bb3e580e5f9600c24e15158 |
|
BLAKE2b-256 | 12f9904afb7e9e0f5ada1f83bdca549018c417c68f9e26ff27ad15d9c7734c89 |