Skip to content

Commit

Permalink
Merge branch 'restore-reset-sequences' into 'main'
Browse files Browse the repository at this point in the history
Reset DB sequences on restore backup to prevent ID conflicts

See merge request reportcreator/reportcreator!727
  • Loading branch information
MWedl committed Oct 8, 2024
2 parents a4c7495 + dcb82cd commit cec24ef
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
* Markdown editor: Show markdown snippet in markdown image preview dialogs
* Bugfixes in note sharing
* Fix race condition when creating comments for text selection
* Reset DB sequences on restore backup to prevent ID conflicts


## v2024.74 - 2024-09-24
Expand Down
14 changes: 14 additions & 0 deletions api/src/reportcreator_api/api_utils/backup_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from django.conf import settings
from django.core import serializers
from django.core.management import call_command
from django.core.management.color import no_style
from django.core.serializers.json import DjangoJSONEncoder
from django.db import connection, transaction
from django.db.migrations.executor import MigrationExecutor
Expand Down Expand Up @@ -235,6 +236,14 @@ def get_model(model_identifier):
connection.check_constraints()


def reset_database_sequences():
app_list = [app_config for app_config in apps.get_app_configs() if app_config.models_module is not None]
models = list(itertools.chain(*map(lambda a: a.get_models(include_auto_created=True), app_list)))
statements = connection.ops.sequence_reset_sql(style=no_style(), model_list=models)
with connection.cursor() as cursor:
cursor.execute('\n'.join(statements))


def walk_storage_dir(storage, base_dir=None):
base_dir = base_dir or ''
try:
Expand Down Expand Up @@ -333,6 +342,11 @@ def restore_backup(z, keepfiles=True):
restore_database_dump(f)
logging.info('Finished restoring DB data')

# Reset sequences
logging.info('Begin resetting DB sequences')
reset_database_sequences()
logging.info('Finished resetting DB sequences')

# Restore files
logging.info('Begin restoring files')
if not keepfiles:
Expand Down
3 changes: 3 additions & 0 deletions api/src/reportcreator_api/tests/test_backup.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,9 @@ def test_backup_restore(self):
# BackupLog entry created
assert list(BackupLog.objects.values_list('type', flat=True)) == [BackupLogType.RESTORE, BackupLogType.BACKUP, BackupLogType.SETUP]

# Can add ignored word without ID conflict
create_languagetool_ignore_word()

def test_backup_restore_damaged(self):
backup = b''.join(self.backup_request(aes_key=self.backup_encryption_key).streaming_content)
backup = backup[:len(backup) - 100]
Expand Down

0 comments on commit cec24ef

Please sign in to comment.