Skip to content

Commit

Permalink
Fix dbrestore on SQLite (#383)
Browse files Browse the repository at this point in the history
Co-authored-by: Mark <[email protected]>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Mark Bakhit <[email protected]>
  • Loading branch information
4 people authored Aug 23, 2024
1 parent 163bd9e commit bc74b87
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 18 deletions.
20 changes: 16 additions & 4 deletions dbbackup/db/sqlite.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,23 @@ def restore_dump(self, dump):
if not self.connection.is_usable():
self.connection.connect()
cursor = self.connection.cursor()
sql_command = b""
sql_is_complete = True
for line in dump.readlines():
try:
cursor.execute(line.decode("UTF-8"))
except (OperationalError, IntegrityError) as err:
warnings.warn(f"Error in db restore: {err}")
sql_command = sql_command + line
line_str = line.decode("UTF-8")
if line_str.startswith("INSERT") and not line_str.endswith(");\n"):
sql_is_complete = False
continue
if not sql_is_complete and line_str.endswith(");\n"):
sql_is_complete = True

if sql_is_complete:
try:
cursor.execute(sql_command.decode("UTF-8"))
except (OperationalError, IntegrityError) as err:
warnings.warn(f"Error in db restore: {err}")
sql_command = b""


class SqliteCPConnector(BaseDBConnector):
Expand Down
1 change: 1 addition & 0 deletions dbbackup/tests/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"dbbackup",
"dbbackup.tests.testapp",
)
DEFAULT_AUTO_FIELD = "django.db.models.AutoField"

DATABASES = {
"default": {
Expand Down
12 changes: 11 additions & 1 deletion dbbackup/tests/test_connectors/test_sqlite.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from django.test import TestCase

from dbbackup.db.sqlite import SqliteConnector, SqliteCPConnector
from dbbackup.tests.testapp.models import CharModel
from dbbackup.tests.testapp.models import CharModel, TextModel


class SqliteConnectorTest(TestCase):
Expand All @@ -28,7 +28,17 @@ def test_create_dump_with_unicode(self):
dump = connector.create_dump()
self.assertTrue(dump.read())

def test_create_dump_with_newline(self):
TextModel.objects.create(
field=f'INSERT ({"foo" * 5000}\nbar\n WHERE \nbaz IS\n "great" );\n'
)

connector = SqliteConnector()
dump = connector.create_dump()
self.assertTrue(dump.read())

def test_restore_dump(self):
TextModel.objects.create(field="T\nf\nw\nnl")
connector = SqliteConnector()
dump = connector.create_dump()
connector.restore_dump(dump)
Expand Down
1 change: 1 addition & 0 deletions dbbackup/tests/testapp/migrations/0001_initial.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

class Migration(migrations.Migration):

initial = True
dependencies = []

operations = [
Expand Down
28 changes: 28 additions & 0 deletions dbbackup/tests/testapp/migrations/0002_textmodel.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Generated by Django 4.0.1 on 2022-04-27 22:36

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("testapp", "0001_initial"),
]

operations = [
migrations.CreateModel(
name="TextModel",
fields=[
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("field", models.TextField()),
],
),
]
16 changes: 4 additions & 12 deletions dbbackup/tests/testapp/models.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,14 @@
from django.db import models

___all__ = (
"CharModel",
"IntegerModel",
"TextModel",
"BooleanModel" "DateModel",
"DateTimeModel",
"ForeignKeyModel",
"ManyToManyModel",
"FileModel",
"TestModel",
)


class CharModel(models.Model):
field = models.CharField(max_length=10)


class TextModel(models.Model):
field = models.TextField()


class ForeignKeyModel(models.Model):
field = models.ForeignKey(CharModel, on_delete=models.CASCADE)

Expand Down
3 changes: 2 additions & 1 deletion docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ Changelog
Unreleased
----------

* Add `--no-drop` option to `dbrestore` command to prevent dropping tables before restoring data.
* Add --no-drop option to dbrestore command to prevent dropping tables before restoring data.
* Fix bug where sqlite dbrestore would fail if field data contains the line break character.

4.2.0 (2024-08-22)
------------------
Expand Down

0 comments on commit bc74b87

Please sign in to comment.