使用python函数式编程将csv文件导入sqllite3

时间:2019-03-07 20:10:27

标签: python csv import sqlite

我知道还有其他帖子,但是我找不到我想到的具体问题。 我正在使用US_baby_names CSV文件。并希望将此csv文件逐行导入到sqlite3中作为表格。

我能够创建称为存储的表。 然后,我试图读取csv文件中的行并将其放入该表中,但是我必须做错了事。

import sqlite3 as sql
from sqlite3 import Error
import csv

def CreateConnection ( dbFileName ):
   try:
      conn = sql.connect(dbFileName)
      return conn
   except Error as e:
      print(e)

   return None

def CreateNew( dbConnection, new):
     sql =  """INSERT INTO storage (dat, Id, Name, Year, group, subgroup, Count)
        VALUES (?,?,?,?,?,?,?)"""

     try:
       cursor = dbConnection.cursor()
       cursor.execute(sql, new)
       return cursor.lastrowid
     except Error as e:
       print(e)

def Main():
  database = "storage.db"
  dbConnection = CreateConnection(database)

  with open('storage.csv', 'rb') as fin:
     dr = csv.DictReader(fin)
     to_db = [(i['dat'], i['Id'], i['Name'], i['Year'], i['group'], i['subgroup'], i['Count']) \
        for i in dr]

    cursor.executemany(CreateNew(sql, to_db))

    dbConnection.close()

if __name__ == "__main__":
  Main()

我相信我的cursor.executemany是错误的,但是我不知道该怎么办。

谢谢

1 个答案:

答案 0 :(得分:2)

您的大部分代码都差不多,但是:

  • cursor.execute(sql, new)中,您将new而不是sqlite3.execute()传递给sqlite3.executemany()(需要一个简单的SQL语句)。
  • 此外,CreateNew()的结果是整数lastrowid,然后将结果传递给executemany()
  • 您必须使用Connection.commit()将更改保存到数据库,并使用Connection.rollback()放弃更改。
  • 您必须以csv.DictReaderr模式将rt类的文件作为文本文件打开。
  • 最后,请记住,sqlite3.Connection是上下文管理器,因此您可以在with语句中使用它。

这应该是您想要的结果:

import sqlite3 as sql
from sqlite3 import Error
import csv


def create_table(conn):
    sql = "CREATE TABLE IF NOT EXISTS baby_names("\
        "dat TEXT,"\
        "Id INTEGER PRIMARY KEY,"\
        "Name TEXT NOT NULL,"\
        "Year INTEGER NOT NULL,"\
        "Gender TEXT NOT NULL,"\
        "State TEXT NOT NULL,"\
        "Count INTEGER)"

    conn.execute(sql)
    conn.execute("DELETE FROM baby_names")

def select_all(conn):
    for r in conn.execute("SELECT * FROM baby_names").fetchall():
        print(r)


def execute_sql_statement(conn, data):
    sql = "INSERT INTO baby_names "\
        "(dat, Id, Name, Year, Gender, State, Count) "\
        "VALUES (?,?,?,?,?,?,?)"

    try:
        cursor = conn.executemany(sql, data)
    except Error as e:
        print(e)
        conn.rollback()
        return None
    else:
        conn.commit()
        return cursor.lastrowid

def main():        
    with sql.connect('baby_names.db') as conn, open('US_Baby_Names_right.csv', 'r') as fin:
        create_table(conn)

        dr = csv.DictReader(fin)
        data = [(i['dat'], i['Id'], i['Name'], i['Year'], i['Gender'], i['State'], i['Count']) for i in dr ]

        lastrowid = execute_sql_statement(conn, data)

        select_all(conn)


main()

我添加了一个create_table()函数只是为了测试我的代码。我还制作了一个示例测试文件,如下所示:

dat,Id,Name,Year,Gender,State,Count
1,1,John,1998,M,Washington,2
2,2,Luke,2000,M,Arkansas,10
3,3,Carrie,1999,F,Texas,3

select_all()函数的输出为:

('1',1,'John',1998,'M','Washington',2)
('2',2,'Luke',2000,'M','Arkansas',10)
('3',3,'Carrie',1999,'F','Texas',3)