Django Фильтрация предупреждений MySQL - PullRequest
8 голосов
/ 04 августа 2010

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

django / db / backends / mysql / base.py: 86: Предупреждение: усеченные данные для столбца 'slug' в строке 1

Первое, что я сделал, - начал прибегая к помощи этой программы после того, как исправил проблему.Чтобы исправить это, я настроил обе модели, чтобы их максимальная длина составляла 128 объявлений, а затем обновил таблицы SQL, чтобы соответствовать им. Но проблема сохранялась .. С некоторой уверенностью, что я действительно решил проблему, я решил, что с таким же успехом начну их отфильтровывать.Итак, в верхней части моего сценария я разместил это.

# Get rid of the MySQLdb warnings
import warnings
import MySQLdb
with warnings.catch_warnings():
    warnings.filterwarnings("ignore", category=MySQLdb.Warning)

И я с радостью перенес это в производство.Угадайте, что - как вы уже догадались, проблема осталась.Что теперь.Я быстро теряю уверенность в том, что я действительно исправил проблему, но двойная проверка показывает, что все столбцы слагов имеют длину 128 символов.Кроме того, я добавил sluggify к ошибке, если он длиннее 128 и все еще ничего.Итак, 2 вопроса:

  1. Как мне определить, какая операция помечает это.то есть где в моем коде поднимается флаг?

  2. Как я могу их отфильтровать?Мое исправление не работает?Это действительно предупреждение MySQLdb или предупреждение django.db.mysql.base?

Спасибо и счастливого взлома Django!

Для тех, у кого есть вопросы по структуре..

CREATE TABLE `people_employee` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(100) DEFAULT NULL,
  `email` varchar(75) DEFAULT NULL,
  `location_id` varchar(100) DEFAULT NULL,
  `jpeg` longtext,
  `first_name` varchar(100) DEFAULT NULL,
  `last_name` varchar(100) DEFAULT NULL,
  `maildomain` varchar(32) DEFAULT NULL,
  `mailserver` varchar(32) DEFAULT NULL,
  `mailfile` varchar(64) DEFAULT NULL,
  `contractor` tinyint(1) NOT NULL,
  `temporary` tinyint(1) NOT NULL,
  `formal_name` varchar(100) DEFAULT NULL,
  `nickname` varchar(32) DEFAULT NULL,
  `cell_phone` varchar(32) DEFAULT NULL,
  `office_phone` varchar(32) DEFAULT NULL,
  `other_phone` varchar(32) DEFAULT NULL,
  `fax` varchar(32) DEFAULT NULL,
  `assistant_id` int(11) DEFAULT NULL,
  `supervisor_id` int(11) DEFAULT NULL,
  `is_supervisor` tinyint(1) NOT NULL,
  `department_id` varchar(100) DEFAULT NULL,
  `division_id` varchar(100) DEFAULT NULL,
  `section_id` varchar(100) DEFAULT NULL,
  `job_classification_id` varchar(100) DEFAULT NULL,
  `functional_area_id` varchar(100) DEFAULT NULL,
  `position_id` varchar(100) DEFAULT NULL,
  `notes_url` varchar(200) DEFAULT NULL,
  `ldap_active` tinyint(1) NOT NULL,
  `notes_active` tinyint(1) NOT NULL,
  `created_at` datetime NOT NULL,
  `last_update` datetime NOT NULL,
  `is_active` tinyint(1) NOT NULL,
  `site_id` int(11) NOT NULL,
  `slug` varchar(128) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `slug` (`slug`),
  KEY `people_employee_location_id` (`location_id`),
  KEY `people_employee_assistant_id` (`assistant_id`),
  KEY `people_employee_supervisor_id` (`supervisor_id`),
  KEY `people_employee_department_id` (`department_id`),
  KEY `people_employee_division_id` (`division_id`),
  KEY `people_employee_section_id` (`section_id`),
  KEY `people_employee_job_classification_id` (`job_classification_id`),
  KEY `people_employee_functional_area_id` (`functional_area_id`),
  KEY `people_employee_position_id` (`position_id`),
  KEY `people_employee_site_id` (`site_id`)
) ENGINE=MyISAM AUTO_INCREMENT=1429 DEFAULT CHARSET=latin1;

И соответствующие модели.py.

slug = models.SlugField(max_length=128, editable=False, unique=True)

Надеюсь, это поможет ..

Ответы [ 3 ]

