【问题标题】:Sqlalchemy pyodbc DNS-less URL connection string does not seem to workSqlalchemy pyodbc DNS-less URL 连接字符串似乎不起作用
【发布时间】:2016-02-16 06:59:11
【问题描述】:

我正在尝试使用 sqlalchemy (1.0.9) 和 pyodbc 连接到 Windows 上的 Sybase ASE 15 数据库。如果我使用 DNS url,一切都会按预期工作:

url = r'sybase+pyodbc://usename:password@dns'
engine = create_engine(url, echo=True)
Session = sessionmaker(bind=engine)
sess = Session()
conn = sess.connection()

但是,如果我避开 DNS,我会收到一条错误消息:

url = 'sybase+pyodbc://username:password@host:port/database?driver=Adaptive Server Enterprise'

,我得到一个错误:

DBAPIError: (pyodbc.Error) ('01S00', '[01S00] [SAP][ASE ODBC Driver]端口号无效 (30011) (SQLDriverConnect)')

端口号正确,与 DNS 中指定的端口相同。

有什么想法吗?

【问题讨论】:

    标签: python sqlalchemy sap-ase pyodbc


    【解决方案1】:

    可能值得尝试使用 pyODBC(以及一般的 ODBC)使用的以分号分隔的无 DSN 格式的某些版本。这里有一些例子:

    http://www.connectionstrings.com/adaptive-server-enterprise-odbc-driver/

    这个问题解决了与 FreeTDS 类似的问题,但概念是相同的,因为连接字符串基本上是通过低级 ODBC 连接:

    SqlAlchemy equivalent of pyodbc connect string using FreeTDS

    URL 被解析为这种类型的字符串,以便 pyodbc 最终连接到 SQLDriverConnect(在 ODBC API 中),因此直接指定 ASE ODBC DSN-less 连接字符串可能会更好。

    更新:进行快速测试以查看为该 URL 生成了哪些连接参数:

    from sqlalchemy.engine.url import *
    from sqlalchemy.connectors.pyodbc import *
    
    connector =  PyODBCConnector()
    url = make_url("sybase+pyodbc://username:password@host:5555/database?driver=Adaptive Server Enterprise")
    print connector.create_connect_args(url)
    

    这会导致:

    [['DRIVER={Adaptive Server Enterprise};Server=host,5555;Database=database;UID=username;PWD=password'], {}]
    

    请注意,主机名和端口由逗号分隔,每个http://www.connectionstrings.com/adaptive-server-enterprise-odbc-driver/tds-based-odbc-driver-from-sybase-ocs-125/,此格式适用于 Sybase 12.5 的基于 TDS 的 ODBC:

    Driver={Sybase ASE ODBC Driver};NetworkAddress=myServerAddress,5000;
    Db=myDataBase;Uid=myUsername;Pwd=myPassword;
    

    但是,ASE 15 格式 (http://www.connectionstrings.com/adaptive-server-enterprise-odbc-driver/adaptive-server-enterprise-150/) 指定 server=myServerAddress;port=myPortnumberport 作为在分号分隔的字符串中传递的键:

    Driver={Adaptive Server Enterprise};app=myAppName;server=myServerAddress;
    port=myPortnumber;db=myDataBase;uid=myUsername;pwd=myPassword;
    

    如果您使用host;port=5555“欺骗”端口规范,您会得到:

    [['DRIVER={Adaptive Server Enterprise};Server=host;port=5555;Database=database;UID=username;PWD=password'], {}]
    

    但这感觉就像一个坏主意™,即使它有效。我还要注意,生成的字符串在 Sybase 连接字符串参考中使用 Database 作为键而不是 Db。这也可能被证明是一个问题。

    使用链接问题中的?odbc_connect 可能是控制发送到 ODBC 的确切连接参数的最佳选择。

    【讨论】:

    • 谢谢@will。今天下午晚些时候将进行更详细的查看/测试。有点烦人,因为不那么干净,代码变得不那么通用。对 Sybase 进行特殊处理。您如何看待您所附问题中建议的 Creator 方法?
    • 将使用您建议的第一种方法(坏主意!)。第二个似乎没有工作。我也可以从字符串中删除端口并执行以下操作:connect_args = {'port': port} engine = create_engine(url, echo=False, connect_args=connect_args)
    • 这似乎是合理的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-03-12
    • 2020-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-12
    • 1970-01-01
    相关资源
    最近更新 更多