From d55c93e1dbc867e85d848d8bb23bf896e8689719 Mon Sep 17 00:00:00 2001 From: Jon Skeet Date: Tue, 21 Apr 2026 11:31:20 +0000 Subject: [PATCH] chore: complete migration of django-google-spanner to librarian The README.rst change is just using a full copy of the parent README.rst instead of an include. (That is then consistent with all other packages.) --- librarian.yaml | 1 - .../django-google-spanner/.repo-metadata.json | 17 +- .../django-google-spanner/docs/README.rst | 289 +++++++++++++++++- 3 files changed, 296 insertions(+), 11 deletions(-) diff --git a/librarian.yaml b/librarian.yaml index 65e375c3dce5..7f710ea77578 100644 --- a/librarian.yaml +++ b/librarian.yaml @@ -83,7 +83,6 @@ libraries: client_documentation_override: https://googleapis.dev/python/db-dtypes/latest/index.html - name: django-google-spanner version: 4.0.3 - skip_generate: true python: library_type: INTEGRATION name_pretty_override: Cloud Spanner Django diff --git a/packages/django-google-spanner/.repo-metadata.json b/packages/django-google-spanner/.repo-metadata.json index 22866389b5fa..9a8193e69015 100644 --- a/packages/django-google-spanner/.repo-metadata.json +++ b/packages/django-google-spanner/.repo-metadata.json @@ -1,14 +1,13 @@ { - "name": "django-google-spanner", - "name_pretty": "Cloud Spanner Django", - "product_documentation": "https://cloud.google.com/spanner/docs/", + "api_shortname": "django-google-spanner", "client_documentation": "https://googleapis.dev/python/django-google-spanner/latest", + "distribution_name": "django-google-spanner", "issue_tracker": "https://issuetracker.google.com/issues?q=componentid:190851%2B%20status:open", - "release_level": "stable", "language": "python", "library_type": "INTEGRATION", - "repo": "googleapis/google-cloud-python", - "distribution_name": "django-google-spanner", - "requires_billing": true, - "api_shortname": "django-google-spanner" -} + "name": "django-google-spanner", + "name_pretty": "Cloud Spanner Django", + "product_documentation": "https://cloud.google.com/spanner/docs/", + "release_level": "stable", + "repo": "googleapis/google-cloud-python" +} \ No newline at end of file diff --git a/packages/django-google-spanner/docs/README.rst b/packages/django-google-spanner/docs/README.rst index 72a33558153f..902696c81756 100644 --- a/packages/django-google-spanner/docs/README.rst +++ b/packages/django-google-spanner/docs/README.rst @@ -1 +1,288 @@ -.. include:: ../README.rst +Cloud Spanner support for Django +================================ + +|GA| |pypi| |versions| + +`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. + + +- `Client Library Documentation`_ +- `Product Documentation`_ + +.. |GA| image:: https://img.shields.io/badge/support-GA-gold.svg + :target: https://github.com/googleapis/google-cloud-python/blob/main/README.rst#general-availability +.. |pypi| image:: https://img.shields.io/pypi/v/django-google-spanner.svg + :target: https://pypi.org/project/django-google-spanner/ +.. |versions| image:: https://img.shields.io/pypi/pyversions/django-google-spanner.svg + :target: https://pypi.org/project/django-google-spanner/ +.. _Cloud Spanner: https://cloud.google.com/spanner/ +.. _Client Library Documentation: https://googleapis.dev/python/django-google-spanner/latest/index.html +.. _Product Documentation: https://cloud.google.com/spanner/docs + +Quick Start +----------- + +In order to use this library, you first need to go through the following steps: + +1. `Select or create a Cloud Platform project.`_ +2. `Enable billing for your project.`_ +3. `Enable the Google Cloud Spanner API.`_ +4. `Setup Authentication.`_ + +.. _Select or create a Cloud Platform project.: https://console.cloud.google.com/project +.. _Enable billing for your project.: https://cloud.google.com/billing/docs/how-to/modify-project#enable_billing_for_a_project +.. _Enable the Google Cloud Spanner API.: https://cloud.google.com/spanner +.. _Setup Authentication.: https://googleapis.dev/python/google-api-core/latest/auth.html + +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. + +.. _`virtualenv`: https://virtualenv.pypa.io/en/latest/ + + +Supported versions +~~~~~~~~~~~~~~~~~~ + +The library supports `Django 3.2 +`_, and `Django 4.2 +`_. +Both versions are long-term support (LTS) releases for the +`Django project_`. +The minimum required Python version is 3.6. + +.. code:: shell + + pip3 install django==3.2 + + +Installing the package +~~~~~~~~~~~~~~~~~~~~~~ + +To install from PyPI: + +.. code:: shell + + pip3 install django-google-spanner + + +To install from source: + +.. code:: shell + + git clone git@github.com:googleapis/google-cloud-python.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: + +.. code:: shell + + 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``: + + .. code:: python + + INSTALLED_APPS = [ + 'django_spanner', + ... + ] + +- Edit the ``DATABASES`` setting to point to an existing Cloud Spanner database: + + .. code:: python + + DATABASES = { + 'default': { + 'ENGINE': 'django_spanner', + 'PROJECT': '$PROJECT', + 'INSTANCE': '$INSTANCE', + 'NAME': '$DATABASE', + } + } + +Configuring primary key generation +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The Spanner Django engine by default uses random int64 values that are generated +by the client as primary key values. This default is applied to all databases that are +configured, including databases that use a different engine than Spanner. You can +disable this behavior with the RANDOM_ID_GENERATION_ENABLED setting: + + .. code:: python + + DATABASES = { + 'default': { + 'ENGINE': 'django_spanner', + 'PROJECT': '$PROJECT', + 'INSTANCE': '$INSTANCE', + 'NAME': '$DATABASE', + 'RANDOM_ID_GENERATION_ENABLED': false, + } + } + + + +Transaction support in autocommit mode +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Django version 4.2 and higher by default supports transactions in autocommit mode. +A transaction is automatically started if you define an +[atomic block](https://docs.djangoproject.com/en/4.2/topics/db/transactions/#controlling-transactions-explicitly). + +Django version 3.2 and earlier did not support transactions in autocommit mode with Spanner. +You can enable transactions in autocommit mode with Spanner with the +`ALLOW_TRANSACTIONS_IN_AUTO_COMMIT` configuration option. + +- To enable transactions in autocommit mode in V3.2, set the flag `ALLOW_TRANSACTIONS_IN_AUTO_COMMIT` to True in your settings.py file. +- To disable transactions in autocommit mode in V4.2, set the flag `ALLOW_TRANSACTIONS_IN_AUTO_COMMIT` to False in your settings.py file. + + +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: + +.. code:: shell + + export GOOGLE_APPLICATION_CREDENTIALS=/path/to/keyfile.json + export GOOGLE_CLOUD_PROJECT=gcloud_project + + +Apply the migrations +~~~~~~~~~~~~~~~~~~~~ + +Please run: + +.. code:: shell + + $ python3 manage.py migrate + +That'll take a while to run. After this you should be able to see the tables and indexes created in your Cloud Spanner console. + + +Create a Django admin user +~~~~~~~~~~~~~~~~~~~~~~~~~~~ +First you’ll need to create a user who can login to the admin site. Run the following command: + +.. code:: shell + + $ python3 manage.py createsuperuser + +which will then produce a prompt which will allow you to create your super user + +.. code:: shell + + Username: admin + Email address: admin@example.com + Password: ********** + Password (again): ********** + Superuser created successfully. + + +Login as admin +~~~~~~~~~~~~~~ +Now, run the server + +.. code:: shell + + 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/4.2/intro/tutorial02/#creating-models +to create and register the model to the Django’s automatically-generated admin site. + +How it works +------------ + +Overall design +~~~~~~~~~~~~~~ + +.. figure:: https://raw.githubusercontent.com/googleapis/google-cloud-python/main/assets/overview.png + :alt: "Overall Design" + +Internals +~~~~~~~~~ + +.. figure:: https://raw.githubusercontent.com/googleapis/google-cloud-python/main/assets/internals.png + :alt: "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 + +.. code:: shell + + >>> 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. + + +Limitations +~~~~~~~~~~~ + +Spanner has certain limitations of its own. The full set of limitations is documented +`here `__. +It is recommended that you go through that list. + +Django spanner has a set of limitations as well, which you can find +`here `__. + +Features from spanner that are not supported in Django-spanner are listed +`here `__.