3 голосов
/ 06 июля 2012

Во-первых, я настоятельно рекомендую не фильтровать такие предупреждения: эта ошибка генерируется MySQL, и это абсолютно означает, что вы теряете данные.

Первое, что нужно сделать, - это использовать команду описания MySQL дляубедитесь, что столбец вашей базы данных фактически соответствует ожидаемому размеру: Django не поддерживает миграцию базы данных, если вы измените длину столбца, так что если поле slug было когда-либо короче, чем сейчас, вам нужновручную измените таблицу, чтобы задать новую длину:

mysql> DESCRIBE my_table slug;
+-------+--------------+------+-----+---------+-------+
| Field | Type         | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| slug  | varchar(255) | NO   | UNI | NULL    |       |
+-------+--------------+------+-----+---------+-------+
1 row in set (0.00 sec)

Если это поле оказалось не тем, что вы ожидали, вы можете просто решить проблему, обновив длину столбца:

mysql> ALTER TABLE my_table MODIFY slug VARCHAR(255) NOT NULL;

Есливы разрешаете символы Unicode в своих слагах, что также может объяснить это, поскольку ваш дамп выше использует набор символов latin1 вместо UTF-8 - один символ UTF-8 может быть до 4байтов данных, что означает, что значение длиной до 17 байтов может переполнить VARCHAR(64).

. Следующий шаг отладки:Реализуйте вариант вызова, который вы делаете, чтобы отфильтровать предупреждения, чтобы точно определить, где происходят ваши ошибки:

warnings.simplefilter("error",  category=MySQLdb.Warning)

Это сделает предупреждение фатальным, что остановит вашу программу, но, что более важно, также произведеттрассировка стека.Что-то вроде этого вы увидите ниже:

#!/usr/bin/env python
import warnings

def foo():
    warnings.warn("uhoh")

def bar():
    foo()

def main():
    warnings.simplefilter("error", UserWarning)
    bar()

if __name__ == "__main__":
    main()

Без вызова simplefilter:

cadams@Io:~ $ python test_warnings.py 
test_warnings.py:5: UserWarning: uhoh
  warnings.warn("uhoh")

С вызовом simplefilter:

cadams@Io:~ $ python test_warnings.py 
Traceback (most recent call last):
  File "test_warnings.py", line 15, in <module>
    main()
  File "test_warnings.py", line 12, in main
    bar()
  File "test_warnings.py", line 8, in bar
    foo()
  File "test_warnings.py", line 5, in foo
    warnings.warn("uhoh")
UserWarning: uhoh
1 голос
/ 29 марта 2016

Я бы отредактировал файл settings.py моего проекта, чтобы такое поведение происходило во всем моем проекте django.В противном случае я мог бы просто включить его в часть скрипта, где я хочу, чтобы это поведение происходило.


Поднимите предупреждения MySQL как ошибки:

import warnings, MySQLdb
warnings.filterwarnings('error', category=MySQLdb.Warning)

Чтобы игнорировать вместо повышенияошибка, замените "error" на "ignore".

Обрабатывайте их в блоке исключения, например:

try:
    # a MySQL DB operation that raises a warning
    # for example: a data truncated warning
except Warning as a_warning:
    # do something here
0 голосов
/ 08 октября 2018

Была похожая проблема, но с другими модулями (например, модуль gis не был найден при импорте форм дискет). Они были действительно лишними для нашего приложения, поэтому я добавил в файл настроек следующее:

# Set up warnings filters
# (action, re-pattern, category)   See warnings module docu.  Python std lib 28.6)

WARNINGS_FILTERS = [
    ("ignore", "Unable to import floppyforms.gis, geometry widgets not available", UserWarning),
    ("ignore", "There are known rendering problems with Cairo <= 1.14.0", UserWarning),
    ("ignore", "@font-face support needs Pango >= 1.38", UserWarning),
]

import warnings

for wf in WARNINGS_FILTERS:
    warnings.filterwarnings(*wf)

Перебор списка по списку дает мне более простой и понятный способ добавления / изменения / удаления предупреждений в будущем.

ПРИМЕЧАНИЕ. При каждом первом импортировании настроек происходит незначительный бит «дополнительной» обработки (скажем, новый рабочий запускается), но модуль предупреждений заменит существующие предупреждения, если append=False, что является значением по умолчанию. Другими словами, многократный импорт настроек не приведет к регистрации нескольких одинаковых фильтров.

...