我一直在查看 pandas 的 Pandas 文档和 Pandas 源代码,以尽可能最快的方式将大型 CSV 表传递到我的 PostgreSQL 数据库中。
使用 pandas.DataFrame.to_sql 使用可调用方法“psql_insert_copy”似乎是迄今为止最好的解决方案。 但我不明白它是如何工作的,老实说,我看了几篇文章,我发现这个方法“table、conn、keys 和 data_iter”的参数模式是固定的。我问桌子如何与其他人这篇文章和这个人一起拿走“钥匙”。
是否可以传递此方法,或创建另一个方法来传递列名?所以我可以在同一个可调用方法中重命名列?这是因为有些column_names不是我所期望的,仅此更改将简化我的代码。 (我还想了解更多关于如何自定义我的可调用及其工作原理的信息)。
您可以使用此代码示例:
# STEP 0: Call libraries
# STEP 1:
# Setup the connection db engine
import csv
from io import StringIO
from sqlalchemy import create_engine
# STEP 2: Create the callable function/method
# Alternative to_sql() *method* for DBs that support COPY FROM
import csv
from io import StringIO
def psql_insert_copy(table, conn, keys, data_iter):
"""
Execute SQL statement inserting data
Parameters
----------
table : pandas.io.sql.SQLTable
conn : sqlalchemy.engine.Engine or sqlalchemy.engine.Connection
keys : list of str
Column names
data_iter : Iterable that iterates the values to be inserted
"""
# gets a DBAPI connection that can provide a cursor
dbapi_conn = conn.connection
with dbapi_conn.cursor() as cur:
s_buf = StringIO()
writer = csv.writer(s_buf)
writer.writerows(data_iter)
s_buf.seek(0)
columns = ', '.join(['"{}"'.format(k) for k in keys])
if table.schema:
table_name = '{}.{}'.format(table.schema, table.name)
else:
table_name = table.name
sql = 'COPY {} ({}) FROM STDIN WITH CSV'.format(
table_name, columns)
cur.copy_expert(sql=sql, file=s_buf)
## STEP 3 : Create the db connection (in my case I installed postgresql and connect to it
engine = create_engine('postgresql://myusername:mypassword@myhost:5432/mydatabase')
## STEP 4: Read my table "dummycsv.csv" from my project root folder
df = pd.read_csv("dummycsv.csv")
## STEP 5: Pass this dummycsv data frame to the function "to_sql" with the argument, callable method. AND THE NEW COLUMNNAMES!
df.to_sql(name='dummycsv', schema='test', con=engine,if_exists="replace", index=False, method=psql_insert_copy)
我尝试在最后一个函数中添加一个额外的参数:
def psql_insert_copy(table, conn, keys, data_iter, colsrenamed)
# ...
df.to_sql(name='dummycsv', schema='test', con=engine,if_exists="replace", index=False, method=psql_insert_copy, colsrenamed = listofstringswithnewnames)
注意: 另外,由于这项研究花了我很多时间,所以我考虑了:
df.rename(columns=dictionary_with_oldnames_and_newnames, inplace=True)
重命名数据帧的列来更改“keys”参数(与psql_insert_copy
但这两种方法有点问题,需要更多的提交选项,更多的步骤可能会导致我的管道中的进程更加不同步。