连接到IBM AS400服务器以进行数据库操作会挂起

AH1*_*H16 10 python database ibm-midrange

我正在尝试用Python中的AS400交谈.目标是使用SQLAlchemy,但是当我无法使用它时,我只使用ibm_db而不是ibm_db_sa来回到更基本的脚本.

import ibm_db
dbConnection = ibm_db.pconnect("DATABASE=myLibrary;HOSTNAME=1.2.3.4;PORT=8471;PROTOCOL=TCPIP;UID=username;PWD=password", "", "") #this line is where it hangs
print ibm_db.conn_errormsg()
Run Code Online (Sandbox Code Playgroud)

问题似乎是端口.如果我使用我在所有示例中看到的50000,我会收到错误.如果我使用446,我会收到错误.令人困惑的部分是:如果我使用8471,IBM说要做,我没有错误,没有超时,没有任何响应.我让脚本运行了二十多分钟,它只是坐在那里,什么都不做.它是活跃的,因为我根本不能使用命令提示符,但它从来没有给我任何反馈.

我每天工作的公司使用同样的400,用于日志记录,电子邮件和(大量)数据库使用,所以我知道它有效.我们使用的软件,在幕后与数据库通信,在我的机器上运行得很好.这告诉我我的驱动程序是好的,网络设置是正确的,等等.我甚至可以从这里远程登陆400.

我在SQLAlchemy和ibm_db电子邮件列表上,并且已经与他们沟通了好几天关于这个问题.我也搜索了这么多,我开始在搜索结果中用完未访问过的链接.似乎没有人无限期地悬挂连接的问题.如果有什么我可以在Python中尝试,我会尝试.我没有直接处理400,但我可以问那些检查/配置我需要的人.正如我所说的,几个工作站可以毫无问题地与400的数据库通信,并且如果从400本身运行,则针对我想要访问的库运行的查询工作正常.如果有人有任何建议,我将非常感谢听到他们.谢谢!

Joh*_*n Y 10

自述文件ibm_db_sa中"支持的数据库"一节中列出仅DB2用于Linux/UNIX/Windows的.所以它很可能不适用于DB2 for i,至少不是开箱即用的.

既然您已经声明有IBM System i Access for Windows,我强烈建议您使用它附带的驱动程序之一(ODBC,OLEDB或ADO.NET,如@Charles所述).

就个人而言,我总是使用ODBC,或者使用pyodbc或者pypyodbc.任何一个都可以.一个简单的例子:

import pyodbc

connection = pyodbc.connect(
    driver='{iSeries Access ODBC Driver}',
    system='11.22.33.44',
    uid='username',
    pwd='password')
c1 = connection.cursor()

c1.execute('select * from qsys2.sysschemas')
for row in c1:
    print row
Run Code Online (Sandbox Code Playgroud)

现在,SQLAlchemy的的连接方法中的一种pyodbc,所以我认为,如果你能建立使用连接pyodbc直接,你可以以某种方式配置的SQLAlchemy做同样的.但我自己不是SQLAlchemy用户,所以我没有示例代码.

UPDATE

我设法让SQLAlchemy连接到我们的IBM i并执行直接的SQL查询.换句话说,让它与简单地直接使用PyODBC具有相同的功能.我还没有测试任何其他SQLAlchemy功能.我在Windows 7机器上设置连接的方法:

  • 安装ibm_db_sa为SQLAlchemy方言
    你可以使用pip它,但我用低技术方式做到了:

    1. ibm_db_sa从PyPI 下载.
      在撰写本文时,最新版本为0.3.2,已于2014-10-20上传.这是可以想象的,后来的版本将是固定的或以不同的方式打破(所以在未来,我将要描述的可能是不必要的,否则可能会无法正常工作的修改).
    2. 解压缩archive(ibm_db_sa-0.3.2.tar.gz)并将随附的ibm_db_sa目录复制到sqlalchemy\dialects目录中.
  • 修改 sqlalchemy\dialects\ibm_db_sa\pyodbc.py

    • 添加initialize()方法的AS400Dialect_pyodbc
      的这点是覆盖同名的方法DB2Dialect,它AS400Dialect_pyodbc从继承.问题是DB2Dialect.initialize()尝试设置属性,dbms_ver并且dbms_name在使用PyODBC连接到IBM i时,这些属性都不可用或相关(据我所知).
    • 添加模块级名称dialect并将其设置为AS400Dialect_pyodbc

上述修改的代码应该放在文件的末尾,如下所示:

    def initialize(self, connection):
        super(DB2Dialect, self).initialize(connection)

dialect = AS400Dialect_pyodbc
Run Code Online (Sandbox Code Playgroud)

注意缩进!请记住,该initialize()方法需要属于AS400Dialect_pyodbc该类,并且dialect需要对模块是全局的.

最后,您需要为引擎创建者提供正确的URL:

'ibm_db_sa+pyodbc://username:password@host/*local'

(显然,替代有效值username,passwordhost).

而已.此时,您应该能够创建引擎,连接到i,并通过SQLAlchemy执行纯SQL.我认为很多ORM的东西也应该在这一点上起作用,但我还没有证实这一点.