【问题标题】:Using pandas to write df to sqlite使用 pandas 将 df 写入 sqlite
【发布时间】:2018-10-27 16:58:10
【问题描述】:

我正在尝试从 csv 文件创建一个 sqlite db。经过一番搜索,似乎可以使用 pandas df。我试过遵循一些教程和文档,但我无法弄清楚这个错误。这是我的代码:

# Import libraries
import pandas, csv, sqlite3

# Create sqlite database and cursor
conn = sqlite3.connect('test.db')
c = conn.cursor()
# Create the table of pitches
c.execute("""CREATE TABLE IF NOT EXISTS pitches (
            pitch_type text,
            game_date text,
            release_speed real
            )""")

conn.commit()

df = pandas.read_csv('test2.csv')
df.to_sql('pitches', conn, if_exists='append', index=False)

conn.close()

当我运行此代码时,我收到以下错误:

sqlite3.OperationalError: table pitches has no column named SL

SL 是我的 csv 文件第一行中的第一个值。我无法弄清楚为什么它将 csv 值视为列名,除非它认为 csv 的第一行应该是标题并试图将其与表中的列名匹配?我不认为是这样,因为我尝试将第一个值更改为实际的列名并得到相同的错误。

编辑:

当我在 csv 中有标题时,数据框如下所示:

     pitch_type  game_date  release_speed
0            SL  8/31/2017           81.9
1            SL  8/31/2017           84.1
2            SL  8/31/2017           81.9
...         ...        ...            ...
2919         SL   8/1/2017           82.3
2920         CU   8/1/2017           78.7

[2921 rows x 3 columns]

我收到以下错误:

sqlite3.OperationalError: table pitches has no column named game_date

当我从 csv 文件中取出标题时:

      SL  8/31/2017  81.9
0     SL  8/31/2017  84.1
1     SL  8/31/2017  81.9
2     SL  8/31/2017  84.1
...   ..        ...   ...
2918  SL   8/1/2017  82.3
2919  CU   8/1/2017  78.7

[2920 rows x 3 columns]

我收到以下错误:

sqlite3.OperationalError: table pitches has no column named SL

编辑#2:

根据this answer,我尝试使用以下代码完全从代码中创建表:

# Import libraries
import pandas, csv, sqlite3

# Create sqlite database and cursor
conn = sqlite3.connect('test.db')
c = conn.cursor()

df = pandas.read_csv('test2.csv')
df.to_sql('pitches', conn, if_exists='append', index=False)

conn.close()

仍然得到

sqlite3.OperationalError: table pitches has no column named SL

错误

编辑#3:

我将建表代码改成如下:

# Create the table of pitches
dropTable = 'DROP TABLE pitches'
c.execute(dropTable)
createTable = "CREATE TABLE IF NOT EXISTS pitches(pitch_type text, game_date text, release_speed real)"
c.execute(createTable)

它现在可以工作了。不知道到底发生了什么变化,因为它在我看来基本相同,但它确实有效。

【问题讨论】:

  • 你能发布你的数据框的样子吗?在 csv 文件中分配列名后,您肯定会遇到不同的错误。
  • 使用请求的信息进行编辑。

标签: python pandas sqlite


【解决方案1】:

检查您的列名。我能够成功复制您的代码而没有错误。 names 变量从sqlite 表中获取所有列名,您可以将它们与带有df.columns 的数据帧标题进行比较。

# Import libraries
import pandas as pd, csv, sqlite3

# Create sqlite database and cursor
conn = sqlite3.connect('test.db')
c = conn.cursor()
# Create the table of pitches
c.execute("""CREATE TABLE IF NOT EXISTS pitches (
            pitch_type text,
            game_date text,
            release_speed real
            )""")
conn.commit()

test = conn.execute('SELECT * from pitches')
names = [description[0] for description in test.description]
print(names)

df = pd.DataFrame([['SL','8/31/2017','81.9']],columns = ['pitch_type','game_date','release_speed'])
df.to_sql('pitches', conn, if_exists='append', index=False)

conn.execute('SELECT * from pitches').fetchall()
>> [('SL', '8/31/2017', 81.9), ('SL', '8/31/2017', 81.9)]

我猜你的列标题中可能有一些空格。

【讨论】:

  • 当这是表中的第二列时,错误显示“没有名为 game_date 的列”对我来说也很奇怪。我不知道为什么它会跳过 pitch_type 列,或者认为它没问题。
  • 使用您的答案,我发现当我在代码的第 17 行 print(names) 时,它只显示 ['pitch_type'],所以我创建表格的语法一定有问题。我不知道是什么。
  • 你的其他栏目有编号吗?您需要为所有这些分配列标题。在这种情况下,to_sql 根据数据框中的列名分配列值。
  • 我更改了表创建代码(将其添加到原始帖子中的编辑#3),它现在可以工作了。不确定初始代码中出了什么问题。感谢您的帮助。
  • 我在使用df.to_sql('table_name',engine,index=False, if_exists='append') 时收到了与 sqlite3 类似的错误消息,在我的情况下,我的 pandas 数据框 df 有一些 多级索引。放下它们后,它工作正常。
【解决方案2】:

如果您尝试从 csv 文件创建表,您可以运行 sqlite3 并执行以下操作:

sqlite> .mode csv
sqlite> .import c:/path/to/file/myfile.csv myTableName

【讨论】:

    【解决方案3】:

    正如您在 pandas read_csv docs 中看到的那样:

    header : int or list of ints, default 'infer'
        Row number(s) to use as the column names, and the start of the
        data.  Default behavior is to infer the column names: if no names
        are passed the behavior is identical to ``header=0`` and column
        names are inferred from the first line of the file, if column
        names are passed explicitly then the behavior is identical to
        ``header=None``. Explicitly pass ``header=0`` to be able to
        replace existing names. The header can be a list of integers that
        specify row locations for a multi-index on the columns
        e.g. [0,1,3]. Intervening rows that are not specified will be
        skipped (e.g. 2 in this example is skipped). Note that this
        parameter ignores commented lines and empty lines if
        ``skip_blank_lines=True``, so header=0 denotes the first line of
        data rather than the first line of the file.
    

    这意味着 read_csv 使用您的第一行作为标题名称。

    【讨论】:

      猜你喜欢
      • 2023-03-13
      • 2017-03-30
      • 1970-01-01
      • 2021-01-25
      • 1970-01-01
      • 2018-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多