【问题标题】:Import CSV file into SQL Server using Python使用 Python 将 CSV 文件导入 SQL Server
【发布时间】:2017-02-15 09:09:17
【问题描述】:

我在将 CSV 文件上传到 MS SQL Server 中的表时遇到问题,CSV 文件有 25 列,并且标题与 SQL 中的表同名,SQL 中的表也有 25 列。当我运行脚本时,它会引发错误

params arg (<class 'list'>) can be only a tuple or a dictionary

将此数据导入 MS SQL 的最佳方法是什么? CSV 和 SQL 表都具有完全相同的列名。

代码如下:

import csv
import pymssql

conn = pymssql.connect(
    server="xx.xxx.xx.90",
    port = 2433,
    user='SQLAdmin',
    password='xxxxxxxx',
    database='NasrWeb'
)

cursor = conn.cursor()
customer_data = csv.reader('cleanNVG.csv') #25 columns with same header as SQL

for row in customer_data:
    cursor.execute('INSERT INTO zzzOracle_Extract([Customer Name]\
      ,[Customer #]\
      ,[Account Name]\
      ,[Identifying Address Flag]\
      ,[Address1]\
      ,[Address2]\
      ,[Address3]\
      ,[Address4]\
      ,[City]\
      ,[County]\
      ,[State]\
      ,[Postal Code]\
      ,[Country]\
      ,[Category ]\
      ,[Class]\
      ,[Reference]\
      ,[Party Status]\
      ,[Address Status]\
      ,[Site Status]\
      ,[Ship To or Bill To]\
      ,[Default Warehouse]\
      ,[Default Order Type]\
      ,[Default Shipping Method]\
      ,[Optifacts Customer Number]\
      ,[Salesperson])''VALUES(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,)',row)

conn.commit()
cursor.close()
print("Done")
conn.close()

这是 CSV 文件的第一行的样子

【问题讨论】:

  • 能否显示 CSV 文件的第一行(或第一行的第一列...),以便我们查看它的样子?
  • 刚刚截取了数据的样子。 @SergeBallesta
  • 您应该复制CSV的文本,而不是截取Excel的屏幕截图,这样会删除文件的分隔符

标签: python python-3.x pymssql


【解决方案1】:

试试d6tstack,它有fast pandas to SQL functionality,因为它使用本机数据库导入命令。它适用于 Postgres 和 MYSQL,MS SQL 是实验性的。如果不起作用,请发表评论或提出问题。

import pandas as pd
df = pd.read_csv('cleanNVG.csv')
uri_mssql = 'mssql+pymssql://usr:pwd@localhost/db'
d6tstack.utils.pd_to_mssql(df, uri_mssql, 'table', 'schema') # experimental

这对于在写入 db 之前导入具有数据架构更改和/或使用 pandas 进行预处理的多个 CSV 也很有用,请参阅examples notebook 中的进一步内容

d6tstack.combine_csv.CombinerCSV(glob.glob('*.csv'), 
    apply_after_read=apply_fun).to_mssql_combine(uri_psql, 'table')

【讨论】:

    【解决方案2】:

    您错误地使用了csv.reader.reader 的第一个参数不是 CSV 文件的路径,而是

    [an] 对象,它支持迭代器协议并在每次调用其__next__() 方法时返回一个字符串——文件对象和列表对象都适用。

    因此,根据documentation 中的示例,您应该这样做:

    import csv
    with open('cleanNVG.csv', newline='') as csvfile:
        customer_data = csv.reader(csvfile)
        for row in customer_data:
            cursor.execute(sql, tuple(row))
    

    【讨论】:

    • 感谢您对 pyodbc/pandas 和 ms sql 的所有回答 - 我自己也遇到了问题,您的回答非常棒。
    【解决方案3】:

    检查表格上的数据类型,以及每个字段的大小。如果是 varchar(10) 并且你的数据长度是 20 个字符,它会抛出一个错误。

    还有,

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

    以下示例假设

    CSV file contains column names in the first line
    Connection is already built
    File name is test.csv
    Table name is MyTable
    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 dbo.Test 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()
    

    不过,基本上,您的代码看起来不错。这是一个通用示例。

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

    【讨论】:

      猜你喜欢
      • 2018-10-19
      • 1970-01-01
      • 2013-02-20
      • 2020-05-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多