在附加到数据库之前循环遍历数据框并检查行
Looping trough dataframe and checking rows before appending to database
问题如何将我的数据框附加到数据库,以便它检查 stock_ticker 是否存在,只附加 stock_ticker 不存在的行?
这是我做的过程
- 将 CSV 文件导入 pandas 数据框
- 指定与数据库中相同的列名
- 使用下面的代码将数据帧发送到数据库但得到
sqlite3.IntegrityError: UNIQUE constraint failed: stocks.stock_ticker
conn = sqlite3.connect('stockmarket.db')
c = conn.cursor()
df.to_sql(name='stocks', con=conn, if_exists='append', index=False)
conn.commit()
我查看了其他完整性错误案例,但似乎找不到适用于附加数据帧的案例?我发现并尝试了这个,但它所做的只是不附加任何内容。
try:
conn = sqlite3.connect('stockmarket.db')
c = conn.cursor()
df.to_sql(name='stocks', con=conn, if_exists='append', index=False)
conn.commit()
except sqlite3.IntegrityError:
print("Already in database")
我不确定我是否正确理解迭代的东西
How to iterate over rows in a DataFrame in Pandas
所以我尝试了这个,但它只是在数据库中为每个人打印了出来。即使艰难,也有 4 个新的股票代码。
for index, row in df.iterrows():
try:
conn = sqlite3.connect('stockmarket.db')
c = conn.cursor()
df.to_sql(name='stocks', con=conn, if_exists='append', index=False)
conn.commit()
except sqlite3.IntegrityError:
print("Already in database")
数据库看起来像这样
非常感谢任何见解:)
看起来发生这种情况是因为 Pandas 不允许声明适当的 ON CONFLICT
策略,以防您尝试将数据附加到具有相同 ( unique) primary key 或违反其他一些 UNIQUEness 约束。 if_exists
仅指整个 table 本身,而不是每一行。
我想你已经想出了一个很好的答案,也许稍加修改就可以了:
# After connecting
for i in range(len(df)):
try:
df[df.index == i].to_sql(name='stocks', con=conn, if_exists='append', index=False)
conn.commit()
except sqlite3.IntegrityError:
pass
现在,如果您的 Pandas 数据中出现了一个较新的值,并且您想要替换数据库中的旧值,那么这可能是一个问题。在这种情况下,您可能希望将原始 SQL 命令用作字符串,并迭代传递 Pandas 值。例如:
insert_statement = """
INSERT INTO stocks (stock_id,
stock_ticker,
{other columns})
VALUES (%s, %s, {as many %s as columns})
ON CONFLICT (stock_id) DO UPDATE
SET {Define which values you will update on conflict}"""
然后你可以运行
for i in range(len(df)):
values = tuple(df.iloc[i])
cursor.execute(insert_statement, values)
问题如何将我的数据框附加到数据库,以便它检查 stock_ticker 是否存在,只附加 stock_ticker 不存在的行?
这是我做的过程
- 将 CSV 文件导入 pandas 数据框
- 指定与数据库中相同的列名
- 使用下面的代码将数据帧发送到数据库但得到
sqlite3.IntegrityError: UNIQUE constraint failed: stocks.stock_ticker
conn = sqlite3.connect('stockmarket.db')
c = conn.cursor()
df.to_sql(name='stocks', con=conn, if_exists='append', index=False)
conn.commit()
我查看了其他完整性错误案例,但似乎找不到适用于附加数据帧的案例?我发现并尝试了这个,但它所做的只是不附加任何内容。
try:
conn = sqlite3.connect('stockmarket.db')
c = conn.cursor()
df.to_sql(name='stocks', con=conn, if_exists='append', index=False)
conn.commit()
except sqlite3.IntegrityError:
print("Already in database")
我不确定我是否正确理解迭代的东西
How to iterate over rows in a DataFrame in Pandas
所以我尝试了这个,但它只是在数据库中为每个人打印了出来。即使艰难,也有 4 个新的股票代码。
for index, row in df.iterrows():
try:
conn = sqlite3.connect('stockmarket.db')
c = conn.cursor()
df.to_sql(name='stocks', con=conn, if_exists='append', index=False)
conn.commit()
except sqlite3.IntegrityError:
print("Already in database")
数据库看起来像这样
非常感谢任何见解:)
看起来发生这种情况是因为 Pandas 不允许声明适当的 ON CONFLICT
策略,以防您尝试将数据附加到具有相同 ( unique) primary key 或违反其他一些 UNIQUEness 约束。 if_exists
仅指整个 table 本身,而不是每一行。
我想你已经想出了一个很好的答案,也许稍加修改就可以了:
# After connecting
for i in range(len(df)):
try:
df[df.index == i].to_sql(name='stocks', con=conn, if_exists='append', index=False)
conn.commit()
except sqlite3.IntegrityError:
pass
现在,如果您的 Pandas 数据中出现了一个较新的值,并且您想要替换数据库中的旧值,那么这可能是一个问题。在这种情况下,您可能希望将原始 SQL 命令用作字符串,并迭代传递 Pandas 值。例如:
insert_statement = """
INSERT INTO stocks (stock_id,
stock_ticker,
{other columns})
VALUES (%s, %s, {as many %s as columns})
ON CONFLICT (stock_id) DO UPDATE
SET {Define which values you will update on conflict}"""
然后你可以运行
for i in range(len(df)):
values = tuple(df.iloc[i])
cursor.execute(insert_statement, values)