Friday, June 08, 2012

SAP HANA y Python - Sí señor!


Ha pasado mucho desde que escribí my último blog sobre Python...15 de Julio del 2011 Tasting the mix of Python and SAP - Volume 3...casi un año...así que pensé que sería buena idea regresar a la acción...pero...sobre que más podría escribir? Empecé a revisar mis opciones y por supuesto pensé rapidamente en SAP HANA. Después de todo, tengo mi propio servidor corriendo en Amazon Web Services así que sonaba como un buen plan.

Al inicio quería utilizar SAP HANA como una conexión ODBC tal como hice con #R en mis primeros dias...pero luego escuché que Python estaba incluído en la instalación del cliente de SAP HANA, así que solo tomó una pequeña investigación, y algunos foros internos de SAP para descubrir que, usar Python y SAP HANA es más fácil de lo que podría haber imaginado...

Primero, tienes que ir a donde tu cliente de SAP HANA está instalado, y luego copiar los 3 archivos de la carpeta hdbcli...


Luego, ve al folder de Python y copia los archivos dentro de la carpeta Lib...


Haz lo mismo con los 2 archivos en la carpeta hdbclient, copialos y pegalos en la carpeta Python/Lib...


Con esto, estamos listos para empezar...descarga cualquier IDE de Python y asigna Python.exe (de la carpeta Python en hdbclient) como el ejecutable de Python.


import dbapi
 
conn = dbapi.connect('ecX-XX-XX-XXX-XXX.compute-1.amazonaws.com',
     30015, 'SYSTEM', 'manager')
 
print conn.isconnected()


Si este pequeño programa imprime "TRUE" en la pantalla, significa que la conexión está lista.

Ve a http://pypi.python.org/pypi/setuptools#windows y copia el archivo ez_setup.py dentro de tu carpeta de Python. Ejecuta en la línea de comandos Python ez_setup.py para instalar las herramientas y luego agrega el directorio "full path/Python/Scripts" a tus variables de entorno en las variables del sistema de Windows...

Con esto, puedes llamar directamente a Easy_Install...el cual vamos a necesitar para poder instalar Bottle, un Web Micro framework de Python.

En la linea de comandos, escribe:

easy_install -U bottle

Con eso, estamos listos para comenzar


from bottle import get, post, request, run, redirect, route
import dbapi
import time
 
 
@get('/login')
def login_form():
    return '''<DIV ALIGN='CENTER'><BR><BR><BR><BR>
                <H1>Python (Bottle) & SAP HANA</H1>
                <BR><TABLE BORDER='1' BORDERCOLOR='BLUE'
                     BGCOLOR='WHITE'>
                <FORM METHOD='POST'>
                <TR><TD>Server</TD><TD>
                <INPUT TYPE='TEXT' NAME='Server'></TD></TR>
                <TR><TD>Port</TD><TD>
                <INPUT TYPE='TEXT' NAME='Port'></TD></TR>
                <TR><TD>User</TD><TD>
                <INPUT TYPE='TEXT' NAME='User'></TD></TR>
                <TR><TD>Password</TD>
                <TD><INPUT TYPE='PASSWORD' NAME='Passwd'></TD></TR>
                <TR><TD COLSPAN='2' ALIGN='CENTER'>
                <INPUT TYPE='SUBMIT' value='Log In' NAME='LOG_IN'>
                <INPUT TYPE='RESET' value='Clear'></TD></TR>
                </FORM>
                <TABLE>
              </DIV>'''
 
 
@post('/login')
def login_submit():
    global cur
    Server = request.forms.get('Server')
    Port = request.forms.get('Port')
    User = request.forms.get('User')
    Passwd = request.forms.get('Passwd')
    Port = int(Port)
    conn = dbapi.connect(Server, Port, User, Passwd)
    cur = conn.cursor()
    redirect("/parameters")
 
 
