Как мне получить ошибки django «Слишком длинные данные для столбца»» в строке» для печати фактического значения?

#mysql #django

#mysql #django

Вопрос:

У меня есть приложение Django. Иногда при загрузке данных я получаю сообщение об ошибке, что одно из значений слишком длинное. Было бы очень полезно для отладки, если бы я мог видеть, какое значение превысило лимит. Могу ли я как-то это настроить? Я использую MySQL.

Было бы также неплохо, если бы я мог включить / отключить это для каждой модели или столбца, чтобы не допустить утечки пользовательских данных в журналы ошибок.

Комментарии:

1. Это не сообщение об ошибке Django, это то, что говорит база данных.

2. Просматривая исходный код MySQL , для этого нет опции конфигурации.

3. @WillemVanOnsem Да и нет. Это признак того, что проверка входных данных не соответствует проверке данных. Обычно это признак того, что используется не ModelForm, а обычная форма с жестко заданным значением max_length для символьных полей, которое со временем не синхронизируется с моделью. Другим распространенным случаем являются поля метода сериализатора DRF с тем же недостатком: нет проверки максимальной длины. Короче говоря, вы улавливаете то, что могли уловить раньше. Другой не столь распространенный случай, который было сложно отлаживать, когда я столкнулся с ним, — это фальшивая миграция, которая увеличивает максимальную длину поля.

4. Теперь, когда я больше думаю об этом, случай формы / сериализатора не работает, потому что поле CharField модели все равно должно было его поймать. Таким образом, это приводит к тому, что модели не синхронизируются с хранилищем базы данных и фальсифицированной / пропущенной / удаленной / неправильно сжатой миграции. Или, возможно, агрегирование / конкатенация, выполняемая на уровне поля, в поле, которое слишком мало.

5. @Melvyn код просто json.load обрабатывает файл json, загруженный через форму, а затем вручную создает их экземпляры MyModel и .save вводит их, поэтому данные вообще не проверяются. Вы правы, я должен изменить код для использования полей. Я действительно ценю, что вы ответили на основной вопрос.

Ответ №1:

При создании экземпляров модели из внешних источников необходимо позаботиться о проверке входных данных или иметь другие гарантии того, что эти данные не могут нарушать ограничения.

Когда вы не вызываете full_clean() , по крайней мере, модель, а вызываете напрямую save , вы обходите валидаторы Django и получаете уведомление о проблеме только от драйвера базы данных, после чего получить диагностику становится сложнее:

 
class JsonImportManager(models.Manager):
    def import(self, json_string: str) -> int:
        data_list = json.loads(json_string)  # list of objects => list of dicts
        failed = 0
        for data in data_list:
            obj = self.model(**data)
            try:
                obj.full_clean()
            except ValidationError as e:
                print(e.message_dict)  # or use better formatting function
                failed  = 1
            else:
                obj.save()

        return failed
 

Это, конечно, очень просто, но это хороший шаблон для начала.