Запись CSV-файла в базу данных SQL Server с использованием Python

Я пытаюсь записать файл csv в таблицу в базе данных SQL Server с помощью python. Я сталкиваюсь с ошибками, когда передаю параметры, но я не сталкиваюсь с ошибками, когда делаю это вручную. Вот код, который я выполняю.

cur=cnxn.cursor() # Get the cursor
csv_data = csv.reader(file(Samplefile.csv')) # Read the csv
for rows in csv_data: # Iterate through csv
    cur.execute("INSERT INTO MyTable(Col1,Col2,Col3,Col4) VALUES (?,?,?,?)",rows)
cnxn.commit()

Ошибка:

pyodbc.DataError: ('22001', '[22001] [Microsoft] [Драйвер ODBC SQL Server] [SQL Server] Строка или двоичные данные будут усечены. (8152) (SQLExecDirectW); [01000] [Microsoft] [ODBC SQL Драйвер сервера] [SQL Server] Оператор прерван. (3621) ')

Однако когда я вставляю значения вручную. Отлично работает

cur.execute("INSERT INTO MyTable(Col1,Col2,Col3,Col4) VALUES (?,?,?,?)",'A','B','C','D')

Я убедился, что ТАБЛИЦА есть в базе данных, типы данных соответствуют данным, которые я передаю. Подключение и курсор тоже правильные. Тип данных строк - список


person NG_21    schedule 21.01.2014    source источник
comment
Содержит ли ваш CSV-файл имена столбцов в первой строке?   -  person Bryan    schedule 21.01.2014


Ответы (6)


Рассмотрите возможность создания запроса динамически, чтобы количество заполнителей соответствовало вашей таблице и формату файла CSV. Тогда вам просто нужно убедиться, что ваша таблица и CSV-файл верны, а не проверять, набрано ли достаточно ? заполнителей в свой код.

В следующем примере предполагается

  1. CSV-файл содержит имена столбцов в первой строке
  2. Подключение уже установлено
  3. Имя файла test.csv
  4. Имя таблицы MyTable
  5. Python 3
...
with open ('test.csv', 'r') as f:
    reader = csv.reader(f)
    columns = next(reader) 
    query = 'insert into MyTable({0}) values ({1})'
    query = query.format(','.join(columns), ','.join('?' * len(columns)))
    cursor = connection.cursor()
    for data in reader:
        cursor.execute(query, data)
    cursor.commit()

Если имена столбцов не включены в файл:

...
with open ('test.csv', 'r') as f:
    reader = csv.reader(f)
    data = next(reader) 
    query = 'insert into MyTable values ({0})'
    query = query.format(','.join('?' * len(data)))
    cursor = connection.cursor()
    cursor.execute(query, data)
    for data in reader:
        cursor.execute(query, data)
    cursor.commit()
person Bryan    schedule 21.01.2014

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

def upload_table(path, filename, delim, cursor):
    """
    Function to upload flat file to sqlserver
    """
    tbl = filename.split('.')[0]
    cnt = 0
    with open (path + filename, 'r') as f:
        reader = csv.reader(f, delimiter=delim)
        for row in reader:
            row.pop() # can be commented out
            row = ['NULL' if val == '' else val for val in row]
            row = [x.replace("'", "''") for x in row]
            out = "'" + "', '".join(str(item) for item in row) + "'"
            out = out.replace("'NULL'", 'NULL')
            query = "INSERT INTO " + tbl + " VALUES (" + out + ")"
            cursor.execute(query)
            cnt = cnt + 1
            if cnt % 10000 == 0:
                cursor.commit()
        cursor.commit()
    print("Uploaded " + str(cnt) + " rows into table " + tbl + ".")
person Indrajit    schedule 02.11.2019

Вы можете передавать столбцы в качестве аргументов. Например:

for rows in csv_data: # Iterate through csv
    cur.execute("INSERT INTO MyTable(Col1,Col2,Col3,Col4) VALUES (?,?,?,?)", *rows)
person arocks    schedule 21.01.2014

Я разобрался. Ошибка возникла из-за ограничения размера таблицы. Он изменил емкость столбца, например, с col1 varchar (10) на col1 varchar (35) и т. Д. Теперь он работает нормально.

person NG_21    schedule 22.01.2014

Если вы используете MySqlHook в воздушном потоке, если cursor.execute () с параметрами выдает ошибку san

TypeError: не все аргументы преобразуются во время форматирования строки

используйте %s вместо ?

with open('/usr/local/airflow/files/ifsc_details.csv','r') as csv_file:
    csv_reader = csv.reader(csv_file)
    columns = next(csv_reader)
    query = '''insert into ifsc_details({0}) values({1});'''
    query = query.format(','.join(columns), ','.join(['%s'] * len(columns)))
    mysql = MySqlHook(mysql_conn_id='local_mysql')
    conn = mysql.get_conn()
    cursor = conn.cursor()
    for data in csv_reader:
        cursor.execute(query, data)
    cursor.commit()
person Prashant Joshi    schedule 08.04.2021

Вы также можете импортировать данные в SQL, используя:

  • Мастер импорта и экспорта SQL Server
  • Службы интеграции SQL Server (SSIS)
  • Функция OPENROWSET

Более подробную информацию можно найти на этой веб-странице: https://docs.microsoft.com/en-us/sql/relational-databases/import-export/import-data-from-excel-to-sql?view=sql-server-2017

person B. Latif    schedule 11.03.2019