@get('/parameters')
def choose_parameters():
    global cur
    query = "SELECT CARRID,CARRNAME FROM SFLIGHT.SCARR WHERE MANDT = 300"
    ret = cur.execute(query)
    ret = cur.fetchall()
    output = "'<CENTER><FORM METHOD='POST'>"
    output += "Carrier <SELECT NAME='Carrid'>"
    for row in ret:
        carrid = str(row[0])
        carrname = str(row[1])
        output += "<OPTION VALUE='%s'>%s</OPTION>" % (carrid, carrname)
    output += "</SELECT>"
    query = "SELECT DISTINCT CITYFROM FROM SFLIGHT.SPFLI WHERE MANDT = 300"
    ret = cur.execute(query)
    ret = cur.fetchall()
    output += "City From<SELECT NAME='Cityfrom'>"
    for row in ret:
        cityfrom = str(row[0])
        output += "<OPTION VALUE='%s'>%s</OPTION>" % (cityfrom, cityfrom)
    output += "</SELECT>"
    output += "<INPUT TYPE='SUBMIT' value='Show Query' NAME='show_query'>"
    output += " </FORM></CENTER>"
    return output
 
 
@post('/parameters')
def show_query():
    counter = 0
    start = time.clock()
    carrid = request.forms.get('Carrid')
    cityfrom = request.forms.get('Cityfrom')
    query = '''SELECT SBOOK.CARRID,SBOOK.CONNID,FLDATE,
                PASSNAME,CITYFROM,CITYTO
                FROM SFLIGHT.SBOOK INNER JOIN SFLIGHT.SPFLI
                ON SBOOK.CONNID = SPFLI.CONNID
                WHERE SBOOK.CARRID = '%s' AND CITYFROM = '%s'
                AND PASSNAME <> ''
                AND SBOOK.MANDT = 300
                AND year(FLDATE) = 2012
                ORDER BY FLDATE DESC''' % (carrid, cityfrom)
    ret = cur.execute(query)
    ret = cur.fetchall()
    output = "<DIV ALIGN='CENTER'><TABLE BORDER='1'>"
    output += "<TR BGCOLOR='#B9C9FE'>"
    output += "<TH>Carrier</TH><TH>Connection</TH>"
    output += "<TH>Flight Date</TH><TH>Passenger Name</TH>"
    output += "<TH>City From</TH><TH>City To</TH>"
    output += "</TR>"
    for row in ret:
        counter += 1
        carrid = str(row[0])
        connid = str(row[1])
        fldate = str(row[2])
        passname = row[3].encode('utf-8')
        cityfrom = row[4].encode('utf-8')
        cityto = row[5].encode('utf-8')
        output += "<TR BGCOLOR='#E8EDFF'>"
        output += '''<TD>%s</TD><TD>%s</TD>
                         <TD>%s</TD><TD>%s</TD>
                         <TD>%s</TD><TD>%s</TD>''' 
        % (carrid, connid, fldate, passname, cityfrom, cityto)
        output += "</TR>"
    output += "</TABLE>"
    end = time.clock()
    time_taken = end - start
    output += "<H1>%s records in %s seconds</H1></DIV>" 
              % (counter, time_taken)
    return output
 
run(host='localhost', port=8080)

Cuando ejecutamos este código, el servidor Web Server de Bottle va a comenzar, así que necesitamos ir a http://localhost:8080/login para comenzar la instalación.


Necesitamos por supuesto logearnos -;)




Podemos elegir un Carrier y el City From para nuestra consulta (Por supuesto, ambas listas son llenadas con data que viene de SAP HANA).



Mostremos la consulta en una bonita tabla...



Tomó un poco más de 3 seconds para recuperar la data de SAP HANA y luego imprimirla en Python. Casi 3K registros en 3 segundos? Eso es velocidad!...especialmente considerando que Python es no es exactamente la herramienta más veloz del mercado -:)

Espero que le haya gustado este blog, puesto que yo realmente disfrute trabajar en el. Es siempre una gran experiencia utilizar Python, SAP HANA o cualquier otros lenguaje de programación para desarrollar algo nuevo -;) Saludos, Blag.

2 comments:

Anonymous said...

Muy buen blog, te felicito, ahora bien, una pregunta, estoy haciendo algo con phonegap y quería saber si hay una forma de conectarlo con SAP como haces con Phyton o Rubi.

Saludos

Alvaro "Blag" Tejada Galindo said...

Hasta ahora no lo hecho pero aqui hay un par de blogs muy utiles:

http://scn.sap.com/community/technology-innovation/blog/2012/05/11/sapui5--building-mobile-apps-together-with-phonegap

http://scn.sap.com/people/pedro.lima/blog/2012/03/29/simple-phonegap-logon-app-for-sap-mobile-applications

Saludos,

Blag.