2018-08-10 pandas写入sqlserver错误处理

使用pyodbc时读取数据是ok 的,但写入时会报错

import pandas as pd
import pyodbc

conn = pyodbc.connect(
    r'DRIVER={SQL Server};'
    r'SERVER=10.2.3.24,1433;'
    r'DATABASE=somedb;'
    r'UID=username;'
    r'PWD=passwd'
    )
sqldata = pd.read_sql("select * from testtable",conn)
df = pd.DataFrame(sqldata)
for i in df.index:
    while True:
        if "**" in df.HandleCMRule[i]:
            df.HandleCMRule[i] = df.HandleCMRule[i].replace("**", "*")
        else:
            df.HandleCMRule[i] = df.HandleCMRule[i].replace("*", ".*?")
            df.HandleCMRule[i] = df.HandleCMRule[i].replace("..*??", ".*?")
            break

当将DataFrame写回数据库时就报错了

df.to_sql("testtable", con=conn, index=False,if_exists="replace")

错误如下:

Traceback (most recent call last):
  File "C:\ProgramData\Anaconda3\lib\site-packages\pandas\io\sql.py", line 1400, in execute
    cur.execute(*args)
pyodbc.ProgrammingError: ('42S02', "[42S02] [Microsoft][ODBC SQL Server Driver][SQL Server]对象名 'sqlite_master' 无效。 (208) (SQLExecDirectW); [42S02] [Microsoft][ODBC SQL Server Driver][SQL Server]无法预定义语句。 (8180)")
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "C:\ProgramData\Anaconda3\lib\site-packages\IPython\core\interactiveshell.py", line 2963, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-3-447cbecb2c26>", line 1, in <module>
    df.to_sql("AIDiagnosisClinicalManifestationTest", con=conn, index=False)
  File "C:\ProgramData\Anaconda3\lib\site-packages\pandas\core\generic.py", line 2127, in to_sql
    dtype=dtype)
  File "C:\ProgramData\Anaconda3\lib\site-packages\pandas\io\sql.py", line 450, in to_sql
    chunksize=chunksize, dtype=dtype)
  File "C:\ProgramData\Anaconda3\lib\site-packages\pandas\io\sql.py", line 1502, in to_sql
    table.create()
  File "C:\ProgramData\Anaconda3\lib\site-packages\pandas\io\sql.py", line 561, in create
    if self.exists():
  File "C:\ProgramData\Anaconda3\lib\site-packages\pandas\io\sql.py", line 549, in exists
    return self.pd_sql.has_table(self.name, self.schema)
  File "C:\ProgramData\Anaconda3\lib\site-packages\pandas\io\sql.py", line 1514, in has_table
    return len(self.execute(query, [name, ]).fetchall()) > 0
  File "C:\ProgramData\Anaconda3\lib\site-packages\pandas\io\sql.py", line 1412, in execute
    raise_with_traceback(ex)
  File "C:\ProgramData\Anaconda3\lib\site-packages\pandas\compat\__init__.py", line 403, in raise_with_traceback
    raise exc.with_traceback(traceback)
  File "C:\ProgramData\Anaconda3\lib\site-packages\pandas\io\sql.py", line 1400, in execute
    cur.execute(*args)
pandas.io.sql.DatabaseError: Execution failed on sql 'SELECT name FROM sqlite_master WHERE type='table' AND name=?;': ('42S02', "[42S02] [Microsoft][ODBC SQL Server Driver][SQL Server]对象名 'sqlite_master' 无效。 (208) (SQLExecDirectW); [42S02] [Microsoft][ODBC SQL Server Driver][SQL Server]无法预定义语句。 (8180)")

折腾半天总是找到方法了。
修改后的代码如下:

import pandas as pd
from sqlalchemy import create_engine


engine = create_engine('mssql+pyodbc://username:passwd@10.2.3.24:1433/somedb?driver=SQL+Server')
#?driver=SQL+Server 没加这个会报错 找不到驱动……
sqldata = pd.read_sql("select * from testtable",engine)
df = pd.DataFrame(sqldata)
for i in df.index:
    while True:
        if "**" in df.HandleCMRule[i]:
            df.HandleCMRule[i] = df.HandleCMRule[i].replace("**", "*")
        else:
            df.HandleCMRule[i] = df.HandleCMRule[i].replace("*", ".*?")
            df.HandleCMRule[i] = df.HandleCMRule[i].replace("..*??", ".*?")
            break
df.to_sql("testtable", con=engine, index=False, if_exists="replace", chunksize=10)
# chunksize 每次传递的数据量大小 ,如果字段较多这个值设的小一些,默认1000
    原文作者:AntFish
    原文地址: https://www.jianshu.com/p/bb8c01af0b14
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