Tengo problemas al tratar de usar un almacén de datos postgres de heroku desde una restauración de una base de datos postgres local que tengo. Usando la base de datos postgres restaurada, Django se ejecuta normalmente. Recupera todos los objetos y utiliza sus campos, claves principales, etc. sin ningún problema.

Pero cuando se trata de escribir en la base de datos, obtengo el mismo error en todos los ámbitos, independientemente del modelo o modelos.

psycopg2.IntegrityError: null value in column "id" violates not-null constraint

Cuando restablezco la base de datos de heroku y creo objetos desde una pizarra en blanco, no hay problemas. Pero si trato de crear cualquier objeto en una base de datos restaurada, siempre obtengo estonull value in column "id" violates not-null constraint


Aquí hay un seguimiento de pila copiado/pegado al intentar crear un modelo básico en Django Admin. Elegí este ejemplo de modelo porque no hay código adicional relacionado con su creación. Sin señales ni nada.

Django Version: 2.0 Python Version: 3.6.3

Traceback:

File "/app/.heroku/python/lib/python3.6/site-packages/django/db/backends/utils.py" in _execute 85. return self.cursor.execute(sql, params)

The above exception (null value in column "id" violates not-null constraint DETAIL: Failing row contains (null, Special Class, special-class). ) was the direct cause of the following exception:

File "/app/.heroku/python/lib/python3.6/site-packages/django/core/handlers/exception.py" in inner 35. response = get_response(request)

File "/app/.heroku/python/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response 128. response = self.process_exception_by_middleware(e, request)

File "/app/.heroku/python/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response 126. response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/app/.heroku/python/lib/python3.6/site-packages/django/contrib/admin/options.py" in wrapper 574. return self.admin_site.admin_view(view)(*args, **kwargs)

File "/app/.heroku/python/lib/python3.6/site-packages/django/utils/decorators.py" in _wrapped_view 142. response = view_func(request, *args, **kwargs)

File "/app/.heroku/python/lib/python3.6/site-packages/django/views/decorators/cache.py" in _wrapped_view_func 44. response = view_func(request, *args, **kwargs)

File "/app/.heroku/python/lib/python3.6/site-packages/django/contrib/admin/sites.py" in inner 223. return view(request, *args, **kwargs)

File "/app/.heroku/python/lib/python3.6/site-packages/django/contrib/admin/options.py" in add_view 1553. return self.changeform_view(request, None, form_url, extra_context)

File "/app/.heroku/python/lib/python3.6/site-packages/django/utils/decorators.py" in _wrapper 62. return bound_func(*args, **kwargs)

File "/app/.heroku/python/lib/python3.6/site-packages/django/utils/decorators.py" in _wrapped_view 142. response = view_func(request, *args, **kwargs)

File "/app/.heroku/python/lib/python3.6/site-packages/django/utils/decorators.py" in bound_func 58. return func.get(self, type(self))(*args2, **kwargs2)

File "/app/.heroku/python/lib/python3.6/site-packages/django/contrib/admin/options.py" in changeform_view 1450. return self._changeform_view(request, object_id, form_url, extra_context)

File "/app/.heroku/python/lib/python3.6/site-packages/django/contrib/admin/options.py" in _changeform_view 1490. self.save_model(request, new_object, form, not add)

File "/app/.heroku/python/lib/python3.6/site-packages/django/contrib/admin/options.py" in save_model 1026. obj.save()

File "/app/.heroku/python/lib/python3.6/site-packages/django/db/models/base.py" in save 729. force_update=force_update, update_fields=update_fields)

File "/app/.heroku/python/lib/python3.6/site-packages/django/db/models/base.py" in save_base 759. updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)

File "/app/.heroku/python/lib/python3.6/site-packages/django/db/models/base.py" in _save_table 842. result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)

File "/app/.heroku/python/lib/python3.6/site-packages/django/db/models/base.py" in _do_insert 880. using=using, raw=raw)

File "/app/.heroku/python/lib/python3.6/site-packages/django/db/models/manager.py" in manager_method 82. return getattr(self.get_queryset(), name)(*args, **kwargs)

File "/app/.heroku/python/lib/python3.6/site-packages/django/db/models/query.py" in _insert 1125. return query.get_compiler(using=using).execute_sql(return_id)

