2016-02-17 22 views
8

Próbuję rozmawiać z AS400 w Pythonie. Celem jest użycie SQLAlchemy, ale gdy nie mogłem tego zrobić, cofnąłem się do bardziej podstawowego skryptu, używając tylko ibm_db zamiast ibm_db_sa.Połączenie z serwerem IBM AS400 dla operacji na bazach danych zawiesza się

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() 

Problem wydaje się być portem. Jeśli korzystam z 50000, które widzę we wszystkich przykładach, pojawia się błąd. Jeśli użyję 446, pojawi się błąd. Najbardziej zastanawiające jest to, że jeśli użyję 8471, co IBM says to do, nie otrzymam błędu, żadnego timeoutu, żadnej odpowiedzi. Pozostawiłem skrypt działający przez ponad dwadzieścia minut, a on po prostu siedzi, nic nie robiąc. Jest aktywny, ponieważ nie mogę w ogóle korzystać z wiersza poleceń, ale nigdy nie daje mi żadnej informacji zwrotnej.

Ten sam 400 jest używany przez firmę, w której pracuję na co dzień, do logowania, wysyłania wiadomości e-mail i (dużej ilości) użycia bazy danych, więc wiem, że to działa. Oprogramowanie, z którego korzystamy, rozmawia z bazą danych za kulisami, działa dobrze na moim komputerze. To mówi mi, że mój sterownik jest dobry, ustawienia sieciowe są poprawne i tak dalej. Mogę nawet telnetować się do 400 stąd.

Jestem na listach e-mail SQLAlchemy i ibm_db i komunikuję się z nimi przez wiele dni o tym problemie. Również googlowałem tak bardzo, że w wynikach wyszukiwania zaczyna brakować linków, które nie odwiedziły mnie. Wydaje się, że nikt nie ma problemu z zawieszeniem się połączenia na czas nieokreślony. Jeśli jest coś, co mogę wypróbować w Pythonie, spróbuję. Nie radzę sobie bezpośrednio z 400, ale mogę poprosić gościa, który sprawdza/konfiguruje to, co jest mi potrzebne. Jak już powiedziałem, kilka stacji roboczych może bez problemu rozmawiać z bazą danych w wersji 400, a zapytania uruchamiane w bibliotece, do której chcę uzyskać dostęp, działają poprawnie, jeśli są uruchamiane z samego 400. Jeśli ktoś ma jakieś sugestie, bardzo bym to docenił. Dzięki!

+0

Jeśli zrobiłeś postępy w tej sprawie, byłoby wspaniale, gdybyś to udostępnił tutaj. Szukałem kodu 'ibm_db_sa', aby zobaczyć czy coś wyskoczyło na mnie, i coś takiego: moduł' 'pirodbc.py' wewnątrz' ibm_db_sa'] (https://github.com/ibmdb/python-ibmdbsa /blob/master/ibm_db_sa/ibm_db_sa/pyodbc.py) ma klasę o nazwie "AS400Dialect_pyodbc" i ma odpowiednią wartość dla 'pyodbc_driver_name'. Tak więc co najmniej * podjęto * próbę, aby SQLAlchemy działało z DB2 for i. –

+0

Nie mam. Cóż, moja aplikacja się porusza, ale na razie polegam tylko na pyodbc. Próbowałem użyć SA, łącząc się z pyodbc, a następnie przekazując funkcję, która łączy się z create_engine, ale to nie zadziałało. – AH16

+0

Ile nie ma dodatkowych funkcji SQLAlchemy? A jak dobrze (a) znasz Python i (b) znasz SQLAlchemy? Powodem, dla którego pytam jest to, że poprzez nieco więcej szturchań i szturchań, udało mi się uzyskać 'create_engine()', aby pomyślnie utworzyć silnik, i użyć tego silnika do robienia nagich zapytań SQL. Innymi słowy, mogę sprawić, że SQLAlchemy będzie służyć jako wyjątkowo zawiły pakowacz PyODBC, bez żadnej wartości dodanej. Cieszę się, że mogę podzielić się swoimi odkryciami, ale nigdy nie korzystałem z ORM, więc mogą pojawić się kolejne problemy, zanim będzie można w pełni wykorzystać SQLAlchemy. –

Odpowiedz

