Actually, lets do the command

This commit is contained in:
shamoon 2024-10-26 22:01:55 -07:00
parent 3c80acc7d9
commit d167dfd444
5 changed files with 90 additions and 2 deletions

View File

@ -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

View File

@ -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
```

View 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)

View File

@ -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):

View File

@ -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())
try:
return super().destroy(request, *args, **kwargs) 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):