Actually, lets do the command
This commit is contained in:
parent
3c80acc7d9
commit
d167dfd444
@ -14,7 +14,8 @@ for command in decrypt_documents \
|
|||||||
document_thumbnails \
|
document_thumbnails \
|
||||||
document_sanity_checker \
|
document_sanity_checker \
|
||||||
document_fuzzy_match \
|
document_fuzzy_match \
|
||||||
manage_superuser;
|
manage_superuser \
|
||||||
|
convert_mariadb_uuid;
|
||||||
do
|
do
|
||||||
echo "installing $command..."
|
echo "installing $command..."
|
||||||
sed "s/management_command/$command/g" management_script.sh > /usr/local/bin/$command
|
sed "s/management_command/$command/g" management_script.sh > /usr/local/bin/$command
|
||||||
|
@ -356,3 +356,17 @@ processing documents with this issue.
|
|||||||
## Platform-Specific Deployment Troubleshooting
|
## Platform-Specific Deployment Troubleshooting
|
||||||
|
|
||||||
A user-maintained wiki page is available to help troubleshoot issues that may arise when trying to deploy Paperless-ngx on specific platforms, for example SELinux. Please see [the wiki](https://github.com/paperless-ngx/paperless-ngx/wiki/Platform%E2%80%90Specific-Troubleshooting).
|
A user-maintained wiki page is available to help troubleshoot issues that may arise when trying to deploy Paperless-ngx on specific platforms, for example SELinux. Please see [the wiki](https://github.com/paperless-ngx/paperless-ngx/wiki/Platform%E2%80%90Specific-Troubleshooting).
|
||||||
|
|
||||||
|
## Logs show "possible incompatible database column" when deleting documents {#convert-uuid-field}
|
||||||
|
|
||||||
|
You may see errors when deleting documents like:
|
||||||
|
|
||||||
|
```
|
||||||
|
Data too long for column 'transaction_id' at row 1
|
||||||
|
```
|
||||||
|
|
||||||
|
This error can occur in installations which have upgraded from a version of Paperless-ngx that used Django 4 (Paperless-ngx versions prior to v2.13.0) with a MariaDB/MySQL database. Due to the backawards-incompatible change in Django 5, the column "documents_document.transaction_id" will need to be re-created, which can be done with a one-time run of the following management command:
|
||||||
|
|
||||||
|
```shell-session
|
||||||
|
$ python3 manage.py convert_mariadb_uuid
|
||||||
|
```
|
||||||
|
36
src/documents/management/commands/convert_mariadb_uuid.py
Normal file
36
src/documents/management/commands/convert_mariadb_uuid.py
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
from django.core.management.base import BaseCommand
|
||||||
|
from django.db import connection
|
||||||
|
from django.db import models
|
||||||
|
|
||||||
|
from documents.models import Document
|
||||||
|
|
||||||
|
|
||||||
|
class Command(BaseCommand): # pragma: no cover
|
||||||
|
# This code is taken almost entirely from https://github.com/wagtail/wagtail/pull/11912 with all credit to the original author.
|
||||||
|
help = "Converts UUID columns from char type to the native UUID type used in MariaDB 10.7+ and Django 5.0+."
|
||||||
|
|
||||||
|
def convert_field(self, model, field_name, null=False):
|
||||||
|
if model._meta.get_field(field_name).model != model:
|
||||||
|
# Field is inherited from a parent model
|
||||||
|
return
|
||||||
|
|
||||||
|
if not model._meta.managed:
|
||||||
|
# The migration framework skips unmanaged models, so we should too
|
||||||
|
return
|
||||||
|
|
||||||
|
old_field = models.CharField(null=null, max_length=36)
|
||||||
|
old_field.set_attributes_from_name(field_name)
|
||||||
|
|
||||||
|
new_field = models.UUIDField(null=null)
|
||||||
|
new_field.set_attributes_from_name(field_name)
|
||||||
|
|
||||||
|
with connection.schema_editor() as schema_editor:
|
||||||
|
schema_editor.alter_field(model, old_field, new_field)
|
||||||
|
self.stdout.write(
|
||||||
|
self.style.SUCCESS(
|
||||||
|
f"Successfully converted {model._meta.label} {field_name} field to UUID type.",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
def handle(self, **options):
|
||||||
|
self.convert_field(Document, "transaction_id", null=True)
|
@ -15,6 +15,7 @@ from django.conf import settings
|
|||||||
from django.contrib.auth.models import Permission
|
from django.contrib.auth.models import Permission
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.core.cache import cache
|
from django.core.cache import cache
|
||||||
|
from django.db import DataError
|
||||||
from django.test import override_settings
|
from django.test import override_settings
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from guardian.shortcuts import assign_perm
|
from guardian.shortcuts import assign_perm
|
||||||
@ -2605,6 +2606,35 @@ class TestDocumentApi(DirectoriesMixin, DocumentConsumeDelayMixin, APITestCase):
|
|||||||
self.assertEqual(resp.status_code, status.HTTP_200_OK)
|
self.assertEqual(resp.status_code, status.HTTP_200_OK)
|
||||||
self.assertEqual(doc1.tags.count(), 2)
|
self.assertEqual(doc1.tags.count(), 2)
|
||||||
|
|
||||||
|
@mock.patch("django_softdelete.models.SoftDeleteModel.delete")
|
||||||
|
def test_warn_on_delete_with_old_uuid_field(self, mocked_delete):
|
||||||
|
"""
|
||||||
|
GIVEN:
|
||||||
|
- Existing document in a (mocked) MariaDB database with an old UUID field
|
||||||
|
WHEN:
|
||||||
|
- API request to delete document is made which raises "Data too long for column" error
|
||||||
|
THEN:
|
||||||
|
- Warning is logged alerting the user of the issue (and link to the fix)
|
||||||
|
"""
|
||||||
|
|
||||||
|
doc = Document.objects.create(
|
||||||
|
title="test",
|
||||||
|
mime_type="application/pdf",
|
||||||
|
content="this is a document 1",
|
||||||
|
checksum="1",
|
||||||
|
)
|
||||||
|
|
||||||
|
mocked_delete.side_effect = DataError(
|
||||||
|
"Data too long for column 'transaction_id' at row 1",
|
||||||
|
)
|
||||||
|
|
||||||
|
with self.assertLogs(level="WARNING") as cm:
|
||||||
|
self.client.delete(f"/api/documents/{doc.pk}/")
|
||||||
|
self.assertIn(
|
||||||
|
"Detected a possible incompatible database column",
|
||||||
|
cm.output[0],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class TestDocumentApiV2(DirectoriesMixin, APITestCase):
|
class TestDocumentApiV2(DirectoriesMixin, APITestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
@ -406,7 +406,14 @@ class DocumentViewSet(
|
|||||||
from documents import index
|
from documents import index
|
||||||
|
|
||||||
index.remove_document_from_index(self.get_object())
|
index.remove_document_from_index(self.get_object())
|
||||||
return super().destroy(request, *args, **kwargs)
|
try:
|
||||||
|
return super().destroy(request, *args, **kwargs)
|
||||||
|
except Exception as e:
|
||||||
|
if "Data too long for column" in str(e):
|
||||||
|
logger.warning(
|
||||||
|
"Detected a possible incompatible database column. See https://docs.paperless-ngx.com/troubleshooting/#convert-uuid-field",
|
||||||
|
)
|
||||||
|
return HttpResponseBadRequest(str(e))
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def original_requested(request):
|
def original_requested(request):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user