django-dbbackup
django-dbbackup copied to clipboard
`dbrestore` fails with non-existent relation
Bug Report
Describe the bug
Trying to restore from a backup, I'm running into the following error:
Error running: pg_restore --dbname=postgresql://postgres:password@db:5432/shipper --single-transaction --clean
pg_restore: error: could not execute query: ERROR: relation "public.core_statistics" does not exist
Command was: ALTER TABLE ONLY public.core_statistics DROP CONSTRAINT shipper_statistics_build_id_98571750_fk_shipper_build_id;
To Reproduce
- Back up the database with
dbbackup - Restore the database with
dbrestore
Expected behavior
The backup is restored successfully.
Screenshots or reproduction
The Django project I'm encountering the problem with can be found here: https://github.com/shipperstack/shipper
I am using the Docker Compose of the project which can be found here: https://github.com/shipperstack/shipper-docker
It is possible that some of the DB schema might be a little weird because of all the migrations, but I am pretty confident in asying that 2.x and above have consistent migrations that shouldn't impose a problem on django-dbbackup (but worth keeping in mind).
Versions
Django-dbbackup
- pypi: 4.0.2
External tools
- Python: 3.11.2-r0 (alpine-3.17)
- Django: 4.1.7
- OS: Linux, Docker
I'm also affected by this bug.
Removing --clean makes it work though.
Interesting, for me, removing --single-transaction did the trick.
For those who find this, issue, I simply added this to my Django confirm: DBBACKUP_CONNECTORS = {"default": {"SINGLE_TRANSACTION": False}}
Can we add an option on these configurations for postgres to allow us to use the if-exists condition on these drop constraints?
https://www.postgresql.org/docs/current/app-pgrestore.html
+1 for --if-exists
Had an issue with droping constaint which does not exists anymore where I needed --if-exists option.
As a hotfix provided locally next code:
# django-dbbackups
# https://github.com/jazzband/django-dbbackup/issues/478#issuecomment-1677907470
DBBACKUP_CONNECTORS = {'default': {'IF_EXISTS': True}}
DBBACKUP_CONNECTOR_MAPPING = {
'django.db.backends.postgresql': 'server.apps.core.db.postgresql.PgDumpBinaryConnector',
}
And in the server.apps.core.db.postgresql module next:
from dbbackup.db.postgresql import PgDumpBinaryConnector as CorePgDumpBinaryConnector, create_postgres_uri
class PgDumpBinaryConnector(CorePgDumpBinaryConnector):
if_exists = False
def _restore_dump(self, dump):
dbname = create_postgres_uri(self)
cmd = f"{self.restore_cmd} {dbname}"
if self.single_transaction:
cmd += " --single-transaction"
if self.drop:
cmd += " --clean"
if self.if_exists:
cmd += " --if-exists"
cmd = f"{self.restore_prefix} {cmd} {self.restore_suffix}"
stdout, stderr = self.run_command(cmd, stdin=dump, env=self.restore_env)
return stdout, stderr
PRs to resolve this are welcome!
Hi @Archmonger , Created PR for resolving it in the library :)