csv 在Pandas中传递 Dataframe 到SQL时,如何检查记录是否存在?

qyuhtwio  于 2023-01-15  发布在  其他
关注(0)|答案(4)|浏览(127)

背景

我正在构建一个将数据从CSV传递到MS SQL数据库的应用程序。该数据库被用作我的企业中所有此类记录(电话)的存储库。当我运行该应用程序时,它读取CSV并将其转换为Pandas Dataframe ,然后我使用SQLAlchemy和pyodbc将记录附加到SQL表中。
然而,由于我所处理的内容的性质,经常会有数据已经导入到表中。我正在寻找一种方法,在将每条记录添加到表中之前,检查我的主键是否存在(SQL表和 Dataframe 中的一列)。

当前代码

# save dataframe to mssql DB engine = sql.create_engine('mssql+pyodbc://CTR-HV-DEVSQL3/MasterCallDb') df.to_sql('Calls', engine, if_exists='append')

样品数据

我的CSV被导入为Pandas Dataframe (主键是FileName,它总是唯一的),然后传递到MS SQL。

+---+------------+-------------+
|   |  FileName  |    Name     |
+---+------------+-------------+
| 1 | 123.flac   | Robert      |
| 2 | 456.flac   | Michael     |
| 3 | 789.flac   | Joesph      |
+---+------------+-------------+

有什么主意吗?谢谢!

8yoxcaq7

8yoxcaq71#

假设您没有内存约束,也没有插入空值,则可以:

sql = "SELECT pk_1, pk_2, pk_3 FROM my_table"
sql_df = pd.read_sql(sql=sql, con=con)
df = pd.concat((df, sql_df)).drop_duplicates(subset=['pk_1', 'pk_2', 'pk_3'], keep=False)
df = df.dropna()
df.to_sql('my_table', con=con, if_exists='append')

根据应用程序的不同,您还可以通过更改查询来减小sql_df的大小。

更新-整体更好,可以插入空值:

sql = "SELECT pk_1, pk_2, pk_3 FROM my_table"
sql_df = pd.read_sql(sql=sql, con=con)
df = df.loc[df[pks].merge(sql_df[pks], on=pks, how='left', indicator=True)['_merge'] == 'left_only']
# df = df.drop_duplicates(subset=pks) # add it if you want to drop any duplicates that you may insert
df.to_sql('my_table', con=con, if_exists='append')
sdnqo3pr

sdnqo3pr2#

如果您遍历行DataFrame.iterrows(),然后在每次迭代中使用ON DUPLICATE作为键值FileName以避免再次添加它,该怎么办?

weylhg0b

weylhg0b3#

您可以检查是否为空,如下所示:

sql = "SELECT pk_1, pk_2, pk_3 FROM my_table"
sql_df = pd.read_sql(sql=sql, con=con)
    
if sql_df.empty:
    print("Is empty")
else:
     print("Is not empty")
nc1teljy

nc1teljy4#

您可以设置参数index=False参见下面的示例

data.to_sql('book_details', con = engine, if_exists = 'append', chunksize = 1000, index=False)**

如果未设置,则命令会自动添加index
book_details是我们要插入 Dataframe 的表的名称。
结果

[SQL: INSERT INTO book_details (`index`, book_id, title, price) VALUES (%(index)s, %(book_id)s, %(title)s, %(price)s)]
[parameters: ({'index': 0, 'book_id': 55, 'title': 'Programming', 'price': 29},
{'index': 1, 'book_id': 66, 'title': 'Learn', 'price': 23},
{'index': 2, 'book_id': 77, 'title': 'Data Science', 'price': 27})]

因此,它需要在表中!!!

相关问题