Подключение к IBM AS400 server для операций с базами данных зависает
Я пытаюсь поговорить с AS400 в Python. Цель состоит в том, чтобы использовать 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 говорит делать, Я не получаю никакой ошибки, никакого тайм-аута, никакого ответа вообще. Я оставил сценарий работает более двадцати минут, и он просто сидит там, ничего не делая. Он активен, потому что я вообще не могу использовать командную строку, но он никогда не дает мне никакой обратной связи.
этот же 400 используется компанией, в которой я работаю каждый день, для ведения журнала, электронной почты и (много) использования базы данных, поэтому я знаю, что это работает. Программное обеспечение, которое мы используем, которое разговаривает с базой данных за кулисами, отлично работает на моей машине. Это говорит мне, что мой драйвер хорош, сетевые настройки правы и так далее. Я даже могу телнеть в 400 отсюда.
Я нахожусь в списках электронной почты SQLAlchemy и ibm_db и общаюсь с ними в течение нескольких дней об этой проблеме. Я также гуглил его так много, что у меня заканчиваются не посещенные ссылки в результатах поиска. Кажется, ни у кого нет проблемы с тем, что соединение висит бесконечно. Если есть что-то, что я могу попробовать в Python, я попробую. Я не имею дела С 400 непосредственно, но я могу спросить парня, который делает это проверьте / настройте все, что мне нужно. Как я уже сказал, несколько рабочих станций могут разговаривать с базой данных 400 без проблем, а запросы запускаются против библиотеки, к которой я хочу получить доступ, работают нормально, если запускаются из самого 400. Если у кого-то есть какие-то предложения, я был бы очень признателен, услышав их. Спасибо!
3 ответов
на README для 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
теперь одним из методов соединения SQLAlchemy является pyodbc
, так что я думаю, что если вы можете установить соединение с помощью pyodbc
непосредственно, вы можете как-то настроить SQLAlchemy, чтобы сделать то же самое. Но я сам не пользователь SQLAlchemy, поэтому у меня нет примера кода для этого.
обновление
мне удалось подключить SQLAlchemy к нашему IBM i и выполнить прямые запросы SQL. Другими словами, чтобы получить примерно такую же функциональность, как просто использовать PyODBC напрямую. я не тестировал никаких других функций SQLAlchemy. что я сделал, чтобы настроить соединение на моей машине Windows 7:
-
установить
ibm_db_sa
как диалект SQLAlchemy
Вы можете использоватьpip
для этого, но я сделал это нетехнологичным способом:- скачать
ibm_db_sa
из PyPI.
Как это написание, последняя версия 0.3.2, загружена на 2014-10-20. Вполне возможно, что более поздние версии будут либо исправлены, либо сломаны по-разному (поэтому в будущем изменения, которые я собираюсь описать, могут быть ненужными, или они могут не работать). - Распаковать архив (
ibm_db_sa-0.3.2.tar.gz
) и скопируйте заключенный на
- скачать
чтобы узнать, какой порт необходим, нужно посмотреть записи таблицы служб в IBM i.
ваш IBM i парень может использовать графический интерфейс iNav или зеленый экран работать с командой Service Table Entry (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 используется для операций "распределенная БД".
исходя из этого нить, чтобы использовать ibm_db для подключения к DB2 на IBM i, вам нужен продукт IBM Connect; это коммерческий пакет, за который нужно заплатить.
этой нить предлагает использовать ODBC через модуль pyodbc. Он также предполагает, что JDBC через инструментарий jt400 также может работать.
вот пример работы с as400, sqlalchemy и панд. Этот exammple взять кучу файлов CSV и вставить с пандами/с SQLAlchemy. Работает только для windows, в linux драйвер odbc i серии segfaults (Centos 7 и Debian 9 x68_64)
клиент-это Windows 10.
моя версия as400-7.3
Python-это 2.7.14
установлен с pip: панды, pyodbc, imb_db_sa, sqlalchemy
вам нужно установить I access for windows из ftp://public.dhe.ibm.com/as400/products/clientaccess/win32/v7r1m0/servicepack/si66062/
Aditionally модификации @JohnY on pyodbc.py C:\Python27\Lib\site-packages\sqlalchemy\dialects\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)
надеюсь, что это помогает.