Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix dbrestore on SQLite #383

Merged
merged 14 commits into from
Aug 23, 2024
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