When using a ORM one of the most common problems is how to map your beautiful
application class inheritance to the database. The specific scenario I’m going
to describe is when you have an abstract base class with some fields and you
want to store those fields in a database table. Then all of its subclasses will
have their own table and to get the data of an instance you will need to make
a join between the base table and the subclass table.
One pattern to accomplish this is the infoheritance pattern described in the
Storm documentation. I’ll show you here a slightly modified version of this
pattern that uses the package lazr.delegates to make the user code easier by
hiding the fact that we are using composition to model inheritance.
So let’s start with some interface definition showing our model hierarchy:
>>> from zope.interface import Interface, Attribute
>>> class IPerson(Interface):
... name = Attribute("Name")
...
>>> class ISecretAgent(IPerson):
... passcode = Attribute("Passcode")
...
>>> class ITeacher(IPerson):
... school = Attribute("School")
No rocket science so far. Let’s write now the implementation of the
IPerson interface. This will be our abstract base class. Pay special
attention to the person property which dynamically retrieve the subclass
instance by using composition.
>>> from zope.interface import implements
>>> from zope.interface.verify import verifyClass
>>> from lazr.delegates import delegates
>>> from storm.locals import Store, Storm, Unicode, Int, Reference
>>> class Person(Storm):
... implements(IPerson)
...
... __storm_table__ = "person"
...
... id = Int(allow_none=False, primary=True)
... name = Unicode()
... person_type = Int(allow_none=False)
... _person = None
...
... def __init__(self, store, name, person_class, **kwargs):
... self.name = name
... self.person_type = person_class.person_type
... store.add(self)
... self._person = person_class(self, **kwargs)
...
... @property
... def person(self):
... if self._person is None:
... assert self.id is not None
... person_class = BasePerson.get_class(self.person_type)
... self._person = Store.of(self).get(person_class, self.id)
... return self._person
>>> verifyClass(IPerson, Person)
True
We will also use a custom metaclass (based on Storm metaclass) so it will
automatically register our subclasses. This is necessary for the dynamic
person property of the Person class where we map integer (stored in the
database) to classes (stored in the source code).
>>> from storm.properties import PropertyPublisherMeta
>>> class PersonType(PropertyPublisherMeta):
... def __init__(self, name, bases, dict):
... super(PersonType, self).__init__(name, bases, dict)
... if not hasattr(self, '_person_types_registry'):
... self._person_types_registry = {}
... elif hasattr(self, '__storm_table__'):
... key = len(self._person_types_registry)
... self._person_types_registry[key] = self
... self.person_type = key
...
... def get_class(self, person_type):
... return self._person_types_registry[person_type]
Now we define a convenience base class for our subclasses. Remember that
the subclasses don’t really inherit from the Person class because we
are using composition. This is where the lazr.delegates.delegates function
comes to rescue. By saying that we delegate the implementation of the
IPerson interface to the ‘person’ attribute, the instances of these subclasses
will look like they really are subclasses of Person, not just from BasePerson.
>>> class BasePerson(Storm):
... __metaclass__ = PersonType
... delegates(IPerson, "person")
...
... person_id = Int(allow_none=False, primary=True)
... person = Reference(person_id, "Person.id")
...
... def __init__(self, person):
... self.person = person
...
>>> class SecretAgent(BasePerson):
... implements(ISecretAgent)
...
... __storm_table__ = "secret_agent"
... passcode = Unicode()
...
... def __init__(self, person, passcode=None):
... super(SecretAgent, self).__init__(person)
... self.passcode = passcode
Here is the magic: we have an interface hierarchy and a different
hierarchy for the classes implementing them. But it’s all transparent
and our classes implement the full hierarchy:
>>> verifyClass(ISecretAgent, SecretAgent)
True
>>> class Teacher(BasePerson):
... implements(ITeacher)
...
... __storm_table__ = "teacher"
... school = Unicode()
...
... def __init__(self, person, school=None):
... super(Teacher, self).__init__(person)
... self.school = school
...
>>> verifyClass(ITeacher, Teacher)
True
Now let’s try storing the objects in the database. We will use a
sqlite in memory database for this example.
>>> from storm.locals import create_database
>>> database = create_database("sqlite:")
>>> store = Store(database)
>>> result = store.execute("""
... CREATE TABLE person (
... id INTEGER PRIMARY KEY,
... person_type INTEGER NOT NULL,
... name TEXT NOT NULL)
... """)
>>> result = store.execute("""
... CREATE TABLE secret_agent (
... person_id INTEGER PRIMARY KEY,
... passcode TEXT)
... """)
>>> result = store.execute("""
... CREATE TABLE teacher (
... person_id INTEGER PRIMARY KEY,
... school TEXT)
... """)
>>> secret_agent = Person(store, u"James Bond",
... SecretAgent, passcode=u"007")
>>> ISecretAgent.providedBy(secret_agent.person)
True
>>> teacher = Person(store, u"Albus Dumbledore",
... Teacher, school=u"Hogwarts")
>>> ITeacher.providedBy(teacher.person)
True
>>> store.commit()
The objects are now saved in the database. Let’s destroy them and
retrieve them back using some queries:
>>> del secret_agent
>>> del teacher
>>> store.rollback()
>>> secret_agent = store.find(SecretAgent).one()
>>> secret_agent.name, secret_agent.passcode
(u'James Bond', u'007')
>>> teacher = store.find(Teacher).one()
>>> teacher.name, teacher.school
(u'Albus Dumbledore', u'Hogwarts')
The great thing is that we can write teacher.name without having to
write teacher.person.name (which also works by the way) effectively
hiding the implementation detail of composition.
Just one final note: Bear in mind that you should not have very deep
hierarchies or you may get a lot of JOINs and a slow application.
You can download a couple of files to test this on your own computer. You just need storm 0.14 and lazr.delegates 1.0, both of which can be installed with easy_install:



