Как получить доступ к AS / 400 с помощью SQLAlchemy? - PullRequest
0 голосов
/ 17 января 2019

Короткая версия: Скажите, пожалуйста, как подключиться к AS / 400s с помощью SQLAlchemy.

Длинная версия

Моя конечная цель - объединить данные из SQL Server и AS / 400 для отображения в приложении Flask Python.Мой подход состоял в том, чтобы получать данные из каждой базы данных в кадры данных Pandas, которые затем можно объединять и выводить в виде JSON.Если у кого-то есть лучший подход, не стесняйтесь оставлять комментарии.Проблема с тем, как я пытаюсь это сделать, заключается в том, что Pandas.read_sql_query() опирается на SQLAlchemy, и заставить SQLAlchemy работать с AS / 400 довольно сложно.

  • Версия AS / 4007.2, хотя другой, к которой я, вероятно, попытаюсь подключиться, является версия 5.1.
  • Я пытаюсь получить к ней доступ с моего компьютера, на котором установлена ​​Windows 7 и есть модули Access 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.

Я прочитал эти ресурсысреди прочего и попытался применить свои методики:

Ниже приведены некоторые неудачные попытки и соответствующие сообщения об ошибках, которые я собрал.Я не знаю, что поставить для первой части ("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 \"dashboards \ web_app \ pandas 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 Псевдоним базы данных или имя базы данных «имя_базы_данных» не найдено на удаленном узле. SQLSTATE = 08004 \ r SQLCODE = -30061 (фон этой ошибки: http://sqlalche.me/e/e3q8) файл "C:\ Git \ dashboards \ web_app \ pandas 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] SQL1336N Удаленный хост "имя_сервера" не найден.SQLSTATE = 08001 \ r SQLCODE = -1336 (Справочная информация об этой ошибке: 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()

Исключение: sqlalchemy.exc.OperationalError (ibm_db_dbi.OperationalError) ibm_db_dbi:: OperationalError: [IBM] [Драйвер CLI] SQL30061N На удаленном узле не найден псевдоним базы данных или имя базы данных «имя_сервера.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 Псевдоним базы данных или имя базы данных "имя_сервера".имя_базы_данных "не найдено на удаленном узле. SQLSTATE = 08004 \ r SQLCODE = -30061 (Справочная информация об этой ошибке: http://sqlalche.me/e/e3q8) Файл" C: \ Git \ dashboards \ web_app \ pandas 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] SQL30061N Псевдоним базы данных или имя базы данных «имя_базы_данных» не найдено на удаленном узле. SQLSTATE = 08004 SQLCODE = -30061 (Справочная информация об этой ошибке: http://sqlalche.me/e/e3q8) Файл "C: \ Git \ dashboards \ web_app \ pandas 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] 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] SQL1336N Удаленный хост "имя_сервера" не найден. 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] SQL1336N Удаленный хост "имя_сервера" не найден. 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 \ dashboards \ web_app \ pandas 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] SQL30061N Псевдоним базы данных или имя базы данных «имя_базы_данных» не найдено на удаленном узле. SQLSTATE = 08004 \ r SQLCODE = -30061 (фон этой ошибки: http://sqlalche.me/e/e3q8) Файл "C: \ Git \ dashboards \ web_app \ pandas db2 test.py", строка 45, в

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

Невозможно открыть 'hashtable_class_helper.pxi': файл не найден (Файл: /// 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 ожидает, что первые пять аргументов будут иметь тип string или unicode (Фон этой ошибки: http://sqlalche.me/e/rvf5) Файл "C: \ Git \ dashboards \ web_app \ pandas db2 test.py", строка 43, в

quoted = urllib.quote_plus(CONNECTION_STRING)
create_engine('ibm_db:///?odbc_connect={}'.format(quoted)).connect()

Исключительная ситуация: sqlalchemy.exc.NoSuchModuleError Не могу загрузить плагин: sqlalchemy.dialects: 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 ожидает, что первые пять аргументов будут иметь тип string или unicode (Фон этой ошибки: http://sqlalche.me/e/rvf5) Файл "C: \ Git \ dashboards \ web_app \ pandas 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 ожидает, что первые пять аргументов будут иметь тип string или 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.dialects: db2.ibm_db_sa

1 Ответ

0 голосов
/ 17 января 2019

У меня наконец получилось, хотя это немного неловко. Я создал пустой файл в своем проекте, чтобы успокоить это сообщение, которое я получал в ответ на одну из попыток, показанных в моем вопросе:

Невозможно открыть '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
...