将 unicode 转义序列数据插入 SQL 服务器数据库 (pyodbc)
Inserting unicode escape sequence data to SQL server db (pyodbc)
我正在尝试将从网络上抓取的数据插入 SQL 服务器数据库,并且我的数据库 table 的相关列设置为 nvarchar(max)
类型。
在 python shell:
中测试
dbargs={'DATABASE': '<mydbname>',
'DRIVER': '{FreeTDS}',
'PORT': '1433',
'PWD': '<mypass>',
'SERVER': '<server>',
'UID': '<myusername>'}
import pyodbc
cnxn = pyodbc.connect(**dbargs)
cursor = cnxn.cursor()
insert_cmd="INSERT INTO c_master (run_id, product_name) VALUES (?,?)"
然后
cursor.execute(insert_cmd, (274, u'test naméâôóòöë'))
工作正常,但是
cursor.execute(insert_cmd, (274, u'test \u2019d'))
导致错误
ProgrammingError: ('42000', "[42000] [FreeTDS][SQL Server]Incorrect syntax near ','. (102) (SQLExecDirectW)")
我发现我正在抓取后一种类型的数据并在我尝试将其插入我的编写器管道中的数据库时生成错误。
处理此类数据的正确方法是什么?
(我正在使用 FreeTDS、unixodbc、MSSQL 服务器、pyodbc)
FreeTDS 和 unixodbc 配置:
/etc/odbc.init:
[myserver]
Driver = FreeTDS
Description =Myserver MSSQL database
# Servername corresponds to the section in freetds.conf
Servername=myserver
Database = mydbname
TDS_Version = 7.0
/etc/odbcinst.ini:
[ODBC]
Trace = Yes
TraceFile = /tmp/odbcsql.log
ForceTrace = Yes
Pooling = Yes
[FreeTDS]
Description = TDS driver (Sybase/MS SQL)
Driver = /usr/lib/x86_64-linux-gnu/odbc/libtdsodbc.so
Setup = /usr/lib/x86_64-linux-gnu/odbc/libtdsS.so
CPTimeout = 120
CPReuse =
/etc/freetds/freetds.conf:
[global]
tds version = 7.0
dump file = /var/log/freetds.log
debug flags = 0xffff
# timeout = 10
# connect timeout = 10
text size = 64512
[myserver]
host = <myserverip>
port = 1433
tds version = 7.0
dump_file = /var/log/freetds.log
client charset = UTF-8
我还在 /etc/environment 和 /etc/profile 中添加了 TDSDUMP="/var/log/freetds.log"。虽然很奇怪,但我仍然没有看到 freetds 日志。
我怀疑您需要配置 FreeTDS 连接以识别将用于插入语句的客户端编码。
据我所知,在 ODBC 中无法为单个参数声明编码。所有 SQL 文本和字符数据均根据单个客户端编码连接配置进行解释。
您还可以设置 TDSDUMP 环境参数,并查看发送到您服务器的数据。如果您还没有做到这一点,请尝试使用 ODBC 日志。
您需要将 TDS_Version
作为连接字符串的一部分传递。您正在连接一个完整的连接字符串,如果您在 connect()
声明中将完整的服务器名称作为 SERVER 传递,它会绕过 DSN。如果要连接 DSN,则需要提供 DSN
(和 UID
/ PWD
)而不是 SERVER
和 PORT
.
我已发出拉取请求,以便在此处更好地向 FreeTDS 解释 TDS 版本:https://github.com/FreeTDS/freetds/pull/71
如果未提供,则使用的默认 TDS 版本不支持 Unicode(如您所见!)。假设您正在使用 SQL Server 2005 或更新版本,如果您正在使用:
- FreeTDS 1.0: 使用 TDS_Version 7.4
- FreeTDS 0.95: 使用 TDS_Version 7.3
- FreeTDS 0.91: 使用 TDS_Version 7.2
祝你好运!
我遇到了同样的问题,一切正常,唯一的问题是有“?” table after insert 语句中的字符。我正在使用 Python 3.7.2.
所以当我使用类似于以下查询时终于成功了。
insert_cmd="""INSERT INTO c_master (run_id, product_name) VALUES ('{runId}',N'{productName}')""".format(runId=4, productName='حلواہ پوری')
我正在尝试将从网络上抓取的数据插入 SQL 服务器数据库,并且我的数据库 table 的相关列设置为 nvarchar(max)
类型。
在 python shell:
中测试dbargs={'DATABASE': '<mydbname>',
'DRIVER': '{FreeTDS}',
'PORT': '1433',
'PWD': '<mypass>',
'SERVER': '<server>',
'UID': '<myusername>'}
import pyodbc
cnxn = pyodbc.connect(**dbargs)
cursor = cnxn.cursor()
insert_cmd="INSERT INTO c_master (run_id, product_name) VALUES (?,?)"
然后
cursor.execute(insert_cmd, (274, u'test naméâôóòöë'))
工作正常,但是
cursor.execute(insert_cmd, (274, u'test \u2019d'))
导致错误
ProgrammingError: ('42000', "[42000] [FreeTDS][SQL Server]Incorrect syntax near ','. (102) (SQLExecDirectW)")
我发现我正在抓取后一种类型的数据并在我尝试将其插入我的编写器管道中的数据库时生成错误。
处理此类数据的正确方法是什么?
(我正在使用 FreeTDS、unixodbc、MSSQL 服务器、pyodbc)
FreeTDS 和 unixodbc 配置:
/etc/odbc.init:
[myserver]
Driver = FreeTDS
Description =Myserver MSSQL database
# Servername corresponds to the section in freetds.conf
Servername=myserver
Database = mydbname
TDS_Version = 7.0
/etc/odbcinst.ini:
[ODBC]
Trace = Yes
TraceFile = /tmp/odbcsql.log
ForceTrace = Yes
Pooling = Yes
[FreeTDS]
Description = TDS driver (Sybase/MS SQL)
Driver = /usr/lib/x86_64-linux-gnu/odbc/libtdsodbc.so
Setup = /usr/lib/x86_64-linux-gnu/odbc/libtdsS.so
CPTimeout = 120
CPReuse =
/etc/freetds/freetds.conf:
[global]
tds version = 7.0
dump file = /var/log/freetds.log
debug flags = 0xffff
# timeout = 10
# connect timeout = 10
text size = 64512
[myserver]
host = <myserverip>
port = 1433
tds version = 7.0
dump_file = /var/log/freetds.log
client charset = UTF-8
我还在 /etc/environment 和 /etc/profile 中添加了 TDSDUMP="/var/log/freetds.log"。虽然很奇怪,但我仍然没有看到 freetds 日志。
我怀疑您需要配置 FreeTDS 连接以识别将用于插入语句的客户端编码。
据我所知,在 ODBC 中无法为单个参数声明编码。所有 SQL 文本和字符数据均根据单个客户端编码连接配置进行解释。
您还可以设置 TDSDUMP 环境参数,并查看发送到您服务器的数据。如果您还没有做到这一点,请尝试使用 ODBC 日志。
您需要将 TDS_Version
作为连接字符串的一部分传递。您正在连接一个完整的连接字符串,如果您在 connect()
声明中将完整的服务器名称作为 SERVER 传递,它会绕过 DSN。如果要连接 DSN,则需要提供 DSN
(和 UID
/ PWD
)而不是 SERVER
和 PORT
.
我已发出拉取请求,以便在此处更好地向 FreeTDS 解释 TDS 版本:https://github.com/FreeTDS/freetds/pull/71
如果未提供,则使用的默认 TDS 版本不支持 Unicode(如您所见!)。假设您正在使用 SQL Server 2005 或更新版本,如果您正在使用:
- FreeTDS 1.0: 使用 TDS_Version 7.4
- FreeTDS 0.95: 使用 TDS_Version 7.3
- FreeTDS 0.91: 使用 TDS_Version 7.2
祝你好运!
我遇到了同样的问题,一切正常,唯一的问题是有“?” table after insert 语句中的字符。我正在使用 Python 3.7.2.
所以当我使用类似于以下查询时终于成功了。
insert_cmd="""INSERT INTO c_master (run_id, product_name) VALUES ('{runId}',N'{productName}')""".format(runId=4, productName='حلواہ پوری')