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

时间:2016-02-17 15:47:30

标签: 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()

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

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

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

4 个答案:

答案 0 :(得分:9)

README for ibm_db_sa仅列出了“支持的数据库”部分中的DB2 for Linux / Unix / Windows。所以它很可能不适用于DB2 for i,至少不是开箱即用的。

由于您已声明拥有适用于Windows的IBM System i Access,因此我强烈建议您使用随附的其中一个驱动程序(ODBC,OLEDB或ADO.NET,如@Charles所述)。

就个人而言,我总是使用ODBC,pyodbcpypyodbc。任何一个都可以。一个简单的例子:

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

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

<强>更新

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

  • 安装ibm_db_sa作为SQLAlchemy方言
    您可能可以使用pip,但我采用的是低技术方式:

    1. 从PyPI下载ibm_db_sa 在撰写本文时,最新版本为0.3.2,已于2014-10-20上传。可以想象,以后的版本将以不同的方式修复或破坏(因此将来,我将要描述的修改可能是不必要的,或者它们可能不起作用)。
    2. 解压缩归档文件(ibm_db_sa-0.3.2.tar.gz)并将随附的ibm_db_sa目录复制到sqlalchemy\dialects目录中。
  • 修改sqlalchemy\dialects\ibm_db_sa\pyodbc.py

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

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

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

dialect = AS400Dialect_pyodbc

注意缩进!请记住,initialize()方法需要属于AS400Dialect_pyodbc类,dialect需要对模块是全局的。< / p>

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

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

(显然,替换usernamepasswordhost的有效值。)

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

答案 1 :(得分:1)

找出所需端口的方法是查看IBM i上的服务表条目。

您的IBM i人员可以使用iNav GUI或绿屏使用服务表条目(WRKSRVTBLE)命令

应该得到这样的屏幕:

Service                                  Port  Protocol  

as-admin-http                            2001  tcp       
as-admin-http                            2001  udp       
as-admin-https                           2010  tcp       
as-admin-https                           2010  udp       
as-central                               8470  tcp       
as-central-s                             9470  tcp       
as-database                              8471  tcp       
as-database-s                            9471  tcp  
drda                                      446  tcp
drda                                      446  udp     

数据库的默认端口确实是8471.虽然drda用于&#34;分布式数据库&#34;操作

基于此thread,要使用ibm_db连接到IBM i上的DB2,您需要IBM Connect产品;这是一个必须付费的商业套餐。

thread建议通过pyodbc模块使用ODBC。它还建议通过JT400工具包的JDBC也可以工作。

答案 2 :(得分:1)

以下是使用as400,sqlalchemy和pandas的示例。 这个例子拿了一堆csv文件并插入pandas / sqlalchemy。 仅适用于Windows,在linux上i系列odbc驱动程序段错误(Centos 7和Debian 9 x68_64)

客户端是Windows 10。

我的as400版本是7.3

Python是2.7.14

安装pip:pandas,pyodbc,imb_db_sa,sqlalchemy

您需要从ftp://public.dhe.ibm.com/as400/products/clientaccess/win32/v7r1m0/servicepack/si66062/

安装Windows访问权限

@JohnY对pyodbc.py的修改 C:\ Python27 \ LIB \站点包\ SQLAlchemy的\方言\ ibm_db_sa \ pyodbc.py 将第99行更改为

    pyodbc_driver_name = "IBM i Access ODBC Driver"

odbc驱动程序更改了它的名称。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import pandas as pd
import numpy as np
from sqlalchemy import create_engine
import glob

csvfiles=(glob.glob("c:/Users/nahum/Documents/OUT/*.csv"))
df_csvfiles = pd.DataFrame(csvfiles)
for index, row in df_csvfiles.iterrows():
    datastore2=pd.read_csv(str(row[0]), delimiter=',', header=[0],skipfooter=3)
    engine = create_engine('ibm_db_sa+pyodbc://DB2_USER:PASSWORD@IP_SERVER/*local')
    datastore2.to_sql('table', engine, schema='SCHEMA', chunksize=1000, if_exists='append', index=False)

希望它有所帮助。

答案 3 :(得分:0)

如果不需要Pandas / SQLAlchemy,只需按照John Y's answer中的建议使用pyodbc。否则,您可以在下面尝试对我有用的方法。摘自我对my own, similar question的回答,您可以查看有关起作用的更多详细信息(在起作用之前,我尝试过很多次并失败了)。

  1. 我在项目中创建了一个空白文件来安抚我收到的此消息:

      

    无法打开'hashtable_class_helper.pxi':找不到文件   (file:///c:/git/dashboards/pandas/_libs/hashtable_class_helper.pxi

    (我的项目文件夹为C:/Git/dashboards,所以我创建了其余的路径。)

  2. 在存在该文件的情况下,下面的代码现在对我有用。为了记录起见,不管John Y's answer中是否建议修改ibm_db_sa模块,它似乎都有效,因此,我建议您不要使用该模块。请注意,尽管它们不是直接导入的,但您需要安装以下模块:pyodbcibm_db_sa,可能还有future(如果使用Python 2,我会忘记是否有必要) 。如果您使用的是Python 3,则需要urllib.parse而不是urllib。我还在计算机上安装了i Access 7.1驱动程序,该驱动程序可能已发挥作用。

import urllib
import pandas as pd
from sqlalchemy import create_engine

CONNECTION_STRING = (
    "driver={iSeries Access ODBC Driver};"
    "system=ip_address;"
    "database=database_name;"
    "uid=username;"
    "pwd=password;"
)

SQL= "SELECT..."

quoted = urllib.quote_plus(CONNECTION_STRING)
engine = create_engine('ibm_db_sa+pyodbc:///?odbc_connect={}'.format(quoted))

df = pd.read_sql_query(
    SQL,
    engine,
    index_col='some column'
)
print df