Examples

A simple model

The first example shows a model for a simple movie database. Movies can have actors, directors, multiple genres, they have a title and a year.

This example also shows how easily real polymorphic inheritance can be used: actors and directors are artists. That is, each property or relationship you add to the Artist-class will be availlable for Actors as well as for Directors, in this case it's the artist's name and date of birth.

#!/usr/bin/env python

import sqlalchemy

from turboentity import *
from turboentity import objectstore

metadata = sqlalchemy.BoundMetaData("sqlite:///:memory:")


class Genre (Entity):
    title = Column(Unicode(30))
    movies = ManyToMany("Movie")


class Movie (Entity):   
    title = Column(Unicode(50))
    year = Column(Integer)
    genres = ManyToMany("Genre")
    director = ManyToOne("Director")
    actors = ManyToMany("Actor")
    
    @property
    def genre(self):
        return " / ".join(genre.title for genre in self.genres)


class Artist (Entity):
    firstname = Column(Unicode(30))
    lastname = Column(Unicode(30))
    birthdate = Column(Date)
    
    @property
    def name(self):
        return self.firstname +" "+ self.lastname

class Director (Artist):
    movies = OneToMany("Movie")


class Actor (Artist):
    movies = ManyToMany("Movie")



def main():
    create_all() # create all tables
    
    scifi = Genre(title="Science-Fiction")
    fantasy = Genre(title="Fantasy")
    horror = Genre(title="Horror")
    
    rscott = Director(lastname="Scott", firstname="Ridley")
    glucas = Director(lastname="Lucas", firstname="George")
    
    sweaver = Actor(lastname="Weaver", firstname="Sigourney")
    hford = Actor(lastname="Ford", firstname="Harrison")
    syoung = Actor(lastname="Young", firstname="Sean")
    mhamill = Actor(lastname="Hamill", firstname="Mark")
    cfisher = Actor(lastname="Fisher", firstname="Carrie")
    
    blade_runner = Movie(title="Blade Runner", year=1982)
    blade_runner.actors.append(hford)
    blade_runner.actors.append(syoung)
    blade_runner.director = rscott
    
    alien = Movie(title="Alien", year=1979)
    alien.actors.append(sweaver)
    alien.director = rscott
    
    star_wars = Movie(title="Star Wars", year=1977)
    star_wars.actors.append(cfisher)
    star_wars.actors.append(hford)
    star_wars.actors.append(mhamill)
    star_wars.director = glucas
    star_wars.genres.append(scifi)
    star_wars.genres.append(fantasy)
    
    scifi.movies.append(blade_runner)
    scifi.movies.append(alien)
    
    alien.genres.append(horror)
    
    objectstore.flush()
    objectstore.clear()
    
    
    for movie in Movie.select():
        print "Movie:       %s" % movie.title
        print "Year:        %d" % movie.year
        print "Genre:       %s" % movie.genre
        print "Directed by: %s" % movie.director.name
        print "Cast:        %s,.." % ", ".join(actor.name
                                            for actor in movie.actors)
        print
    

if __name__ == '__main__':
    main()

View plaintext/download: simple.py

top

Self-referential relationships

In this example there is a simple father-children relationship, so you can see how self-referential relationships work. Furthermore this shows how you can tweak some entity-specific settings by providing an inner class named "turboentity":

#!/usr/bin/env python

import sqlalchemy
from turboentity import *
from turboentity import objectstore

metadata = sqlalchemy.BoundMetaData("sqlite:///:memory:")

class Person (Entity):
    class turboentity:
        tablename = "some_human_lifeform"
        order_by = "name"

    name = Column(Unicode(30))
    father = ManyToOne("Person")
    children = OneToMany("Person")

def main():
    create_all()

    grampa = Person(name="Abe")
    homer = Person(name="Homer")
    bart = Person(name="Bart")
    lisa = Person(name="Lisa")

    grampa.children.append(homer)
    homer.children.append(bart)
    lisa.father = homer

    objectstore.flush()
    objectstore.clear()

    p = Person.get_by(name="Homer")
    print "%s is %s's child." % (p.name, p.father.name)
    print "His children are %s." % (
            " and ".join(c.name for c in p.children))


if __name__ == '__main__':
    main()

View plaintext/download: selfref.py

top

TurboGears identity model

And finally, here's the model.py you can use as a starting point for your identity-based TurboGears-projects. Simply start your new TurboGears-project by typing

tg-admin quickstart -i -s {ProjectName}

and replace the generated model.py with the attached file below. Automatic table creation works as normal:

tg-admin sql create

at least with TurboGears 1.1a0 (r2032).

This Example also shows how TurboEntity can improve the readability of your sourcecode.

from datetime import datetime
from turbogears.database import metadata, session
from turbogears import identity 
from turboentity import *


class Visit (Entity):
    class turboentity:
        tablename = "visit"
    
    visit_key = Column(String(40), primary_key=True)
    created = Column(DateTime, nullable=False, default=datetime.now)
    expiry = Column(DateTime)

    @classmethod
    def lookup_visit(cls, visit_key):
        return Visit.get(visit_key)


class VisitIdentity (Entity):
    class turboentity:
        tablename = "visit_identity"

    visit_key = Column(String(40), primary_key=True)
    user_id = Column(Integer, ForeignKey("tg_user.user_id"), index=True)


class Group (Entity):
    """
        An ultra-simple group definition.
    """
    
    class turboentity:
        tablename = "tg_group"
    
    group_id = Column(Integer, primary_key=True)
    group_name = Column(Unicode(16), unique=True)
    display_name = Column(Unicode(255))
    created = Column(DateTime, default=datetime.now)
    
    users = ManyToMany("User")
    permissions = ManyToMany("Permission")


class User (Entity):
    """
        Reasonably basic User definition. Probably
        would want additional attributes.
    """
    
    class turboentity:
        tablename = "tg_user"

    user_id = Column(Integer, primary_key=True)
    user_name = Column(Unicode(16), unique=True)
    email_address = Column(Unicode(255), unique=True)
    display_name = Column(Unicode(255))
    password = Column(Unicode(40))
    created = Column(DateTime, default=datetime.now)
    
    groups = ManyToMany("Group")

    @property
    def permissions(self):
        perms = set()
        for g in self.groups:
            perms = perms | set(g.permissions)
        return perms


class Permission (Entity):   
    class turboentity:
        tablename = "tg_permission"
    
    permission_id = Column(Integer, primary_key=True)
    permission_name = Column(Unicode(16), unique=True)
    description = Column(Unicode(255))

    groups = ManyToMany("Group")

View plaintext/download: model.py

top