luni, 24 august 2009

Python SQLAlchemy ORM

A couple of days ago I implemented some Python classes which were supposed to map tables from an Oracle DB. In Java, we can use Hibernate for achieving this. In Python, I chose to use SQLAlchemy framework. In the beginning, I had found the syntax a little confusing but after I understood it everything went smoothly. In the following paragraphs, I'll show how a one-to-may relation can be implemented and also how to use composite keys in SQLAlchemy.
I assume that classes are implemented in da package.

1. In __init__.py file I instantiate sqlalchemy dependency objects.

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

BaseEntity = declarative_base()
strDbURL = "oracle://db_tes:xxx@xe"
objDbEngine = create_engine(strDbURL, echo=False)

Session = sessionmaker(bind=objDbEngine)
Session.configure(bind=objDbEngine)

def getConnection():
return Session()

In this moment, we can start implementing the entities. Every entity can extend BaseEntity. Every time we need a database connection we use getConnection() method. A SQLAlchemy session is similar to a Hibernate session.

2. I define User class which has a composite chei(username and password ---- don't do this in practice: you can safely choose to use serial number as primary key). In this example, I want to show how composite keys are implemented.

from da import BaseEntity
from sqlalchemy import Column,Integer,String,Numeric,DateTime,ForeignKey,Sequence
from sqlalchemy.orm import relation, backref

class User(BaseEntity):
username = Column("username", String, primary_key=True)
password = Column("password", String, primary_key=True)
descriere = Column("descriere", String)

def __init__(self, strUsername, strPassword, strDesc):
self.username = strUsername
self.password = strPassword
self.descriere = strDesc

3. I implement the Address class.

from da import BaseEntity
from sqlalchemy import Column,Integer,String,Numeric,DateTime,ForeignKey,Sequence
from sqlalchemy.orm import relation, backref

class Adress(BaseEntity):
id = Column("id", Integer, Sequence("seq_xxx_id"), primary_key=True)
fk_username = Column("fk_username", String, ForeignKey("utilizatori.username"))
fk_password = Column("fk_password", String, ForeignKey("utilizatori.password"))
street = Column("street", String)
number = Column("number", String)

user = relation("User",
foreign_keys=[fk_username, fk_password],
primaryjoin="User.username == Address.fk_username and "
"User.password == Address.fk_password",
backref="adresses")

def __init__(self, strUser, strPasswd, strStreet, strNumber):
self.fk_username = strUser
self.fk_password = strPassword
self.street = strStreet
self.number = strNumber

Comments: in this example, I try to show the power and flexibility provided by SQLAlchemy. First of all, in every SQLAlchemy entity we'll define the mapped table structure to attributes of the class. Using relation function, we can implement links(foreign keys) to other entities:
  • one-to-one relation
  • one-to-many relation
  • many-to-many relation
We can also use the backref keyword argument to indicate that we want a reference at the other end of relation.

4. After we implemented all the entities, we have to use them. In the folloing example, I show several lines of code that prove the entities functionality:

import da
from da import User, Address

# I select all user from the database
objSes = da.getConnection()
for objUsr, in objSes.query(User).all():
print(objUsr.addresses)

# filter that returns the user with a specific address
for objUsr in objSes.query(User, Address).filter(User.username == Address.fk_username and User.password == Address.fk_password).filter(Address.id == 1).all():
print(objUsr.username)

In conclusion, SQLAlchemy easily maps relational logic to object logic(the scope of any ORM) but it doesn't require a configuration file or annotations(like Hibernate). In addition, writting a query is extremely easy. What was not covered in this tutorial but it is intuitive is entity saving(persist). We use add method of an opened session for adding and updating an entity.

luni, 10 august 2009

Java si Mocking - PowerMock

In previous posts I talked about testing python code through injected dependencies. The same idea can be achieved in Java even if it's a little trickier. After I had studied a couple of mocking libraries for java I decided to use PowerMock because it is very close to mocker library for python. This library improves EasyMock and in the latest release it supports integration with Mockito. It worth mentioning some unique features of this library:
  • mocking static functions/methods
  • mocking private functions/methods
These features are extremely important but hard to implement in other testing frameworks. For a better understanding of PowerMock I present a small example.

class Calculator {
public static int add(int a1, int a2) {
return a1 + a2;
}
}

class Operatii {
public int operatieComplexa(int a1, a2) {
int a = Calculator.add(a1, a2);
return ++a;
}
}

@RunWith(PowerMockRunner.class)
@PrepareForTest({Calculator.class})
class TestOperatii {
@Test
public void testOperatieComplexa() {
PowerMock.mockStatic(Calculator.class);
EasyMock.expect(Calculator.add(1, 2).andReturn(3);

PowerMock.replayAll();

Operatii obj = new Operatii();
int ret = obj.operatieComplexa(1, 2);

PowerMock.verifyAll();

Assert.assertEquals(4, ret);
}
}

This is all. When you run the test the code will use an injected method instead of using the static method from Calculator class. Some elements need to be explained:

  • @RunWith(PowerMockRunner.class). It tells JUnit to use PowerMockRunner class for running the tests(it won't work without this line because PowerMock implements a custom class loader).
  • @PrepareForTest({Calculator.class}). This annotation describe the class which static methods will be mocked using mockStatic method.
In conclusion, PowerMock is a powerful testing framework which implements record/replay/verify phases in a similar manner as mocker. For more details, please visit: http://code.google.com/p/powermock/w/list

miercuri, 5 august 2009

Python invoking web services

Recently, I had to invoke a webservice method from python. One solution found was to build a SOAP request. After the request is built, I use httplib for sending request and receiving an answer from the webservice. For this demo, I'll use www.infovalutar.ro webservice(an exchange rate service from Romania).

------------------------------------------------------------------------------------------------
import httplib

HOST = "www.infovalutar.ro"
URL = "/curs.asmx"

def SOAP_GetMoneda(strMoneda):
strReq = """<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
<soap12:Body>
<getlatestvalue xmlns="http://www.infovalutar.ro/">
<Moneda>%s</Moneda>
</getlatestvalue>
</soap12:Body>
</soap12:Envelope>"""

return strReq % strMoneda

if __name__ == "__main__":
data = SOAP_GetMoneda("USD")

dctHeaders = {"Host" : HOST,
"Content-Type" : "text/xml; charset=utf-8",
"Content-Length" : len(data),
"SOAPAction" : "http://www.infovalutar.ro/getlatestvalue"}

con = httplib.HTTPConnection(HOST)

con.request("POST", URL, data, dctHeaders)
resp = con.getresponse()
print(resp.read())

con.close()
--------------------------------------------------------------------------------

What I don't show in this answer is how to parse the response. This should be a simple fact regarding the fact that soap response is a xml document. In the above presented code, I just print the response on the standard output.