Conan siempre ha sido uno de mis héroes desde pequeño y aunque no tuviera muchos comics de él, tras ver la película Conan el Bárbaro, siempre que podía imitaba sus mandobles con una fregona. Ahora tengo la edición de coleccionista de la película y estos dos tomos que Ana me ha regalado este año. Lo que no sabía de pequeño es que Robert E. Howard, el autor del personaje, era coetáneo de H. P. Lovecraft, uno de mis autores preferidos. Eso se nota en algunas descripciones y sensaciones que transmiten los relatos de Conan, quién puede matar a un gorila de un puñetazo pero cuando se enfrenta a hechiceros y a lo desconocido en general tiene miedo y prefiere evitarlo. A través de los relatos cortos que componen el libro te haces una idea de la personalizad de Conan: bruto y primitivo pero al mismo tiempo inteligente y justo. Un libro muy recomandable si tienes los 60 eurazos que cuesta esta edición de super lujo
Más de lo mismo, es decir, genial. Esta vez hay menos relatos pero son más largos. El último, “La Hora del Dragón”, me ha parecido el mejor relato de Howard de los que he leido. Es casi una novela por su extensión y habla de los días en los que Conan ya era rey de Aquilonia, de cómo le arrebatan el trono y de cómo consigue recuperarlo. Ojalá alguién haga un día
Añoranzas y pesares es una trilogía compuesta de 4 libros. Es trilogía porque el tercer y cuarto libro originariamente eran uno solo pero por su tamaño las editoriales decidieron dividirlo en dos. Me lo he leido porque Ana me lo ha recomendado y porque en general soy muy aficionado a los libros de fantasía. El libro engancha mucho porque la historia es rápida y dinámica (me leí los 4 libros en dos meses) pero creo que eso es todo lo bueno que puede decir sobre él. Es bastante predecible y algunas cosas parecen copias literales de El Señor de los Anillos pero bueno, junto con Ken Follet o Stephen King, creo que el autor es uno de esos que hacen libros como churros y libros que enganchan mucho.
Este libro trata de una técnica que me llamaba la atención desde hace algún tiempo: hacer prototipos en papel de programas informáticos. Básicamente viene a decir que es tan poco lo que cuesta hacer un prototipo en papel y tanto lo que se aprende de él que todos los proyectos de software deberían hacerlos en sus fases iniciales. El libro hace especial hincapié en los tests de usabilidad usando prototipos de papel pero yo creo que hacer prototipos de papel es también de enorme utilidad para etapas de análisis y posterior implementación.
Este libro lo leí durante mi estancia en Brasil en la magnifica biblioteca de
Al igual que el User Interface Design for Programmers, este libro también lo leí en Brasil y también me fascinó. Se lee en el mismo tiempo que se lee un Mortadelo, uno se rie casi igual y se aprende un montón sobre usabilidad de páginas web. Como el anterior, el libro gira en torno a una premisa: cualquier elemento de una página web (o cualquier interfaz de usuario) que haga pensar al usuario y le obligue a tomar una decisión, sobra. En los siguientes capítulos desarrolla esta idea y pone numerosos ejemplos con webs existentes de cosas que se deben hacer y cosas que no se deben hacer. Especial mención merece un apéndice al final del libro donde encontramos una carta modelo para tu jefe o tu cliente explicándo por qué no se deben hacer páginas web con gifs animados, introducciones en flash y demás aberraciones que sólo podemos perdonarle a Homer Simpson.
He de confesar que a estas alturas de la vida no había leído este libro y tenía una mezcla de curiosidad y mala conciencia por ello. Afortunadamente ha sido fácil de remediar y he de decir que el libro no me ha decepcionado lo más mínimo, cosa que suele pasarme por ejemplo con ciertas películas, que todo el mundo recomienda y luego la ves y dices “no es para tanto”. Pienso que este libro debería ser de obligada lectura en la carrera de informática ya que explica de forma clara y cristalina conceptos difíciles de coger la primera vez que empiezas a programar como los arrays, las cadenas de caractéres, los punteros, etc. Lo único que me falta para completar esta lectura es desarrollar un programilla sencillo pero útil donde pueda poner en práctica lo que he aprendido y/o recordado con este libro.
Este es el tercer y último libro de este post de los que leí en Brasil. Es considerado un clásico en la ingeniería del software y comprende un montón de artículos sobre el desarrollo de aplicaciones software de complejidad y tamaño considerables. En él viene a decir que la tarea más compleja de hacer una aplicación es la comunicación entre las distintas partes involucradas: el cliente, el arquitecto de software, los analistas, los programadores, etc. A consecuencia de esto añadir más mano de obra a un proyecto de software que lleva retraso según la planificación original no sólo no resuelve el problema sino que lo agrava. Otro artículo interesante incluido en el libro es “No silver bullet” en el que viene decir que en la informática no hay una herramienta/tecnología/metodología mágica que mejore sustancialmente la creación de software tal y como han ido vendiendola distintos fabricantes desde finales de los años 60. Es curioso (o aterrador si se quiere) comprobar que casi 40 años después, este paper sigue siendo tan verídico como en la fecha en la que se publicó. Lo de silver bullet (bala de plata) es porque compara el proceso de creación de software con un hombre lobo por los peligros que ello conlleva y la bala de plata es lo único que mata al hombre lobo. En informática no hay balas de plata.
Esta novela la ví comentada en
Snow Crash se considera uno de los libros que iniciaron el género de Ciber Punk. Tiene un estilo ágil y rápido con las descripciones justas y diálogos llenos de dobles sentidos y argot. Esto hace que se lea muy rápido pero al mismo tiempo requiere concentración por parte del lector para que no se le pase ningún detalle de la enrevesada trama. Su visión del futuro no es muy tentadora pero su gran dosis de humor negro y cinismo hace que al final sea una experiencia divertida, por lo menos al leerla. Vivir en ese mundo me imagino que y no es tán divertido. La portada de mi edición es la de la foto y es bastante más cutre: una chica en 3D encima de una patineta voladora. Es bastante dificil que te tomen en serio cuando te ven en el autobus leyendo un libro con dicha portada….
Este libro me lo regalaron Mario y Montero el año pasado y es un poco denso de lee, lleno de referencias a otros libros, de cifras y estadísticas. Todo para poner a Estados Unidos en su lugar. Después de leer el libro lo único que se te queda es una sensación de mala leche e impotencia enorme tras ver que todas tus sospechas sobre este país eran ciertas y Chomsky simplemente las ha investigado y plasmado aquí. No apto para personas sensibles a las injusticias mundiales.
Este libro me lo recomendó mi buen amigo
El alfabeto de la masculinidad es un libro escrito por el autor de
Por último, este año pasado me leí los Hijos de Hurín, de Tolkien padre aunque editado y juntado por Tolkien hijo. He de decir que he leido más de un libro de los que ha publicado Tolkien hijo y sólo este me ha parecido bueno. El Libro de los Cuentos Perdidos, el Retorno de la Sombra y otros como estos me parecieron un mero trabajo de corta y pega. Pero en esta ocasión parece que se ha esmerado. La historia que cuenta no es nueva si has leido el Silmarilion, eso sí esta mucho más desarrollada y se puede leer sin tener que memorizar 50 nombres para no perderte. La gente que lee el Silmarilion y no les gusta porque esperan que sea otro Señor de los Anillos se sentirán un poco menos decepcionados con este libro. Aunque la verdad, a mí el Silmarilion me encantó. Este libro me ha gustado tanto que lo he comprado 3 veces este año: uno para mí y dos para hacer regalos, a Ana y a Daniel, las otras dos personas en el mundo que conozco que están casi tan flipadas con Tolkien como yo.

