INSERT INTO SELECT 基于数据帧
INSERT INTO SELECT based on a dataframe
我有一个数据框 df,我想执行一个查询以将数据框中的所有值插入 table。基本上我正在尝试加载为以下查询:
INSERT INTO mytable
SELECT *
FROM mydataframe
为此,我有以下代码:
import pyodbc
import pandas as pd
connection = pyodbc.connect('Driver={' + driver + '} ;'
'Server=' + server + ';'
'UID=' + user + ';'
'PWD=' + pass + ';')
cursor = connection.cursor()
query = 'SELECT * FROM [myDB].[dbo].[myTable]'
df = pd.read_sql_query(query, connection)
sql = 'INSERT INTO [dbo].[new_date] SELECT * FROM :x'
cursor.execute(sql, x=df)
connection.commit()
但是,我收到以下错误:
TypeError: execute() takes no keyword arguments
有谁知道我做错了什么吗?
cursor.execute 不接受关键字参数。执行插入的一种方法可以使用以下代码片段。
cols = "`,`".join([str(i) for i in df.columns.tolist()])
# Insert DataFrame recrds one by one.
for i,row in df.iterrows():
sql = "INSERT INTO `[dbo].[new_date]` (`" +cols + "`) VALUES (" + "?,"*(len(row)-1) + "%s)"
cursor.execute(sql, tuple(row))
此处您遍历每一行,然后将其插入 table。
我在连接 pandas 和 SQL 服务器时也遇到了一些问题。但是我得到了这个解决方案来编写我的 df:
import pyodbc
import sqlalchemy
engine = sqlalchemy.create_engine('mssql+pyodbc://{0}:{1}@{2}:{3}/{4}?driver={5}'.format(username,password,server,port,bdName,driver))
pd.to_sql("TableName",con=engine,if_exists="append")
对于来自 Pandas 的原始 DB-API 插入查询,考虑 DataFrame.to_numpy()
和 executemany
并避免任何顶层 for
循环。但是,在追加查询中必须使用显式列。调整以下列和 qmark 参数占位符以对应于数据框列。
# PREPARED STATEMENT
sql = '''INSERT INTO [dbo].[new_date] (Col1, Col2, Col3, ...)
VALUES (?, ?, ?, ...)
'''
# EXECUTE PARAMETERIZED QUERY
cursor.executemany(sql, df.to_numpy().tolist())
conn.commit()
(顺便说一下,在 SQL 查询中,最佳做法通常是始终显式引用列并避免 SELECT *
以提高代码可读性、可维护性甚至性能。)
感谢您的回答:) 但我使用以下代码来解决我的问题:
params = urllib.parse.quote_plus("DRIVER={SQL Server};SERVER=servername;DATABASE=database;UID=user;PWD=pass")
engine = sqlalchemy.create_engine("mssql+pyodbc:///?odbc_connect=%s" % params)
engine.connect()
query = query
df = pd.read_sql_query(query, connection)
df.to_sql(name='new_table',con=engine, index=False, if_exists='append')
请参阅下面我最喜欢的解决方案,其中包含 UPSERT 语句。
df_columns = list(df)
columns = ','.join(df_columns)
values = 'VALUES({})'.format(','.join(['%s' for col in df_columns]))
update_list = ['{} = EXCLUDED.{}'.format(col, col) for col in df_columns]
update_str = ','.join(update_list)
insert_stmt = "INSERT INTO {} ({}) {} ON CONFLICT ([your_pkey_here]) DO UPDATE SET {}".format(table, columns, values, update_str)
我有一个数据框 df,我想执行一个查询以将数据框中的所有值插入 table。基本上我正在尝试加载为以下查询:
INSERT INTO mytable
SELECT *
FROM mydataframe
为此,我有以下代码:
import pyodbc
import pandas as pd
connection = pyodbc.connect('Driver={' + driver + '} ;'
'Server=' + server + ';'
'UID=' + user + ';'
'PWD=' + pass + ';')
cursor = connection.cursor()
query = 'SELECT * FROM [myDB].[dbo].[myTable]'
df = pd.read_sql_query(query, connection)
sql = 'INSERT INTO [dbo].[new_date] SELECT * FROM :x'
cursor.execute(sql, x=df)
connection.commit()
但是,我收到以下错误:
TypeError: execute() takes no keyword arguments
有谁知道我做错了什么吗?
cursor.execute 不接受关键字参数。执行插入的一种方法可以使用以下代码片段。
cols = "`,`".join([str(i) for i in df.columns.tolist()])
# Insert DataFrame recrds one by one.
for i,row in df.iterrows():
sql = "INSERT INTO `[dbo].[new_date]` (`" +cols + "`) VALUES (" + "?,"*(len(row)-1) + "%s)"
cursor.execute(sql, tuple(row))
此处您遍历每一行,然后将其插入 table。
我在连接 pandas 和 SQL 服务器时也遇到了一些问题。但是我得到了这个解决方案来编写我的 df:
import pyodbc
import sqlalchemy
engine = sqlalchemy.create_engine('mssql+pyodbc://{0}:{1}@{2}:{3}/{4}?driver={5}'.format(username,password,server,port,bdName,driver))
pd.to_sql("TableName",con=engine,if_exists="append")
对于来自 Pandas 的原始 DB-API 插入查询,考虑 DataFrame.to_numpy()
和 executemany
并避免任何顶层 for
循环。但是,在追加查询中必须使用显式列。调整以下列和 qmark 参数占位符以对应于数据框列。
# PREPARED STATEMENT
sql = '''INSERT INTO [dbo].[new_date] (Col1, Col2, Col3, ...)
VALUES (?, ?, ?, ...)
'''
# EXECUTE PARAMETERIZED QUERY
cursor.executemany(sql, df.to_numpy().tolist())
conn.commit()
(顺便说一下,在 SQL 查询中,最佳做法通常是始终显式引用列并避免 SELECT *
以提高代码可读性、可维护性甚至性能。)
感谢您的回答:) 但我使用以下代码来解决我的问题:
params = urllib.parse.quote_plus("DRIVER={SQL Server};SERVER=servername;DATABASE=database;UID=user;PWD=pass")
engine = sqlalchemy.create_engine("mssql+pyodbc:///?odbc_connect=%s" % params)
engine.connect()
query = query
df = pd.read_sql_query(query, connection)
df.to_sql(name='new_table',con=engine, index=False, if_exists='append')
请参阅下面我最喜欢的解决方案,其中包含 UPSERT 语句。
df_columns = list(df)
columns = ','.join(df_columns)
values = 'VALUES({})'.format(','.join(['%s' for col in df_columns]))
update_list = ['{} = EXCLUDED.{}'.format(col, col) for col in df_columns]
update_str = ','.join(update_list)
insert_stmt = "INSERT INTO {} ({}) {} ON CONFLICT ([your_pkey_here]) DO UPDATE SET {}".format(table, columns, values, update_str)