根据数据框插入选择

时间:2020-04-19 16:11:48

标签: python sql-server pandas pyodbc

我有一个数据框df,我想执行一个查询以将数据框中的所有值插入表中。基本上,我正在尝试加载以下查询:

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

有人知道我在做什么错吗?

5 个答案:

答案 0 :(得分:1)

我在将熊猫与SQL Server连接时也遇到了一些问题。但是我有这个解决方案来编写我的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")

答案 1 :(得分:1)

请参阅下面我最喜欢的解决方案,其中包含 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)

答案 2 :(得分:0)

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))

这里您要遍历每一行,然后将其插入表中。

答案 3 :(得分:0)

对于来自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 *来提高代码的可读性,可维护性甚至性能。)

答案 4 :(得分:0)

感谢您的回答:),但是我使用以下代码解决了我的问题:

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')
相关问题