8

W katalogu "Obsługiwana baza danych" wyszczególnione jest tylko DB2 dla Linux/Unix/Windows. Dlatego najprawdopodobniej nie działa w przypadku produktu DB2 for i, przynajmniej nie od razu po wyjęciu z pudełka.

Po stwierdzeniu, że masz produkt IBM System i Access dla systemu Windows, zdecydowanie zalecamy użycie jednego ze sterowników, który jest z nim zgodny (ODBC, OLEDB lub ADO.NET, o czym wspomniały @Charles).

Osobiście zawsze używam ODBC z pyodbc lub pypyodbc. Każda z nich działa dobrze.Prosty przykład:

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 

Teraz jedna z metod połączenia sqlalchemy jest pyodbc, więc myślę, że jeśli można nawiązać połączenie przy użyciu pyodbc bezpośrednio, można jakoś skonfigurować SQLAlchemy zrobić to samo. Ale sam nie jestem użytkownikiem SQLAlchemy, więc nie mam na to kodu przykładowego.

UPDATE

udało mi się dostać SQLAlchemy aby połączyć się z naszym IBM i oraz wykonywanie prostych zapytań SQL. Innymi słowy, aby uzyskać tę samą funkcjonalność, co bezpośrednio wykorzystując PyODBC. Nie testowałem żadnych innych funkcji SQLAlchemy. Co zrobiłem, aby skonfigurować połączenie na moim Windows 7 maszyny:

  • Install ibm_db_sa jako dialekt sqlalchemy
    może być w stanie wykorzystać pip za to, ale ja mu low-tech sposób:

    1. Pobierz ibm_db_sa z PyPI.
      Od tego momentu najnowsza wersja to 0.3.2, która została przesłana 2014-10-20. Można sobie wyobrazić, że późniejsze wersje będą albo naprawiane, albo łamane na różne sposoby (więc w przyszłości modyfikacje, które zamierzam opisać, mogą być niepotrzebne lub mogą nie działać).
    2. Rozpakuj archiwum (ibm_db_sa-0.3.2.tar.gz) i skopiuj załączony katalog ibm_db_sa do katalogu sqlalchemy\dialects.
  • Zmienić sqlalchemy\dialects\ibm_db_sa\pyodbc.py

    • Dodaj metodę initialize() do klasy
      Punkt ten ma zastąpić metodę o tej samej nazwie w DB2Dialect, co AS400Dialect_pyodbc dziedziczy od AS400Dialect_pyodbc. Problem polega na tym, że DB2Dialect.initialize() próbuje ustawić atrybuty dbms_ver i dbms_name, z których żadna nie jest dostępna lub istotna podczas łączenia się z IBM i przy użyciu PyODBC (o ile wiem).
    • Dodaj nazwę moduł poziomie dialect i ustawić go do klasy AS400Dialect_pyodbc

kod na powyższe modyfikacje powinny iść na końcu pliku, a wygląda tak:

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

dialect = AS400Dialect_pyodbc 

Zwróć uwagę na wcięcie! Pamiętaj, że metoda initialize() musi należeć do klasy AS400Dialect_pyodbc, a dialect musi być globalna dla modułu.

Wreszcie, trzeba dać Stwórca Silnik właściwy URL:

'ibm_db_sa+pyodbc://username:[email protected]/*local'

(oczywiście, zastępować prawidłowych wartości username, password i host.)

To wszystko. W tym momencie powinieneś być w stanie stworzyć silnik, połączyć się z i i wykonać zwykły SQL poprzez SQLAlchemy. Myślę, że wiele rzeczy z ORM również powinno działać w tym momencie, ale nie zweryfikowałem tego.

+0

Cóż, to chyba działa! Mogę uruchamiać zapytania i, oczywiście, łączyć się! Jest tak dużo informacji o używaniu ibm_db do tych rzeczy, że jestem zaskoczony, że prosty pyodbc wykonał zadanie za minutę, podczas gdy ibm_db/ibm_db_sa nie działa od wielu dni. Teraz muszę po prostu dowiedzieć się, jak podłączyć to z powrotem do sqlalchemy. Dzięki za pomoc. Również dzięki @Charles, za wszystkie twoje odpowiedzi w ciągu ostatnich kilku dni. – AH16

