Bridge to enable using Django with Spanner.
Project description
Cloud Spanner is the world’s first fully managed relational database service to offer both strong consistency and horizontal scalability for mission-critical online transaction processing (OLTP) applications. With Cloud Spanner you enjoy all the traditional benefits of a relational database; but unlike any other relational database service, Cloud Spanner scales horizontally to hundreds or thousands of servers to handle the biggest transactional workloads.
Quick Start
In order to use this library, you first need to go through the following steps:
This package provides a 3rd-party database backend for using Cloud Spanner with the Django ORM. It uses the Cloud Spanner Python client library under the hood.
Installation
Install this library in a virtualenv using pip. virtualenv is a tool to create isolated Python and Django environments. The basic problem it addresses is one of dependencies and versions, and indirectly permissions.
With virtualenv, it’s possible to install this library without needing system install permissions, and without clashing with the installed system dependencies.
Mac/Linux
pip install virtualenv
virtualenv <your-env>
source <your-env>/bin/activate
<your-env>/bin/pip install python-spanner-django
<your-env>/bin/pip install google-cloud-spanner
Windows
pip install virtualenv
virtualenv <your-env>
<your-env>\Scripts\activate
<your-env>\Scripts\pip.exe install python-spanner-django
<your-env>\Scripts\pip.exe install google-cloud-spanner
Supported versions
At the moment, this library only supports Django 2.2. It also requires Python version 3.6 or later.
This package follows a common versioning convention for Django plugins: the major and minor version components of this package should match the installed version of Django. That is, django-google-spanner~=2.2 works with Django~=2.2.
Installing the package
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 .
Creating a Cloud Spanner instance and database
If you don’t already have a Cloud Spanner database, or want to start from scratch for a new Django application, you can create a new instance and database using the Google Cloud SDK:
gcloud spanner instances create $INSTANCE --config=regional-us-central1 --description="New Django Instance" --nodes=1
gcloud spanner databases create $DB --instance $INSTANCE
Configuring settings.py
This package provides a Django application named django_spanner. To use the Cloud Spanner database backend, the application needs to installed and configured:
Add django_spanner as the first entry in INSTALLED_APPS:
INSTALLED_APPS = [ 'django_spanner', ... ]
Edit the DATABASES setting to point to an existing Cloud Spanner database:
DATABASES = { 'default': { 'ENGINE': 'django_spanner', 'PROJECT': '$PROJECT', 'INSTANCE': '$INSTANCE', 'NAME': '$DATABASE', } }
Set credentials and project environment variables
You’ll need to download a service account JSON key file and point to it using an environment variable:
export GOOGLE_APPLICATION_CREDENTIALS=/path/to/keyfile.json
export GOOGLE_CLOUD_PROJECT=gcloud_project
Apply the migrations
Please run:
$ python3 manage.py migrate
and that’ll take a while to run. After this you should be able to see the tables and indices created in your Cloud Spanner console.
Now run your server
After those migrations are completed, that will be all. Please continue on with the guides.
Create an Django admin user
First you’ll need to create a user who can login to the admin site. Run the following command:
$ python3 manage.py createsuperuser
which will then produce a prompt which will allow you to create your super user
Username: admin
Email address: admin@example.com
Password: **********
Password (again): **********
Superuser created successfully.
Login as admin
Let’s run the server
python3 manage.py runserver
Then visit http://127.0.0.1:8000/admin/
Create and register your first model
Please follow the guides in https://docs.djangoproject.com/en/2.2/intro/tutorial02/#creating-models to create and register the model to the Django’s automatically-generated admin site.
How it works
Overall design
Internals
Executing a query
Here is an example of how to add a row for Model Author, save it and later query it using Django
>>> author_kent = Author( first_name="Arthur", last_name="Kent", rating=Decimal("4.1"),)
>>> author_kent.save()
>>> qs1 = Author.objects.all().values("first_name", "last_name")
HOW TO CONTRIBUTE
Contributions to this library are always welcome and highly encouraged.
See CONTRIBUTING for more information on how to get started.
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 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 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 (#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 and PositiveSmallIntegerField are both stored as 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)
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) 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:
>>> Book.objects.annotate(adjusted_rating=F('rating') + None) ... google.api_core.exceptions.InvalidArgument: 400 Operands of + cannot be literal NULL ...
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.1b3.tar.gz
.
File metadata
- Download URL: django-google-spanner-2.2.1b3.tar.gz
- Upload date:
- Size: 64.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.4.2 importlib_metadata/4.6.1 pkginfo/1.7.1 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.61.2 CPython/3.9.0
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 5355f3775cfab9481b5129432031140698542a2a1050696188f27d4780d2a887 |
|
MD5 | 2d39117c0808b3564add16a6ccea975b |
|
BLAKE2b-256 | 59936c72624c3725f903c4bdd3482142f7593a0f562c7aba28c823655a5f515b |
Provenance
File details
Details for the file django_google_spanner-2.2.1b3-py3-none-any.whl
.
File metadata
- Download URL: django_google_spanner-2.2.1b3-py3-none-any.whl
- Upload date:
- Size: 80.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.4.2 importlib_metadata/4.6.1 pkginfo/1.7.1 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.61.2 CPython/3.9.0
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 6c71a460c6f3c916003f23191b4f4c2df6e3954556be6f7fa76bdfa5cf9dd7af |
|
MD5 | 20bc395427796d10f412ba2bd277e3ce |
|
BLAKE2b-256 | 58f49745946793477330e1b46a1c1805453993073c7eb0479eb688bb1f1a64d0 |