File "/app/.heroku/python/lib/python3.6/site-packages/django/db/models/sql/compiler.py" in execute_sql 1280. cursor.execute(sql, params)

File "/app/.heroku/python/lib/python3.6/site-packages/django/db/backends/utils.py" in execute 100. return super().execute(sql, params)

File "/app/.heroku/python/lib/python3.6/site-packages/django/db/backends/utils.py" in execute 68. return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)

File "/app/.heroku/python/lib/python3.6/site-packages/django/db/backends/utils.py" in _execute_with_wrappers 77. return executor(sql, params, many, context)

File "/app/.heroku/python/lib/python3.6/site-packages/django/db/backends/utils.py" in _execute 85. return self.cursor.execute(sql, params)

File "/app/.heroku/python/lib/python3.6/site-packages/django/db/utils.py" in exit 89. raise dj_exc_value.with_traceback(traceback) from exc_value

File "/app/.heroku/python/lib/python3.6/site-packages/django/db/backends/utils.py" in _execute 85. return self.cursor.execute(sql, params)

Exception Type: IntegrityError at /admin/fantasy/raceclass/add/ Exception Value: null value in column "id" violates not-null constraint DETAIL: Failing row contains (null, Special Class, special-class).


El modelo del seguimiento de la pila (tenga en cuenta que este error le ocurre a todos los modelos, no solo a este [muy básico]).

class RaceClass(models.Model):
    title = models.CharField(max_length=140)
    slug = models.SlugField(unique=True)

    def __str__(self):
        return self.title

    class Meta:
        ordering = ['title']

Así es como restauro (d) los datos locales en heroku:

Estoy descargando mi base de datos Postgres local (Versión 10.0) usando el comando:

PGPASSWORD=mypassword pg_dump -Fc --no-acl --no-owner -h localhost -U myuser mydb > mydb.dump

Luego carga a AWS y restaura a un almacén de datos de Postgres (versión 9.6.5) en Heroku usando el comando:

heroku pg:backups:restore 'https://s3.amazonaws.com/me/items/3H0q/mydb.dump' DATABASE_URL

Ambos son directamente de la documentación de Heroku: https://devcenter.heroku.com/articles/heroku-postgres-import-export


Nota al margen: estoy usando la versión 10.0 de Postgres localmente y Heroku Datastore es 9.6.5

respuesta

Estoy bastante seguro de que esto se debe a que está exportando desde Postgres 10 e importando a 9. No falla del todo, pero parte de la definición del esquema (en este caso, los campos de ID de incremento automático) no se importan correctamente.

Se me ocurren dos opciones:

  1. Intente volcar SQL sin procesar en lugar de un formato personalizado:

    PGPASSWORD=mypassword pg_dump --no-acl --no-owner -h localhost -U myuser mydb > mydb.sql
    

    No puede usar pg_restorepara cargar esto; en su lugar, debe ejecutar la consulta manualmente usando psql. Algo como esto debería funcionar:

    heroku pg:psql < mydb.sql
    

    La advertencia aquí es que primero debe vaciar la base de datos existente.

  2. Si esto también falla, debe exportar desde la misma versión principal de Postgres a la que desea importar.

El error clave es este:

I'm using Version 10.0 Postgres locally and Heroku Datastore is 9.6.5

Eso es un problema esperando a suceder. Intentaría usar la misma versión en ambos. Al menos la misma versión principal.

Lo que me viene a la mente con estos dos en particular es la introducción de columnas de SQL estándar IDENTITYen Postgres 10 , que están destinadas a reemplazar en gran medida las columnas en serie. No reveló las definiciones de la tabla, por lo que solo puedo adivinar. La IDENTITYfunción en Postgres 10 no se traduciría de nuevo a Postgres 9.6, lo que podría explicar muy bien la violación de los valores NULL en sus mensajes de error.

Relacionada:

Recientemente me enfrenté al mismo problema, esto es lo que funciona para mí:

  1. Crear nueva base de datos
  2. Usando Django manage.py para volcar los datos de mi base de datos y restaurarlos a la nueva base de datos después de aplicar todas las migraciones.

    python manage.py dumpdata --exclude auth.permission --exclude contenttypes --indent 2 > db.json

  3. Restaurar la copia de seguridad

    python manage.py loaddata db.json