【问题标题】:Import .csv to SQL将 .csv 导入 SQL
【发布时间】:2015-07-07 12:22:33
【问题描述】:

我正在尝试使用 CSV 来使用 Python 填充 34 列 SQL 数据库,尽管我不能。

import csv sqlite3
con = sqlite3.connect(":memory:")
cur = con.cursor()

cur.execute("CREATE TABLE t (No, Source, Host, Link, Date, Time, time2, Category, AuthorId, AuthorName, AuthorUrl, Auth, Followers, Following, Age, Gender, Language, Country, Province, City, Location, Sentiment, Title, Snippet, Description, Tags, Contents, View, Comments, Rating, Favourites, Duration, Bio, UniqueId);")}

with open('database.csv', 'rb') as fin:
    dr = csv.reader(fin) 
    dicts = ({'No': line[0], 'Source': line[1], 'Host': line[2], 'Link': line[3], 'Date': line[4], 'Time': line[5], 'time2': line[6], 'Category': line[7], 'AuthorId': line[8], 'AuthorName': line[9], 'AuthorUrl': line[10], 'Auth': line[11], 'Followers': line[12], 'Following': line[13], 'Age': line[14], 'Gender': line[15], 'Language': line[16], 'Country': line[17], 'Province': line[18], 'City': line[19], 'Location': line[20], 'Sentiment': line[21], 'Title': line[22], 'Snippet': line[23], 'Description': line[24], 'Tags': line[25], 'Contents': line[26], 'View': line[27], 'Comments': line[28], 'Rating': line[29], 'Favourites': line[30], 'Duration': line[31], 'Following': line[32], 'UniqueId': line[33]} for line in dr)
    to_db = ((i['No'], i['Source'], i['Host'], i['Link'], i['Date'], i['Time'], i['time2'], i['Category'], i['AuthorId'], i['AuthorName'], i['AuthorUrl'], i['Auth'], i['Followers'], i['Following'], i['Age'], i['Gender'], i['Language'], i['Country'], i['Province'], i['City'], i['Location'], i['Sentiment'], i['Title'], i['Snippet'], i['Description'], i['Tags'], i['Contents'], i['View'], i['Comments'], i['Rating'], i['Favourites'], i['Duration'], i['Bio'], i['UniqueId']) for i in dicts)

cur.executemany("INSERT INTO t VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", to_db)
con.commit()

我一直在关注许多迹象,虽然这是我第一次pythoning,但我不知道该怎么做。

你能帮我解决这个问题吗?非常感谢。

Pd:如果无法推断,则 csv 文件没有标题,我正在尝试一次逐列填充。

【问题讨论】:

  • 哪里出了问题?您能否提供一个输入数据的简单示例,以便我们了解您面临的问题?你的代码看起来很乱,一张表有 34 列似乎很多:)
  • 顺便说一句,如果您需要在导入这些数据时应用一些逻辑,那么 Python 是完美的,但如果您只需要原始导入,那么许多 DBMS 开箱即用地支持此功能。 stackoverflow.com/questions/2987433/…

标签: python sql csv


【解决方案1】:

如果 CSV 元素的位置正确,你能不能做一些更直接的事情,即作为以下数据的示例

1,2,3
a,b,c

使用以下内容;

import sqlite3
con = sqlite3.connect(":memory:")
cur = con.cursor()

cur.execute("CREATE TABLE t (col1,col2,col3);")

with open('database.csv', 'rb') as fp:
    for line in fp.readlines():
        cur.execute("INSERT INTO t VALUES (?, ?, ?)",line.strip().split(','))
con.commit()

for row in cur.execute("select * from t;"):
    print row

【讨论】:

    【解决方案2】:

    这行得通。我使用了一些捷径来节省打字时间。

    import csv
    import sqlite3
    import itertools
    
    params = ['No', 'Source', 'Host', 'Link', 'Date', 'Time', 'time2', 'Category', 'AuthorId', 'AuthorName', 'AuthorUrl', 'Auth', 'Followers', 'Following', 'Age', 'Gender', 'Language', 'Country', 'Province', 'City', 'Location', 'Sentiment', 'Title', 'Snippet', 'Description', 'Tags', 'Contents', 'View', 'Comments', 'Rating', 'Favourites', 'Duration', 'Bio', 'UniqueId']
    
    create_str = "CREATE TABLE t (%s);" % ', '.join('"%s"' % p for p in params)
    insert_str = "INSERT INTO t VALUES (%s)" % ', '.join(itertools.repeat('?', len(params)))
    
    with open('database.csv') as fin:
        dr = csv.DictReader(fin, fieldnames=params, skipinitialspace=True)
        lst = [tuple(d[p] for p in params) for d in dr]
    
    con = sqlite3.connect(":memory:")
    cur = con.cursor()
    cur.execute(create_str)
    
    cur.executemany(insert_str, lst)
    con.commit()
    
    for row in cur.execute("select * from t;"):
        print(row)
    

    请注意使用字符串格式操作来构建 sql 查询字符串的不良做法。如果与未知的输入数据一起使用,它可能会导致 sql 注入攻击。我在这里这样做是因为字符串仅是从已知值构建的,而未知输入(来自文件的输入)是使用标准“?”正确构建的。带有元组的占位符传递给execute 方法。

    请注意,一张表中的参数太多了。它应该在多个表中更加规范化,但我想你会在某个时候了解到这一点。

    【讨论】:

    • 比你好多了,我试图找出为什么在使用你的代码后,会出现这个错误:“你不能使用 8 位字节串,除非你使用可以解释 8 位字节串的 text_factory (如 text_factory = str)。强烈建议您将应用程序切换为 Unicode 字符串。”
    • 简单的答案是不要以二进制模式打开文件。我调整了答案。这只是 python 3 中的一个问题。
    猜你喜欢
    • 2011-07-04
    • 1970-01-01
    • 1970-01-01
    • 2021-02-04
    • 2012-04-05
    • 2012-12-24
    • 1970-01-01
    • 2013-02-20
    • 2014-10-29
    相关资源
    最近更新 更多