如何使用 SQLAlchemy 访问 AS/400?
How do I access AS/400 using SQLAlchemy?
简短版: 请告诉我如何通过 SQLAlchemy 连接到 AS/400s。
长版
我的最终目标是加入来自 SQL 服务器和 AS/400 的数据,以显示在 Flask Python 应用程序中。我的方法是将每个数据库中的数据放入 Pandas 数据帧中,然后可以将其连接并输出为 JSON。如果有人有更好的方法,请随时发表评论。我尝试这样做的方式的问题是 Pandas.read_sql_query()
依赖于 SQLAlchemy,而让 SQLAlchemy 与 AS/400 一起工作被证明是相当困难的。
- AS/400 是 7.2 版,但我可能会尝试连接的另一个是 5.1 版。
- 我正在尝试从我的电脑访问它,我的电脑是 运行 Windows 7,我有 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/
- SqlAlchemy equivalent of pyodbc connect string using FreeTDS
以下是我收集的一些失败尝试和相应的错误消息。我不知道第一部分要放什么(“something+something//...
”),要指定哪个端口(446?8471?别的什么?什么都没有?),是否使用服务器的名称或 IP 地址,或者是否为 create_engine()
使用连接字符串样式参数,所以我一直在尝试我能想到的每一种组合。我尝试按照上面第二个 link 中的建议修改 AS400Dialect_pyodbc
class,之后我再次尝试重新 运行 一些失败的尝试。我可能会继续尝试,但此时我只是在原地打转。
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()
Exception has occurred: sqlalchemy.exc.InterfaceError
(pyodbc.InterfaceError) ('IM002', u'[IM002] [Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified (0) (SQLDriverConnect)') (Background on this error at: http://sqlalche.me/e/rvf5)
File "C:\Git\dashboards\web_app\pandas db2 test.py", line 43, in
create_engine('ibm_db_sa://username:password@ip_address:446/database_name').connect()
Exception has occurred: sqlalchemy.exc.OperationalError
(ibm_db_dbi.OperationalError) ibm_db_dbi::OperationalError: [IBM][CLI Driver] SQL30061N The database alias or database name "database_name " was not found at the remote node. SQLSTATE=08004\r SQLCODE=-30061 (Background on this error at: http://sqlalche.me/e/e3q8)
File "C:\Git\dashboards\web_app\pandas db2 test.py", line 43, in
create_engine('ibm_db_sa://username:password@server_name:446/database_name').connect()
Exception has occurred: sqlalchemy.exc.OperationalError
(ibm_db_dbi.OperationalError) ibm_db_dbi::OperationalError: [IBM][CLI Driver] SQL1336N The remote host "server_name" was not found. SQLSTATE=08001\r SQLCODE=-1336 (Background on this error at: http://sqlalche.me/e/e3q8create_engine('ibm_db_sa://username:password@ip_address:446/server_name.database_name').connect()
create_engine('ibm_db_sa://username:password@ip_address:446/server_name.database_name').connect()
Exception has occurred: sqlalchemy.exc.OperationalError
(ibm_db_dbi.OperationalError) ibm_db_dbi::OperationalError: [IBM][CLI Driver] SQL30061N The database alias or database name "server_name.database_name " was not found at the remote node. SQLSTATE=08004\r SQLCODE=-30061 (Background on this error at: http://sqlalche.me/e/e3q8)
create_engine('db2+ibm_db://username:password@ip_address:446/server_name.database_name').connect()
Exception has occurred: sqlalchemy.exc.OperationalError
(ibm_db_dbi.OperationalError) ibm_db_dbi::OperationalError: [IBM][CLI Driver] SQL30061N The database alias or database name "server_name.database_name " was not found at the remote node. SQLSTATE=08004\r SQLCODE=-30061 (Background on this error at: http://sqlalche.me/e/e3q8)
File "C:\Git\dashboards\web_app\pandas db2 test.py", line 45, in
create_engine('db2+ibm_db://username:password@ip_address:446/database_name').connect()
Exception has occurred: sqlalchemy.exc.OperationalError
(ibm_db_dbi.OperationalError) ibm_db_dbi::OperationalError: [IBM][CLI Driver] SQL30061N The database alias or database name "database_name " was not found at the remote node. SQLSTATE=08004\r SQLCODE=-30061 (Background on this error at: http://sqlalche.me/e/e3q8)
File "C:\Git\dashboards\web_app\pandas db2 test.py", line 45, in
create_engine('db2+ibm_db://username:password@ip_address/database_name').connect()
Exception has occurred: sqlalchemy.exc.OperationalError
(ibm_db_dbi.OperationalError) ibm_db_dbi::OperationalError: [IBM][CLI Driver] SQL30081N A communication error has been detected. Communication protocol being used: "TCP/IP". Communication API being used: "SOCKETS". Location where the error was detected: "ip_address". Communication function detecting the error: "connect". Protocol specific error code(s): "10061", "", "". SQLSTATE=08001\r SQLCODE=-30081 (Background on this error at: http://sqlalche.me/e/e3q8)
create_engine('db2+ibm_db://username:password@server_name:446/database_name').connect()
Exception has occurred: sqlalchemy.exc.OperationalError
(ibm_db_dbi.OperationalError) ibm_db_dbi::OperationalError: [IBM][CLI Driver] SQL1336N The remote host "server_name" was not found. SQLSTATE=08001\r SQLCODE=-1336 (Background on this error at: http://sqlalche.me/e/e3q8)
create_engine('db2+ibm_db://username:password@server_name/database_name').connect()
Exception has occurred: sqlalchemy.exc.OperationalError
(ibm_db_dbi.OperationalError) ibm_db_dbi::OperationalError: [IBM][CLI Driver] SQL1336N The remote host "server_name" was not found. SQLSTATE=08001\r SQLCODE=-1336 (Background on this error at: http://sqlalche.me/e/e3q8)
create_engine('db2+pyodbc://username:password@ip_address:446/database_name').connect()
Exception has occurred: sqlalchemy.exc.InterfaceError
(pyodbc.InterfaceError) ('IM002', u'[IM002] [Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified (0) (SQLDriverConnect)') (Background on this error at: http://sqlalche.me/e/rvf5)
File "C:\Git\dashboards\web_app\pandas db2 test.py", line 45, in
create_engine('db2://username:password@ip_address:446/database_name').connect()
Exception has occurred: sqlalchemy.exc.OperationalError
(ibm_db_dbi.OperationalError) ibm_db_dbi::OperationalError: [IBM][CLI Driver] SQL30061N The database alias or database name "database_name " was not found at the remote node. SQLSTATE=08004\r SQLCODE=-30061 (Background on this error at: http://sqlalche.me/e/e3q8)
File "C:\Git\dashboards\web_app\pandas db2 test.py", line 45, in
quoted = urllib.quote_plus(CONNECTION_STRING)
create_engine('ibm_db_sa+pyodbc:///?odbc_connect={}'.format(quoted)).connect()
Unable to open 'hashtable_class_helper.pxi': File not found
(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()
Exception has occurred: sqlalchemy.exc.InterfaceError
(ibm_db_dbi.InterfaceError) ibm_db_dbi::InterfaceError: connect expects the first five arguments to be of type string or unicode (Background on this error at: http://sqlalche.me/e/rvf5)
File "C:\Git\dashboards\web_app\pandas db2 test.py", line 43, in
quoted = urllib.quote_plus(CONNECTION_STRING)
create_engine('ibm_db:///?odbc_connect={}'.format(quoted)).connect()
Exception has occurred: sqlalchemy.exc.NoSuchModuleError
Cant load plugin: sqlalchemy.dialects:ibm_db
quoted = urllib.quote_plus(CONNECTION_STRING)
create_engine('db2:///?odbc_connect={}'.format(quoted)).connect()
Exception has occurred: sqlalchemy.exc.InterfaceError
(ibm_db_dbi.InterfaceError) ibm_db_dbi::InterfaceError: connect expects the first five arguments to be of type string or unicode (Background on this error at: http://sqlalche.me/e/rvf5)
File "C:\Git\dashboards\web_app\pandas db2 test.py", line 45, in
quoted = urllib.quote_plus(CONNECTION_STRING)
create_engine('db2+ibm_db:///?odbc_connect={}'.format(quoted)).connect()
Exception has occurred: sqlalchemy.exc.InterfaceError
(ibm_db_dbi.InterfaceError) ibm_db_dbi::InterfaceError: connect expects the first five arguments to be of type string or unicode (Background on this error at: http://sqlalche.me/e/rvf5)
quoted = urllib.quote_plus(CONNECTION_STRING)
create_engine('db2+ibm_db_sa:///?odbc_connect={}'.format(quoted)).connect()
Exception has occurred: sqlalchemy.exc.NoSuchModuleError
Cant load plugin: sqlalchemy.dialects:db2.ibm_db_sa
我终于让它工作了,虽然有点尴尬。我在我的项目中创建了一个空白文件来安抚我收到的这条消息,以回应我的问题中显示的一种尝试:
Unable to open 'hashtable_class_helper.pxi'
: File not found (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
简短版: 请告诉我如何通过 SQLAlchemy 连接到 AS/400s。
长版
我的最终目标是加入来自 SQL 服务器和 AS/400 的数据,以显示在 Flask Python 应用程序中。我的方法是将每个数据库中的数据放入 Pandas 数据帧中,然后可以将其连接并输出为 JSON。如果有人有更好的方法,请随时发表评论。我尝试这样做的方式的问题是 Pandas.read_sql_query()
依赖于 SQLAlchemy,而让 SQLAlchemy 与 AS/400 一起工作被证明是相当困难的。
- AS/400 是 7.2 版,但我可能会尝试连接的另一个是 5.1 版。
- 我正在尝试从我的电脑访问它,我的电脑是 运行 Windows 7,我有 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/
- SqlAlchemy equivalent of pyodbc connect string using FreeTDS
以下是我收集的一些失败尝试和相应的错误消息。我不知道第一部分要放什么(“something+something//...
”),要指定哪个端口(446?8471?别的什么?什么都没有?),是否使用服务器的名称或 IP 地址,或者是否为 create_engine()
使用连接字符串样式参数,所以我一直在尝试我能想到的每一种组合。我尝试按照上面第二个 link 中的建议修改 AS400Dialect_pyodbc
class,之后我再次尝试重新 运行 一些失败的尝试。我可能会继续尝试,但此时我只是在原地打转。
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()
Exception has occurred: sqlalchemy.exc.InterfaceError (pyodbc.InterfaceError) ('IM002', u'[IM002] [Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified (0) (SQLDriverConnect)') (Background on this error at: http://sqlalche.me/e/rvf5) File "C:\Git\dashboards\web_app\pandas db2 test.py", line 43, in
create_engine('ibm_db_sa://username:password@ip_address:446/database_name').connect()
Exception has occurred: sqlalchemy.exc.OperationalError (ibm_db_dbi.OperationalError) ibm_db_dbi::OperationalError: [IBM][CLI Driver] SQL30061N The database alias or database name "database_name " was not found at the remote node. SQLSTATE=08004\r SQLCODE=-30061 (Background on this error at: http://sqlalche.me/e/e3q8) File "C:\Git\dashboards\web_app\pandas db2 test.py", line 43, in
create_engine('ibm_db_sa://username:password@server_name:446/database_name').connect()
Exception has occurred: sqlalchemy.exc.OperationalError (ibm_db_dbi.OperationalError) ibm_db_dbi::OperationalError: [IBM][CLI Driver] SQL1336N The remote host "server_name" was not found. SQLSTATE=08001\r SQLCODE=-1336 (Background on this error at: http://sqlalche.me/e/e3q8create_engine('ibm_db_sa://username:password@ip_address:446/server_name.database_name').connect()
create_engine('ibm_db_sa://username:password@ip_address:446/server_name.database_name').connect()
Exception has occurred: sqlalchemy.exc.OperationalError (ibm_db_dbi.OperationalError) ibm_db_dbi::OperationalError: [IBM][CLI Driver] SQL30061N The database alias or database name "server_name.database_name " was not found at the remote node. SQLSTATE=08004\r SQLCODE=-30061 (Background on this error at: http://sqlalche.me/e/e3q8)
create_engine('db2+ibm_db://username:password@ip_address:446/server_name.database_name').connect()
Exception has occurred: sqlalchemy.exc.OperationalError (ibm_db_dbi.OperationalError) ibm_db_dbi::OperationalError: [IBM][CLI Driver] SQL30061N The database alias or database name "server_name.database_name " was not found at the remote node. SQLSTATE=08004\r SQLCODE=-30061 (Background on this error at: http://sqlalche.me/e/e3q8) File "C:\Git\dashboards\web_app\pandas db2 test.py", line 45, in
create_engine('db2+ibm_db://username:password@ip_address:446/database_name').connect()
Exception has occurred: sqlalchemy.exc.OperationalError (ibm_db_dbi.OperationalError) ibm_db_dbi::OperationalError: [IBM][CLI Driver] SQL30061N The database alias or database name "database_name " was not found at the remote node. SQLSTATE=08004\r SQLCODE=-30061 (Background on this error at: http://sqlalche.me/e/e3q8) File "C:\Git\dashboards\web_app\pandas db2 test.py", line 45, in
create_engine('db2+ibm_db://username:password@ip_address/database_name').connect()
Exception has occurred: sqlalchemy.exc.OperationalError (ibm_db_dbi.OperationalError) ibm_db_dbi::OperationalError: [IBM][CLI Driver] SQL30081N A communication error has been detected. Communication protocol being used: "TCP/IP". Communication API being used: "SOCKETS". Location where the error was detected: "ip_address". Communication function detecting the error: "connect". Protocol specific error code(s): "10061", "", "". SQLSTATE=08001\r SQLCODE=-30081 (Background on this error at: http://sqlalche.me/e/e3q8)
create_engine('db2+ibm_db://username:password@server_name:446/database_name').connect()
Exception has occurred: sqlalchemy.exc.OperationalError (ibm_db_dbi.OperationalError) ibm_db_dbi::OperationalError: [IBM][CLI Driver] SQL1336N The remote host "server_name" was not found. SQLSTATE=08001\r SQLCODE=-1336 (Background on this error at: http://sqlalche.me/e/e3q8)
create_engine('db2+ibm_db://username:password@server_name/database_name').connect()
Exception has occurred: sqlalchemy.exc.OperationalError (ibm_db_dbi.OperationalError) ibm_db_dbi::OperationalError: [IBM][CLI Driver] SQL1336N The remote host "server_name" was not found. SQLSTATE=08001\r SQLCODE=-1336 (Background on this error at: http://sqlalche.me/e/e3q8)
create_engine('db2+pyodbc://username:password@ip_address:446/database_name').connect()
Exception has occurred: sqlalchemy.exc.InterfaceError (pyodbc.InterfaceError) ('IM002', u'[IM002] [Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified (0) (SQLDriverConnect)') (Background on this error at: http://sqlalche.me/e/rvf5) File "C:\Git\dashboards\web_app\pandas db2 test.py", line 45, in
create_engine('db2://username:password@ip_address:446/database_name').connect()
Exception has occurred: sqlalchemy.exc.OperationalError (ibm_db_dbi.OperationalError) ibm_db_dbi::OperationalError: [IBM][CLI Driver] SQL30061N The database alias or database name "database_name " was not found at the remote node. SQLSTATE=08004\r SQLCODE=-30061 (Background on this error at: http://sqlalche.me/e/e3q8) File "C:\Git\dashboards\web_app\pandas db2 test.py", line 45, in
quoted = urllib.quote_plus(CONNECTION_STRING)
create_engine('ibm_db_sa+pyodbc:///?odbc_connect={}'.format(quoted)).connect()
Unable to open 'hashtable_class_helper.pxi': File not found (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()
Exception has occurred: sqlalchemy.exc.InterfaceError (ibm_db_dbi.InterfaceError) ibm_db_dbi::InterfaceError: connect expects the first five arguments to be of type string or unicode (Background on this error at: http://sqlalche.me/e/rvf5) File "C:\Git\dashboards\web_app\pandas db2 test.py", line 43, in
quoted = urllib.quote_plus(CONNECTION_STRING)
create_engine('ibm_db:///?odbc_connect={}'.format(quoted)).connect()
Exception has occurred: sqlalchemy.exc.NoSuchModuleError Cant load plugin: sqlalchemy.dialects:ibm_db
quoted = urllib.quote_plus(CONNECTION_STRING)
create_engine('db2:///?odbc_connect={}'.format(quoted)).connect()
Exception has occurred: sqlalchemy.exc.InterfaceError (ibm_db_dbi.InterfaceError) ibm_db_dbi::InterfaceError: connect expects the first five arguments to be of type string or unicode (Background on this error at: http://sqlalche.me/e/rvf5) File "C:\Git\dashboards\web_app\pandas db2 test.py", line 45, in
quoted = urllib.quote_plus(CONNECTION_STRING)
create_engine('db2+ibm_db:///?odbc_connect={}'.format(quoted)).connect()
Exception has occurred: sqlalchemy.exc.InterfaceError (ibm_db_dbi.InterfaceError) ibm_db_dbi::InterfaceError: connect expects the first five arguments to be of type string or unicode (Background on this error at: http://sqlalche.me/e/rvf5)
quoted = urllib.quote_plus(CONNECTION_STRING)
create_engine('db2+ibm_db_sa:///?odbc_connect={}'.format(quoted)).connect()
Exception has occurred: sqlalchemy.exc.NoSuchModuleError Cant load plugin: sqlalchemy.dialects:db2.ibm_db_sa
我终于让它工作了,虽然有点尴尬。我在我的项目中创建了一个空白文件来安抚我收到的这条消息,以回应我的问题中显示的一种尝试:
Unable to open
'hashtable_class_helper.pxi'
: File not found (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