Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用python将csv文件写入SQL Server数据库_Python_Sql Server_Csv_Pyodbc - Fatal编程技术网

使用python将csv文件写入SQL Server数据库

使用python将csv文件写入SQL Server数据库,python,sql-server,csv,pyodbc,Python,Sql Server,Csv,Pyodbc,我正在尝试使用python将csv文件写入SQLServer数据库中的表中。当我传递参数时,我会遇到错误,但是当我手动传递参数时,我不会遇到任何错误。这是我正在执行的代码 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("INS

我正在尝试使用python将csv文件写入SQLServer数据库中的表中。当我传递参数时,我会遇到错误,但是当我手动传递参数时,我不会遇到任何错误。这是我正在执行的代码

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 Server驱动程序][SQL Server]语句已终止。(3621)]

但是,当我手动插入值时。它很好用

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

我已经确保表在数据库中,数据类型与我传递的数据一致。连接和光标也正确。行的数据类型为“list”

您可以将列作为参数传递。例如:

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

考虑动态构建查询,以确保占位符的数量与表和CSV文件格式匹配。然后,只需确保表和CSV文件是正确的,而不是检查代码中是否输入了足够的
占位符

下面的示例假设

  • CSV文件在第一行中包含列名
  • 连接已经建立
  • 文件名为
    test.csv
  • 表名为
    MyTable
  • Python 3
  • 如果文件中未包含列名:

    ...
    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()
    

    我把它整理好了。该错误是由于表的大小限制造成的。它将列容量从col1 varchar(10)更改为col1 varchar(35)等。现在它工作正常。

    您还可以使用以下任一方法将数据导入SQL:

    • SQL Server导入和导出向导
    • SQL Server集成服务(SSIS)
    • OPENROWSET函数
    更多详细信息可在此网页上找到:
    我修改了Brian上面写的代码,如下所示,因为上面发布的代码无法处理我试图上传的分隔文件。行
    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 + ".")
    

    如果您在airflow中使用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()
    

    您的csv文件是否在第一行包含列名?
    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()