2016-05-24 8 views
2

Я написал следующий фрагмент для импорта CSV-файла в базу данных MS SQL Server но это дает мне ошибку. он основан на коде, написанном для Sqlite for Python и изменен для MSSQL.pyodbc.DataError: ('22018', "[22018] [Microsoft] [драйвер SQL-сервера ODBC] [Ошибка SQL Server] Ошибка конверсии] ошибка

import csv, pyodbc 
import logging 

def _get_col_datatypes(fin): 
    dr = csv.DictReader(fin) # comma is default delimiter 
    fieldTypes = {} 
    for entry in dr: 
     feildslLeft = [f for f in dr.fieldnames if f not in fieldTypes.keys()] 
     if not feildslLeft: break # We're done 
     for field in feildslLeft: 
      data = entry[field] 

      # Need data to decide 
      if len(data) == 0: 
       continue 

      if data.isdigit(): 
       fieldTypes[field] = "INTEGER" 
      else: 
       fieldTypes[field] = "TEXT" 
     # TODO: Currently there's no support for DATE in sqllite 

    if len(feildslLeft) > 0: 
     raise Exception("Failed to find all the columns data types - Maybe some are empty?") 

    return fieldTypes 


def escapingGenerator(f): 
    for line in f: 
     yield line.encode("ascii", "xmlcharrefreplace").decode("ascii") 


def csvToDb(csvFile, outputToFile = False): 
    # TODO: implement output to file 

    with open(csvFile,mode='r') as fin: 
     dt = _get_col_datatypes(fin) 

     fin.seek(0) 

     reader = csv.DictReader(fin) 

     # Keep the order of the columns name just as in the CSV 
     fields = reader.fieldnames 
     cols = [] 


     # Set field and type 
     for f in fields: 
      cols.append("%s %s" % (f, dt[f])) 

     # Generate create table statement: 
     stmt = "CREATE TABLE ads (%s)" % ",".join(cols) 

     con = pyodbc.connect('DRIVER={SQL Server};SERVER=localhost;DATABASE=sd;UID=Test;PWD=11') 
     cur = con.cursor() 
     cur.execute(stmt) 

     fin.seek(0) 


     reader = csv.reader(escapingGenerator(fin)) 

     # Generate insert statement: 
     stmt = "INSERT INTO ads VALUES(%s);" % ','.join('?' * len(cols)) 

     cur.executemany(stmt, reader) 
     con.commit() 

    return con 


csvToDb('Books.csv') 

ошибка я получаю

pyodbc.DataError: ('22018', "[22018] [Microsoft][ODBC SQL Server Driver][SQL Server]Conversion failed when converting the varchar value 'a' to data type int. (245) (SQLExecDirectW)")

Также предложите, если вы думаете, есть какие-либо другие методы динамического импорта CSV или текстовых файлов в базу данных MSSQL

ответ

1

Сообщение об ошибке

Conversion failed when converting the varchar value 'a' to data type int.

показывает, что ваш код может быть «обмануть», думая, что столбец является целым числом, когда это действительно текст, по-видимому, потому что он смотрит только на первом ряду данных. Тестирование показывает, что оба

ID,txt1,txt2,int1 
1,foo,123,3 
2,bar,abc,4 

и

"ID","txt1","txt2","int1" 
1,"foo","123",3 
2,"bar","abc",4 

результат в коде производства оператор CREATE TABLE:

CREATE TABLE ads (ID INTEGER,txt1 TEXT,txt2 INTEGER,int1 INTEGER) 

, который является неправильным, так как столбец [txt2] на самом деле не INTEGER.

Вы можете исследовать настройку вашего кода, чтобы посмотреть больше, чем первая строка данных. (Собственные процедуры импорта Microsoft часто по умолчанию используют первые восемь строк при попытке автоматического определения типов данных.) Вы также можете просто импортировать все столбцы в виде текста, а затем конвертировать их позже на SQL-сервере.

Однако, учитывая, что там должны быть сотни –, если не тысячи – примеров там для импорта данных в формате CSV для SQL Server, вы должны также рассмотреть возможность сделать более исчерпывающий поиск существующих (отлаженной) код, прежде чем продолжить инвестировать время и усилия в «развертывание собственного решения».

+0

Спасибо @gord thompson, но столбец, который получает ошибку, имеет только цифры без комбинации слов и цифр. – Zack

Смежные вопросы