sqlalchemy寻找服务器版本为字符串,而不是类似字节的对象

时间:2019-01-02 14:30:40

标签: python windows sqlalchemy pypyodbc

我不知道是什么突然导致的(我最近重新安装了Anaconda和所有python库,但是我回到了以前的相同版本),但是当sqlalchemy尝试连接到SQL Server时,它失败了,因为它查找服务器版本并尝试在其上运行字符串操作。

在重新安装软件包之前,以下没有问题。我会这样连接:

sqlalchemy_conn_string = 'mssql+pyodbc://myDSN'
sqlalchemy.create_engine(sqlalchemy_conn_string, module=pypyodbc)

然后它一直到达名为pyodbc.py的文件,并在此功能下失败:

def _get_server_version_info(self, connection):
  try:
    raw = connection.scalar("SELECT SERVERPROPERTY('ProductVersion')")
  except exc.DBAPIError:
    #...
  else:
    version= []
    r = re.compile(r'[.\-]')
    for n in r.split(raw):  # culprit here
      try:
        version.append(int(n))
      except ValueError:
        version.append(n)
    return tuple(version)

Out[1]: TypeError: cannot use a string pattern on a bytes-like object

这是因为在此步骤中,raw不是可以拆分的字符串:

# from PyCharm's debugger window
raw = {bytes}b'13.0.5026.0'

在这一点上,我不知道是否应该为sqlalchemy和/或pypyodbc提交错误报告,或者是否可以自己解决该问题。但是我想要一个不涉及在我自己的机器上编辑sqlalchemy代码的解决方案(例如专门处理类似字节的对象),因为我们还有其他团队成员也将下载香草sqlalchemy和pypyodbc,因此不会没有信心编辑该源代码。

1 个答案:

答案 0 :(得分:1)

我已经确认了python 3.6.4下的pypyodbc行为。

print(pypyodbc.version)  # 1.3.5
sql = """\
SELECT SERVERPROPERTY('ProductVersion')
"""
crsr.execute(sql)
x = crsr.fetchone()[0]
print(repr(x))  # b'12.0.5207.0'

请注意,SQLAlchemy的mssql+pyodbc方言是为pyodbc而不是py py odbc编码的,并且不能保证两者都是100%兼容的。

显而易见的解决方案是改为使用pyodbc。

更新:

检查您的SQLAlchemy版本。我只是看了mssql+pyodbc dialect的当前源代码,确实如此

def _get_server_version_info(self, connection):
    try:
        # "Version of the instance of SQL Server, in the form
        # of 'major.minor.build.revision'"
        raw = connection.scalar(
            "SELECT CAST(SERVERPROPERTY('ProductVersion') AS VARCHAR)")

即使使用pypyodbc,也应避免该问题。

如果您使用的是SQLAlchemy的最新生产版本(当前版本为1.2.15),那么使用1.3.0b1版本可能会更好。