googleapis / python-spanner-django

Cloud Spanner database backend for Django
BSD 3-Clause "New" or "Revised" License
88 stars 27 forks source link

django-spanner's autofield generation does not work for non-default spanner DBs #783

Open untitaker opened 2 years ago

untitaker commented 2 years ago

https://github.com/googleapis/python-spanner-django/pull/780 introduced a check as to whether the default database's engine is spanner or not, and depending on that decides to override id generation with clientside uuid or not.

This fix is insufficient. It does improve the situation, as django-spanner will disable its monkeypatches if the default db is not spanner.

But the original issue https://github.com/googleapis/python-spanner-django/issues/742 was talking about using multiple databases, where default db is mysql. This is what django.db.connection.settings_dict refers to. The correct key to check would be django.db.connections[???].settings_dict.

Steps to reproduce

  1. set up spanner as a non-default database
  2. see that even running basic migrations against that non-default db fails, as the inserts into the django_migrations table already fail.

I'll investigate how to fix. It's likely something else has to be patched entirely.

Environment details

IlyaFaer commented 1 year ago

About the next spring a new auto incrementing primary keys features is expected to be released in Spanner. It should make autofield patch unnecessary at all.

mitsuo0114 commented 3 months ago

+1. what is current status? I've found the auto incrementing primary keys feature was introduced. https://cloud.google.com/blog/products/databases/announcing-support-for-auto-generated-keys-in-spanner?hl=en

But still I'm facing error when migration info is inserted to django_migrations.

"id must not be NULL in table django_migrations."

On Cloud Spanner, following table is created automatically. The table definition of django_migrations does not include configs for auto-generate-keys.

CREATE TABLE django_migrations (
  id INT64 NOT NULL,
  app STRING(255) NOT NULL,
  name STRING(255) NOT NULL,
  applied TIMESTAMP NOT NULL,
) PRIMARY KEY(id);;

I manually configured django_migrations with sequence like below and migration succeeded.

CREATE SEQUENCE serial OPTIONS(sequence_kind='bit_reversed_positive');

CREATE TABLE django_migrations (
  id INT64 DEFAULT (GET_NEXT_SEQUENCE_VALUE(SEQUENCE serial)),
  app STRING(255) NOT NULL,
  name STRING(255) NOT NULL,
  applied TIMESTAMP NOT NULL,
) PRIMARY KEY(id);;

but I'm concerning this is right way for work around. It would be helpful if someone give advice to me and for this workaround.

sarafraghav commented 3 weeks ago

Facing this same issue - using spanner as a non-default DB. Whenever I am inserting records to another db - bulk_create is failing with thw following strace

File "/Users/saraf/Library/Caches/pypoetry/virtualenvs/workflow-platform-HlqtOrhH-py3.12/lib/python3.12/site-packages/django/contrib/contenttypes/management/__init__.py", line 152, in create_contenttypes ContentType.objects.using(using).bulk_create(cts) File "/Users/saraf/Library/Caches/pypoetry/virtualenvs/workflow-platform-HlqtOrhH-py3.12/lib/python3.12/site-packages/django/db/models/query.py", line 816, in bulk_create assert len(returned_columns) == len(objs_without_pk)

If I remove django_spanner from installed_apps before running this command - it works