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
  • Вопрос задан
  • 114 просмотров
Решения вопроса 1
sergey-gornostaev
@sergey-gornostaev
Седой и строгий
Во-первых, вы закрываете курсор после первой же итерации. Поэтому у вас вообще не должно обрабатываться больше одной строки. Во-вторых, можно завернуть проблемный код в обработчик исключений и убедиться, что числовое поле действительно содержит ожидаемое значение и не содержит нечисловых символов:

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 без каких либо скриптов, одним запросом
Ответ написан
Ваш ответ на вопрос

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

Войти через TM ID
Похожие вопросы
от 120 000 руб.
áxmit Петрозаводск
от 60 000 до 120 000 руб.
SaveTime Москва
от 140 000 до 200 000 руб.