短版本: 请告诉我如何通过SQLAlchemy连接到AS/400
长版本
我的最终目标是连接SQL Server和AS/400中的数据,以便在Flask Python应用程序中显示。我的方法是将每个数据库中的数据转换为Pandas数据帧,然后将其连接并输出为JSON。如果有人有更好的方法,请随时留言。我尝试这样做的方式的问题是Pandas.read_sql_query()
依赖于SQLAlchemy,而让SQLAlchemey与AS/400一起工作被证明是相当困难的。
- AS/400的版本是7.2,不过我可能会尝试连接的另一个版本是5.1
- 我正试图从我的计算机上访问它,该计算机运行Windows 7,具有I access 7.1、Python 2.7和Python模块,包括
pyodbc
和ibm_db_sa
如果没有sqlalchemy
,pyodbc
工作得很好:
CONNECTION_STRING = (
"driver={iSeries Access ODBC Driver};"
"system=ip_address;"
"database=database_name;"
"uid=username;"
"pwd=password;"
)
pyodbc.connect(CONNECTION_STRING)
# Queries work fine after this.
我阅读了这些资源,以及其他资源,并尝试应用它们的技术:
- https://pypi.org/project/ibm_db_sa/
- 连接到IBM AS400服务器进行数据库操作挂起
- 使用FreeTDS的pyodbc连接字符串的SqlAlchemy等价物
以下是我收集的一些失败尝试和相应的错误消息。我不知道第一部分("something+something//...
")应该放什么,指定哪个端口(446?8471?其他什么?什么都不知道?),是使用服务器的名称或IP地址,还是使用create_engine()
的连接字符串样式参数,所以我一直在尝试我能想到的每一种组合。我尝试按照上面第二个链接中的建议修改AS400Dialect_pyodbc
类,之后我再次尝试重新运行一些失败的尝试。我可能会继续尝试,但我现在只是在原地打转。
from sqlalchemy import create_engine
CONNECTION_STRING = (
"driver={iSeries Access ODBC Driver};"
"system=ip_address;"
"database=database_name;"
"uid=username;"
"pwd=password;"
)
create_engine('ibm_db_sa+pyodbc://username:password@ip_address:446/database_name').connect()
发生异常:sqlalchemy.exc.InterfaceError(pyodbc.InterfaceError)('IM002',u'[IM002][Microsoft][ODBC驱动程序管理器]未找到数据源名称,也未指定默认驱动程序(0)(SQLDriverConnect)')(此错误的背景信息:http://sqlalche.me/e/rvf5)中的文件"C:\Git\disables\web_app\pandands db2 test.py",第43行
create_engine('ibm_db_sa://username:password@ip_address:446/database_name').connect()
发生异常:sqlalchemy.exc.OperationalError(ibm_db_dbi.OperationalError)ibm_db_dbi::OperationalError:[ibm][CLI Driver]SQL30061N在远程节点上找不到数据库别名或数据库名称"database_name"。SQLSTATE=08004\r SQLCODE=-30061(此错误的背景信息:http://sqlalche.me/e/e3q8)中的文件"C:\Git\disables\web_app\pandands db2 test.py",第43行
create_engine('ibm_db_sa://username:password@server_name:446/database_name').connect()
发生异常:sqlalchemy.exc.OperationalError(ibm_db_dbi.OperationalError)ibm_db_dbi::OperationalError:[ibm][CLI Driver]SQL1336N未找到远程主机"server_name"。SQLSTATE=08001\r SQLCODE=-1336(此错误的背景信息:http://sqlalche.me/e/e3q8create_engine('im_db_sa://用户名:password@ip_address:446/server_name.database_name').connect()
create_engine('ibm_db_sa://username:password@ip_address:446/server_name.database_name').connect()
发生异常:sqlalchemy.exc.OperationalError(ibm_db_dbi.OperationalError)ibm_db_dbi::OperationalError:[ibm][CLI Driver]SQL30061N在远程节点上找不到数据库别名或数据库名称"server_name.database_name"。SQLSTATE=08004\r SQLCODE=-30061(此错误的背景信息:http://sqlalche.me/e/e3q8)
create_engine('db2+ibm_db://username:password@ip_address:446/server_name.database_name').connect()
发生异常:sqlalchemy.exc.OperationalError(ibm_db_dbi.OperationalError)ibm_db_dbi::OperationalError:[ibm][CLI Driver]SQL30061N在远程节点上找不到数据库别名或数据库名称"server_name.database_name"。SQLSTATE=08004\r SQLCODE=-30061(此错误的背景信息:http://sqlalche.me/e/e3q8)中的文件"C:\Git\disables\web_app\pandands db2 test.py",第45行
create_engine('db2+ibm_db://username:password@ip_address:446/database_name').connect()
发生异常:sqlalchemy.exc.OperationalError(ibm_db_dbi.OperationalError)ibm_db_dbi::OperationalError:[ibm][CLI Driver]SQL30061N在远程节点上找不到数据库别名或数据库名称"database_name"。SQLSTATE=08004\r SQLCODE=-30061(此错误的背景信息:http://sqlalche.me/e/e3q8)中的文件"C:\Git\disables\web_app\pandands db2 test.py",第45行
create_engine('db2+ibm_db://username:password@ip_address/database_name').connect()
发生异常:sqlalchemy.exc.OperationalError(ibm_db_dbi.OperationalError)ibm_db_dbi::OperationalError:[ibm][CLI Driver]SQL30081N检测到通信错误。正在使用的通信协议:"TCP/IP"。正在使用的通信API:"SOCKETS"。检测到错误的位置:"ip_address"。检测到错误的通信功能:"连接"。特定于协议的错误代码:"10061"、">"、">"。SQLSTATE=08001\r SQLCODE=-30081(此错误的背景信息:http://sqlalche.me/e/e3q8)
create_engine('db2+ibm_db://username:password@server_name:446/database_name').connect()
发生异常:sqlalchemy.exc.OperationalError(ibm_db_dbi.OperationalError)ibm_db_dbi::OperationalError:[ibm][CLI Driver]SQL1336N未找到远程主机"server_name"。SQLSTATE=08001\r SQLCODE=-1336(此错误的背景信息:http://sqlalche.me/e/e3q8)
create_engine('db2+ibm_db://username:password@server_name/database_name').connect()
发生异常:sqlalchemy.exc.OperationalError(ibm_db_dbi.OperationalError)ibm_db_dbi::OperationalError:[ibm][CLI Driver]SQL1336N未找到远程主机"server_name"。SQLSTATE=08001\r SQLCODE=-1336(此错误的背景信息:http://sqlalche.me/e/e3q8)
create_engine('db2+pyodbc://username:password@ip_address:446/database_name').connect()
发生异常:sqlalchemy.exc.InterfaceError(pyodbc.InterfaceError)('IM002',u'[IM002][Microsoft][ODBC驱动程序管理器]未找到数据源名称,也未指定默认驱动程序(0)(SQLDriverConnect)')(此错误的背景信息:http://sqlalche.me/e/rvf5)中的文件"C:\Git\disables\web_app\pandands db2 test.py",第45行
create_engine('db2://username:password@ip_address:446/database_name').connect()
发生异常:sqlalchemy.exc.OperationalError(ibm_db_dbi.OperationalError)ibm_db_dbi::OperationalError:[ibm][CLI Driver]SQL30061N在远程节点上找不到数据库别名或数据库名称"database_name"。SQLSTATE=08004\r SQLCODE=-30061(此错误的背景信息:http://sqlalche.me/e/e3q8)中的文件"C:\Git\disables\web_app\pandands db2 test.py",第45行
quoted = urllib.quote_plus(CONNECTION_STRING)
create_engine('ibm_db_sa+pyodbc:///?odbc_connect={}'.format(quoted)).connect()
无法打开"hashtable_class_help.pxi":找不到文件(file:///c:/git/dashboards/pandas/_libs/hashtable_class_helper.pxi)。
quoted = urllib.quote_plus(CONNECTION_STRING)
create_engine('ibm_db_sa:///?odbc_connect={}'.format(quoted)).connect()
发生异常:sqlalchemy.exc.InterfaceError(ibm_db_dbi.InterfaceError)ibm_db_dbi::InterfaceError:connect要求前五个参数的类型为字符串或unicode(此错误的背景信息:http://sqlalche.me/e/rvf5)中的文件"C:\Git\disables\web_app\pandands db2 test.py",第43行
quoted = urllib.quote_plus(CONNECTION_STRING)
create_engine('ibm_db:///?odbc_connect={}'.format(quoted)).connect()
发生异常:sqlalchemy.exc.NoSuchModuleError无法加载插件:sqlalchemy.方言:ibm_db
quoted = urllib.quote_plus(CONNECTION_STRING)
create_engine('db2:///?odbc_connect={}'.format(quoted)).connect()
发生异常:sqlalchemy.exc.InterfaceError(ibm_db_dbi.InterfaceError)ibm_db_dbi::InterfaceError:connect要求前五个参数的类型为字符串或unicode(此错误的背景信息:http://sqlalche.me/e/rvf5)中的文件"C:\Git\disables\web_app\pandands db2 test.py",第45行
quoted = urllib.quote_plus(CONNECTION_STRING)
create_engine('db2+ibm_db:///?odbc_connect={}'.format(quoted)).connect()
发生异常:sqlalchemy.exc.InterfaceError(ibm_db_dbi.InterfaceError)ibm_db_dbi::InterfaceError:connect要求前五个参数的类型为字符串或unicode(此错误的背景信息:http://sqlalche.me/e/rvf5)
quoted = urllib.quote_plus(CONNECTION_STRING)
create_engine('db2+ibm_db_sa:///?odbc_connect={}'.format(quoted)).connect()
发生异常:sqlalchemy.exc.NoSuchModuleError无法加载插件:sqlalchemy.方言:db2.ibm_db_sa
我终于让它工作了,尽管有点尴尬。我在我的项目中创建了一个空白文件,以安抚我在回答我的问题中显示的一个尝试时收到的消息:
无法打开
'hashtable_class_helper.pxi'
:找不到文件(file:///c:/git/dashboards/pandas/_libs/hashtable_class_helper.pxi
)。
(我的项目文件夹是C:/Git/dashboards
,所以我创建了路径的其余部分。)
有了这个文件,下面的代码现在对我有效了。engine.connect()
有效,但我运行了一个实际的查询来进一步验证它是否有效。记录在案,无论ibm_db_sa
模块是否按照我问题中的一个链接中的建议进行了修改,它似乎都能工作,所以我建议不要使用该模块。请注意,尽管它们不是直接导入的,但您需要安装以下模块:pyodbc
、ibm_db_sa
,可能还有future
(我忘了)。
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
MPBASE AS BASEPA,
COALESCE(SUM(MPQTY), 0) AS PWIP
FROM FUTMODS.MPPROD
WHERE MPOPT <> '*'
GROUP BY MPBASE
"""
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='basepa'
)
print df