2010-08-04 5 views
8

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

Джанго/DB/бэкэнды/MySQL/base.py: 86: Внимание: Данные усечены для столбца 'пули' в строке 1

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

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

И я счастливо отодвинул его на производство. Угадайте, что - вы догадались, что проблема осталась. Ну что теперь. Я быстро теряю уверенность в том, что я действительно исправил проблему, но двойная проверка этого показывает, что все столбцы slug имеют длину 128 символов. Кроме того, я завернул провал в ошибку, если он длиннее 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; 

И соответствующий models.py.

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

Надежда, что помогает ..

+0

ли поле (s) эти данные могут поступать из текста имеют ограничения, налагаемые? –

+0

Нет - я устанавливаю пулю на сохранение. Я выталкиваю предупреждение, если длина> 128 (но это не так). – rh0dium

+0

Можете ли вы опубликовать вывод «описать» таблицы (из производственной коробки) и модели, которую вы используете? –

ответ

3

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

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

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:

[email protected]:~ $ python test_warnings.py 
test_warnings.py:5: UserWarning: uhoh 
    warnings.warn("uhoh") 

С вызовом SimpleFilter:

[email protected]:~ $ 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 
+0

Wow - Поговорите о возрождении! Хорошая работа! Я уже решил это (не удалось обновить этот сайт). Вы упомянули об UTF-8/Latin. Какой PITA он должен был найти. Отличные намеки здесь! – rh0dium

1

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


Raise 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 
Смежные вопросы