CHAPTER 12
■
DATABASES AND JYTHON: OBJECT RELATIONAL
MAPPING AND USING JDBC
252
# Delarative creation of the table, class, and mapper
>>> from sqlalchemy.ext.declarative import declarative_base
>>> from sqlalchemy.schema import Sequence
>>> Base = declarative_base()
>>> class Player(object):
... __tablename__ = 'player'
... id = Column(Integer, Sequence(‘id_seq’), primary_key=True)
... first = Column(String(50))
... last = Column(String(50))
... position = Column(String(30))
... def __init__(self, first, last, position):
... self.first = first
... self.last = last
... self.position = position
... def __repr__(self):
... return "
" % (self.first, self.last, self.position)
...
It is time to create a session and begin working with our database. We must create a session class
and bind it to our database engine that was defined with create_engine earlier. Once created, the Session
class will create new session object for our database. The Session class can also do other things that are
out of scope for this section, but you can read more about them at sqlalchemy.org
or other great
references available on the web. See Listing 12-29.
Listing 12-29. Creating a Session Class
>>> from sqlalchemy.orm import sessionmaker
>>> Session = sessionmaker(bind=db)
We can start to create Player objects now and save them to our session. The objects will persist in
the database once they are needed; this is also known as a flush(). If we create the object in the session
and then query for it, SqlAlchemy will first persist the object to the database and then perform the query.
See Listing 12-30.
Listing 12-30. Creating and Querying the Player Object
#Import sqlalchemy module and zxoracle
>>> import zxoracle
>>> from sqlalchemy import create_engine
>>>
from sqlalchemy import Table, Column, String, Integer, MetaData, ForeignKey
>>> from sqlalchemy.schema import Sequence
# Create engine
>>> db = create_engine('zxoracle://schema:password@hostname:port/database’)
# Create metadata and table
>>> metadata = MetaData()
>>> player = Table('player', metadata,
... Column('id', Integer, Sequence('id_seq'), primary_key=True),
... Column('first', String(50)),
... Column('last', String(50)),
www.it-ebooks.info
CHAPTER 12
■
DATABASES AND JYTHON: OBJECT RELATIONAL MAPPING AND USING JDBC
253
... Column('position', String(30)))
>>> metadata.create_all(db)
# Create class to hold table object
>>> class Player(object):
... def __init__(self, first, last, position):
... self.first = first
... self.last = last
... self.position = position
... def __repr__(self):
... return "
" % (self.first, self.last, self.position)
# Create mapper to
map the table to the class
>>> from sqlalchemy.orm import mapper
>>> mapper(Player, player)
# Create Session class and bind it to the database
>>> from sqlalchemy.orm import sessionmaker
>>> Session = sessionmaker(bind=db)
>>> session = Session()
# Create player objects, add them to the session
>>> player1 = Player('Josh', 'Juneau', 'forward')
>>> player2 = Player('Jim', 'Baker', 'forward')
>>> player3 = Player('Frank', 'Wierzbicki', 'defense')
>>> player4 = Player('Leo', 'Soto', 'defense')
>>> player5 = Player('Vic', 'Ng', 'center')
>>> session.add(player1)
>>> session.add(player2)
>>> session.add(player3)
>>> session.add(player4)
>>> session.add(player5)
# Query the objects
>>> forwards = session.query(Player).filter_by(position='forward').all()
>>> forwards
[
,
]
>>> defensemen = session.query(Player).filter_by(position='defense').all()
>>> defensemen
[
,
]
>>> center = session.query(Player).filter_by(position='center').all()
>>> center
[
]
Well, hopefully from this example you can see the benefits of using SqlAlchemy. Of course, you can
perform all of the necessary SQL actions such as insert, update, select, and delete against the objects.
However, as said before, there are many very good tutorials where you can learn how to do these things.
We’ve barely scratched the surface of what you can do with SqlAlchemy, it is a very powerful tool to add
to any Jython or Python developer’s arsenal.
www.it-ebooks.info
CHAPTER 12
■
DATABASES AND JYTHON: OBJECT RELATIONAL MAPPING AND USING JDBC
254
Hibernate
Hibernate is a very popular object relational mapping solution used in the Java world. As a matter of fact,
it is so popular that many other ORM solutions are either making use of Hibernate or extending it in
various ways. As Jython developers, we can make use of Hibernate to create powerful hybrid
applications. Because Hibernate works by mapping POJO (plain old Java object) classes to database
tables, we cannot map our Jython objects to it directly. While we could
always try to make use of an
object factory to coerce our Jython objects into a format that Hibernate could use, this approach leaves a
bit to be desired. Therefore, if you wish to create an application coded entirely using Jython, this would
probably not be the best ORM solution. However, most Jython developers are used to doing a bit of work
in Java and as such, they can harness the maturity and power of the Hibernate API to create first-class
hybrid applications. This section will show you how to create database persistence objects using
Hibernate
and Java, and then use them directly from a Jython application. The end result, code the
entity POJOs in Java, place them into a JAR file along with Hibernate and all required mapping
documents, and then import the JAR into your Jython application and use.
We have found that the easiest way to create such an application is to make use of an IDE such as
Eclipse or Netbeans. Then create two separate projects, one of the projects would be a pure Java
application that will include the entity beans. The other project would be a pure Jython application that
would include everything else. In this situation, you could simply add
resulting JAR from your Java
project into the sys.path of your Jython project and you’ll be ready to go. However, this works just as well
if you do not wish to use an IDE.
It is important to note that this section will provide you with one use case for using Jython, Java, and
Hibernate together. There may be many other scenarios in which this combination of technologies
would work out just as well, if not better. It is also good to note that this section will not cover Hibernate
in any great depth; we’ll just scratch the surface of what it is capable of doing. There are a plethora of
great Hibernate tutorials available on the web if you find this solution to be useful.
Entity Classes and Hibernate Configuration
Because our Hibernate entity beans must be coded in Java, most of the
Hibernate configuration will
reside in your Java project. Hibernate works in a straightforward manner. You basically map a table to a
POJO and use a configuration file to map the two together. It is also possible to use annotations as
opposed to XML configuration files, but for the purposes of this use case we will show you how to use the
configuration files.
The first configuration file we need to assemble is the hibernate.cfg.xml, which you can find in the
root of your Java project directory tree. The purpose of this file is to define your database connection
information as well as declare which entity configuration files will be used in your project. For the
purposes of this example, we will be using the PostgreSql database, and we’ll
be using the classic
examples of the hockey roster application. This makes for a very simple use-case as we only deal with
one table here, the Player table. Hibernate makes it very possible to work with multiple tables and even
associate them in various ways.
Listing 12-31.
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
org.postgresql.Driver
jdbc:postgresql://localhost/database-name
www.it-ebooks.info