【问题标题】:Importing a csv file to sqllite3 using python functional programming使用python函数式编程将csv文件导入sqllite3
【发布时间】:2019-03-07 20:10:27
【问题描述】:

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

我能够创建名为 storage 的表。 然后我试图读取 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 是错误的,但我不知道还能做什么..

谢谢

【问题讨论】:

  • 使用函数打开数据库连接并返回连接是个坏主意。使用上下文管理器。您将一个执行数据库事务的函数传递给 executemany,这根本不起作用

标签: python csv import sqlite


【解决方案1】:

您的大部分代码几乎是正确的,但是:

  • cursor.execute(sql, new) 中,您将一个可迭代的new 传递给sqlite3.execute()(这需要一个简单的SQL 语句),而不是sqlite3.executemany()
  • 此外,CreateNew() 的结果是一个整数,lastrowid,你将这个结果传递给executemany()
  • 您必须使用Connection.commit() 将更改保存到数据库,并使用Connection.rollback() 丢弃它们。
  • 您必须以rrt 模式将csv.DictReader 类的文件作为文本文件 打开。
  • 最后,请记住 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,约翰,1998,M,华盛顿,2 2,2,卢克,2000,M,阿肯色,10 3,3,嘉莉,1999,F,德州,3

select_all() 函数的输出是:

('1',1,'约翰',1998,'M','华盛顿',2) ('2',2,'卢克',2000,'M','阿肯色',10) ('3',3,'嘉莉',1999,'F','德州',3)

【讨论】:

  • 谢谢,您的 cmets 让我很容易看到我的错误!我真的很感激
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-02-19
  • 2017-02-15
  • 2018-10-19
  • 2019-02-13
  • 2011-02-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多