mr-ZA
@mr-ZA

Из csv в mysql таблицу PYTHON?

Всех приветствую, возникла проблема при импорте строк из .csv файла с записями в mysql с помощью python скрипта. Объясните мне пожалуйста что не так, исправьте!

Таблица mysql:
CREATE TABLE crimes (
 `Crime id` INT PRIMARY KEY,
 `Original Crime Type Name` VARCHAR(30),
 `Call Date` DATETIME,
 `Offense Date` DATETIME,
 `Call Time` TIME,
 `Call Date Time` DATETIME,
 Disposition VARCHAR(10),
 Address VARCHAR(40),
 City VARCHAR(13),
 State VARCHAR(2),
 `Agency Id` INT,
 `Address Type` VARCHAR(16),
 `Common Location` VARCHAR(20));


Скрипт питон
import MySQLdb
import csv

db = MySQLdb.connect(host="192.168.1.2",
                     port=3306,
                     user="non-root-boy",
                     passwd="123456",
                     db="sfpd")
print ("\nConnection to DataBase established..\n")
cur = db.cursor()

f = open('/home/decoy/Downloads/police-department-calls-for-service.csv')
csv_f = csv.reader(f)                               #parsed -> return in csv_f

for row in csv_f:
    cur.execute('INSERT INTO sfpd(`Crime Id`, `Original Crime Type Name`, \
                   `Report Date`, `Call Date`, `Offense Date`, `Call Time`, \
                   `Call Date Time`, `Disposition`, `Address`, `City`, `State`, `Agency Id`, \
                   `Address Type`, `Common Location`)' 'VALUES("%d", "%s", "%s", "%s", "%s", "%s", \
                   "%s", "%s", "%s", "%s", "%d", "%s")', row)

    # close the connection to the database.
    cur.close()

    print ("Done")

db.close()


Ошибка
(Connection to DataBase established..

Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/MySQLdb/cursors.py", line 238, in execute
    query = query % args
TypeError: %d format: a number is required, not str

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/decoy/Projects/Python/sfpdBASE_insert.py", line 21, in <module>
    "%s", "%s", "%s", "%s", "%d", "%s")', row)
  File "/usr/lib/python3/dist-packages/MySQLdb/cursors.py", line 240, in execute
    self.errorhandler(self, ProgrammingError, str(m))
  File "/usr/lib/python3/dist-packages/MySQLdb/connections.py", line 52, in defaulterrorhandler
    raise errorclass(errorvalue)
_mysql_exceptions.ProgrammingError: %d format: a number is required, not str

Process finished with exit code 1)


.csv строка с которой ошибки нет:
160922294	Passing Call	2016-04-01T00:00:00	2016-04-01T00:00:00	2016-04-01T00:00:00	15:41	2016-04-01T15:41:00	HAN	Haight St Corridor		CA	1	Geo-Override


.CSV строка номер 238 на которую он ругается
160913103	Encampment	2016-03-31T00:00:00	2016-03-31T00:00:00	2016-03-31T00:00:00	18:57	2016-03-31T18:57:00	ADV	2700 Block Of Folsom St	San Francisco	CA	1	Premise Address
  • Вопрос задан
  • 1470 просмотров
Решения вопроса 1
sergey-gornostaev
@sergey-gornostaev Куратор тега Python
Седой и строгий
Во-первых, вы закрываете курсор после первой же итерации. Поэтому у вас вообще не должно обрабатываться больше одной строки. Во-вторых, можно завернуть проблемный код в обработчик исключений и убедиться, что числовое поле действительно содержит ожидаемое значение и не содержит нечисловых символов:

import MySQLdb
import csv

csv_file = '/home/decoy/Downloads/police-department-calls-for-service.csv'
db_props = {
    'host': '192.168.1.2',
    'port': 3306,
    'user': 'non-root-boy',
    'passwd': '123456',
    'db': 'sfpd'
}
query = ''''INSERT INTO sfpd(`Crime Id`, `Original Crime Type Name`,
                   `Report Date`, `Call Date`, `Offense Date`, `Call Time`,
                   `Call Date Time`, `Disposition`, `Address`, `City`, `State`, `Agency Id`,
                   `Address Type`, `Common Location`) VALUES("%d", "%s", "%s", "%s", "%s", "%s",
                   "%s", "%s", "%s", "%s", "%d", "%s")'''

with open(csv_file) as fh:
    csv_f = csv.reader(fh)
    with MySQLdb.connect(**db_props) as cur:
        for row in csv_f:
            try:
                cur.execute(query, row)
            except TypeError as exc:
                field_val = row[-2]
                if isinstance(field_val, str):
                    print(''.join(r'\x{0:02x}'.format(ord(c)) if c.isspace() or not c.isprintable() else c for c in field_val))
                else:
                    raise
print ("Done")

И, в-третьих, непонятно почему предпоследнее поле таблицы БД имеет тип varchar, а вставить вы пытаетесь число.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
vitovt
@vitovt
Их CSV можно напрямую в MySQL без каких либо скриптов, одним запросом
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы