2012-06-19 7 views
8

Komunikat o błędzie Dostałemdanych okrojone do kolumny „url” w wierszu 1 - błąd przy programowaniu z Python Django

Traceback (most recent call last): 
    File "./test.py", line 416, in <module> 
    startup() 
    File "./test.py", line 275, in startup 
    writer.save(r,data) 
    File "/home/user/project/test/output.py", line 91, in save 
    self.save_doc(r, data, pid) 
    File "/home/user/project/test/output.py", line 130, in save_doc 
    cursor.execute(dbquery) 
    File "/usr/local/lib/python2.6/site-packages/django/db/backends/util.py", line 34, in execute 
    return self.cursor.execute(sql, params) 
    File "/usr/local/lib/python2.6/site-packages/django/db/backends/mysql/base.py", line 86, in execute 
    return self.cursor.execute(query, args) 
    File "/usr/local/lib/python2.6/site-packages/MySQL_python-1.2.3c1-py2.6-linux-x86_64.egg/MySQLdb/cursors.py", line 175, in execute 
    File "/usr/local/lib/python2.6/site-packages/MySQL_python-1.2.3c1-py2.6-linux-x86_64.egg/MySQLdb/cursors.py", line 89, in _warning_check 
_mysql_exceptions.Warning: Data truncated for column 'url' at row 1 

Pierwszą rzeczą Sprawdzałem to jeśli ciąg URL jest dłuższy niż długość pola , ale w rzeczywistości jest znacznie krótszy. Database Projekt

+----------+-------------------------------------------------------------------+ 
| Database | Create Database             | 
+----------+-------------------------------------------------------------------+ 
| myurlcol | CREATE DATABASE `myurlcol` /*!40100 DEFAULT CHARACTER SET utf8 */ | 
+----------+-------------------------------------------------------------------+ 

Tabela Projekt

CREATE TABLE `document` (
    `id` int(11) NOT NULL auto_increment, 
    `url` varchar(255) collate utf8_bin NOT NULL, 
    `md5` varchar(32) collate utf8_bin NOT NULL, 
    `host` varchar(255) collate utf8_bin default NULL, 
    `content_sha1` varchar(40) collate utf8_bin NOT NULL, 
    `add_date` datetime NOT NULL, 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `url` (`url`), 
    UNIQUE KEY `md5` (`md5`), 
    KEY `main_crawl_document_content_sha1` (`content_sha1`), 
    KEY `main_crawl_document_discover_date` (`add_date`), 
    KEY `main_crawl_document_host` (`host`), 
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_bin; 

I wydrukować długości danych próbuję wstawić do tabeli (I 'm testowania przy użyciu tylko jeden adres URL):

len(url) = 89 
len(md5) = 32 
len(host) = 20 
len(content_sha1) = 40 
len(add_date) = 19 

Używałem kursora utworzonego przez Django.db.connection. Aby być bardziej pouczające, wkleić całą komendę zapytania do bazy danych zdałem do cursor.execute()

INSERT INTO main_document SET url='ftp://ftp.ncbi.nlm.nih.gov/pub/pmc/0a/39/Arthritis_Res_2000_Jun_5_2%284%29_315-326.tar.gz',md5='b6ba3adde8de87e4dc255092b04d07ea',host='ftp.ncbi.nlm.nih.gov',content_sha1='9aeab4412cc9b1add84a6d2bca574664e193b56e',add_date='2012-05-15 00:00:00'; 

Najśmieszniejsze jest to, że powyższa komenda działa kiedy kopiować i wklejać do linii poleceń MySQL. Brak komunikatów o błędach i dane są poprawnie wstawiane.

Co się dzieje?

+0

To ostrzeżenie, a nie błąd. –

+0

@Secator może to być ostrzeżenie MySQL, ale powraca jako błąd w Pythonie. Sądzę, że nie mogłeś tego zobaczyć aż do edycji, która to usuwa. – Jordan

+2

Dziękuję za pozostawienie komentarzy, ale oto moje pytania: (1) jak usunąć te ostrzeżenia. (2) jeśli muszę je zachować, jak je zignorować i pozwolić na zapisanie danych do bazy danych. Obecnie dane nie są zapisywane w bazie danych. – fanchyna

Odpowiedz

0

Powinieneś spróbować urllib.unquote(url), aby uzyskać unquote ciąg znaków URL przed wstawieniem go do bazy danych. Znacznik cudzysłowu%, który występuje w twoim łańcuchu, jest special character dla MySQL i może zmienić twoją transakcję.

Twoja wkładka powinien brzmieć:

INSERT INTO main_document SET url='ftp://ftp.ncbi.nlm.nih.gov/pub/pmc/0a/39/Arthritis_Res_2000_Jun_5_2(4)_315-326.tar.gz',md5='b6ba3adde8de87e4dc255092b04d07ea',host='ftp.ncbi.nlm.nih.gov',content_sha1='9aeab4412cc9b1add84a6d2bca574664e193b56e',add_date='2012-05-15 00:00:00'; 

Zauważ, że MySQL traktuje% tylko w kontekstach specjalny wzorzec dopasowania. Na końcu może być coś nie tak z Django ORM.

+0

Jeśli fanchyna używa cursor.execute(), znak '%' nie powinien stanowić problemu, ponieważ% s byłby wcześniej zastąpiony, prawda? – madtyn

1

cursor.execute obsługuje przechwytywanie MySQL, jeśli używasz go poprawnie. Some Examples Here

Podstawową ideą jest wykorzystanie %s w surowym ciąg SQL, gdzie aktualnie są w tym wartości surowców, a następnie przekazać Drugi argument cursor.execute() która jest krotką (lub tablica) wartości w porządku. W twoim przypadku będzie to wyglądać następująco:

url = 'ftp://ftp.ncbi.nlm.nih.gov/pub/pmc/0a/39/Arthritis_Res_2000_Jun_5_2%284%29_315-326.tar.gz' 
md5 = 'b6ba3adde8de87e4dc255092b04d07ea' 
host = 'ftp.ncbi.nlm.nih.gov' 
content_sha1 = '9aeab4412cc9b1add84a6d2bca574664e193b56e' 
add_date = '2012-05-15 00:00:00' 
sql = "INSERT INTO main_document SET url = %s, md5 = %s, host = %s, content_sha1 = %s, add_date = %s" 
cursor.execute(sql, (url, md5, host, content_sha1, add_date)) 
+0

Nie widzę wartości "md5" określonej w składni instrukcji execute. Czy to literówka? – daemon12

+0

Tak, właśnie naprawiłem to, aby dołączyć md5, dziękuję! –

Powiązane problemy