截断表不适用于 SQL Server sqlalchemy 引擎和 pandas

Posted

技术标签:

【中文标题】截断表不适用于 SQL Server sqlalchemy 引擎和 pandas【英文标题】:Truncate table not working with SQL server sqlalchemy engine and pandas 【发布时间】:2017-06-24 01:57:25 【问题描述】:

我可以使用 sqlalchemy 和 pandas 成功查询和插入数据:

from sqlalchemy import create_engine
import pandas as pd
engine = create_engine('mssql://myserver/mydb?driver=SQL+Server+Native+Client+11.0?trusted_connection=yes')

读取临时表:

sql_command = """
select top 100 * from tempy
"""

df = pd.read_sql(sql_command, engine)
print df

   tempID  tempValue
0       1          2

追加新数据:

df_append = pd.DataFrame( [[4,6]] , columns=['tempID','tempValue']) 
df_append.to_sql(name='tempy', con=engine, if_exists = 'append', index=False)

df = pd.read_sql(sql_command, engine)
print df

   tempID  tempValue
0       1          2
1       4          6

尝试截断数据:

connection = engine.connect()
connection.execute( '''TRUNCATE TABLE tempy''' )
connection.close()

再次读取表,但截断失败:

df = pd.read_sql(sql_command, engine)
print df

   tempID  tempValue
0       1          2
1       4          6

【问题讨论】:

你尝试提交了吗? 我无法重现这种行为。你的 Pandas 和 SQLAlchemy 版本是什么?顺便说一句,您不必创建 connection 对象,以下内容也可以:engine.execute('truncate table tempy') @MaxU pandas 0.9.1 和 sqlalchemy 1.0.13 @univerio 感谢您提供有关提交的提示 【参考方案1】:

pandas 0.19.2 和 sqlalchemy 1.1.5 有同样的问题。

正如我所见,autocommit 在运行 TRUNCATE 语句时不会在 engine.execute() 中强制执行。如果我手动强制,那么TRUNCATE 可以完美运行:

from sqlalchemy.sql import text as sa_text

engine.execute(sa_text('''TRUNCATE TABLE tempy''').execution_options(autocommit=True))

DROP 可以完美运行而无需强制 autocommit...

【讨论】:

谢谢! autocommit 是关键。 @ragesz DROP 不需要自动提交的原因是许多 RDBMS 使一些 DDL 指令非事务性的。更糟糕的是,它们可以触发正在进行的事务的提交。因此,定义哪个查询是否需要自动提交的确切行为是特定于供应商的。【参考方案2】:

这对我有用:

from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind=engine)
session = Session()
session.execute('''TRUNCATE TABLE tempy''')
session.commit()
session.close()

【讨论】:

【参考方案3】:

这是基于问题的完整解决方案,在 Windows 上使用 sqlalchemy 1.1.15 我在尝试实施其他解决方案时收到错误:

import sqlalchemy
engine = sqlalchemy.create_engine('mssql://myserver/mydb?driver=SQL+Server+Native+Client+11.0?trusted_connection=yes')
connection = engine.connect()
truncate_query = sqlalchemy.text("TRUNCATE TABLE tempy")
connection.execution_options(autocommit=True).execute(truncate_query)

【讨论】:

【参考方案4】:

在尝试了 ragesz 发布的解决方案但它对我不起作用(我的 sqlalchemy 版本是 1.3.9)后,我得到了以下工作:

with engine.connect() as con:
    con.execution_options(autocommit=True).execute("TRUNCATE TABLE foo;")

【讨论】:

以上是关于截断表不适用于 SQL Server sqlalchemy 引擎和 pandas的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server 日期格式不适用于存储过程

SQL Server 2008 中的截断/清除表变量

sql 截断sql server数据库中的所有表

在 SQL Server 2005 中截断数据库的所有表

可以在sql server中使用Cursor截断多个表

由于截断/删除导致 SQL Server 主键冲突?