+0

Mam ten sam problem, ale mam tylko dostęp do serwera linuksowego. Zakładam, że pyodbc działa tylko na systemach Windows. Czy znasz rozwiązanie dla Linuksa? – Jimmy

+1

@ Jimmy - może znajdziesz coś pożytecznego [tutaj] (http://stackoverflow.com/questions/2960339/unable-to-install-pyodbc-on-linux). –

1

Aby dowiedzieć się, jaki port jest potrzebny, należy przejrzeć wpisy w tabeli usług w systemie IBM i.

Twój IBM i facet może używać iNav GUI lub ekranu zieloną Praca z zastawy stołowej wejście (WRKSRVTBLE) Komenda

powinien dostać ekran tak:

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  

domyślny port dla DB jest rzeczywiście 8471. Chociaż drda jest używana do operacji "rozproszonych db".

Na tej podstawie thread, aby użyć ibm_db do połączenia z produktem DB2 w systemie IBM i, potrzebny jest produkt IBM Connect; który jest pakietem komercyjnym, za który trzeba zapłacić.

Ten thread sugeruje użycie ODBC przez moduł pyodbc. Sugeruje to również, że JDBC za pośrednictwem zestawu narzędzi JT400 może również działać.

+0

Dzięki za szybką odpowiedź. Poproszę ich o sprawdzenie portów, ale powiedziano mi, że nikt ich nie zmodyfikował. Jeśli spróbuję 446 zamiast 8471, otrzymam coś w stylu "wykonanie instrukcji SQL nie powiodło się z powodu błędu w strumieniu danych komunikacyjnych, który wpłynie na pomyślne wykonanie kolejnych poleceń i instrukcji SQL."SQLCode = -30020-0206, SQLState = 58009 – AH16

+0

Zapomniałem powiedzieć, że mam zainstalowane wszystkie niezbędne sterowniki i produkty IBM (nasza firma ma do nich dostęp) .W rzeczywistości inne oprogramowanie, z którego korzystamy, musi rozmawiać z 400 seriami na moim komputerze bez problemów, więc jestem przekonany, że mam całe niezbędne oprogramowanie. Ponadto otrzymałem potwierdzenie, że nasze porty są skonfigurowane podobnie jak standardowe (tak więc 446 i 8471 to dwa możliwe). , 8471 to ten, który się zawiesza i nigdy nie ma błędów ani nie wychodzi, a 446 błędów w ciągu dwóch sekund. – AH16

+0

Aby dodać trochę do odpowiedzi Charlesa, prawie wszystkie przykłady w sieci dotyczą DB2 LUW lub DB2 dla systemu mainframe. trzeba przetestować dla DB2 for IBM i. Nie jest to również AS400 i jest to bardzo ważne, gdy szuka się pomocy - jeśli ktoś zamieścił coś w systemie AS/400, jest albo starożytny, albo JEDYNYM, i żadne z nich nie będzie pomocne. Wypróbuj system IBM i, a nawet iSeries: –

0

Oto przykład pracy z as400, sqlalchemy i pandami. To polecenie należy pobrać kilka plików CSV i wstawić przy użyciu pand/sqlalchemy. działa tylko dla systemu Windows, na Linux naruszenia ochrony pamięci sterownika ODBC (I seria CentOS 7 i Debiana 9 x68_64)

Client Windows 10.

Moja wersja AS400 jest 7,3

Python jest 2.7.14

zainstalowany pIP pand, pyodbc, imb_db_sa, sqlalchemy

Musisz zainstalować mam dostępu do okien z ftp://public.dhe.ibm.com/as400/products/clientaccess/win32/v7r1m0/servicepack/si66062/

Aditionally modyfikacje autorstwa @JohnY na pyodbc.py C: \ Python27 \ Lib \ site-packages \ sqlalchemy \ dialektów \ ibm_db_sa \ pyodbc.py Zmień linię 99 do

pyodbc_driver_name = "IBM i Access ODBC Driver" 

ODBC kierowca zmienił to Nazwa.

#!/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:[email protected]_SERVER/*local') 
    datastore2.to_sql('table', engine, schema='SCHEMA', chunksize=1000, if_exists='append', index=False) 

Mam nadzieję, że to pomaga.