PyORQ (Python Object Relational binding with Queries) implements persistence
for Python objects using a relational database (RDBMS, e.g. PostgreSQL MySQL)
for storage.
Object-relational mappings have been done before. They are relatively
straightforward: classes map to tables, attributes map to columns and
instances map to rows. However, fundamental to the object paradigm is that
identity maps to state, and not the other way around. Hence, to search
(i.e. map state to identity) one has to loop over the collection of all
objects and examine their state. If the objects are in a persistent store, the
objects need to be instantiated first which may be prohibitively expensive.
Traditionally there have been two solutions to this problem:
- Use persistent containers that use knowledge of the object's state to
allow efficient searches (e.g. B-Trees). However, this essentially
generalizes the notion of identity, and does not allow for arbitrary queries
without instantiation.
- Use knowledge of the object-relational mapping to write SQL queries that
return object identities, which can then be used to instantiate the results of
the query. However, this means that the mechanism of the object-relational
mapping becomes part of the interface, and requires the user to use SQL
within his application.
The innovative aspect of PyORQ is the use of Python expressions to denote
queries which can be automatically translated into SQL and then be executed by
the backend. This leverages the full search capabilities of RDBMSs in an
object-oriented programming environment. Contrary to other object-relational
Python-SQL mappings, the user needs no knowledge of SQL to search the
database.
v. 0.1 of PyORQ has the following features:
- A notation for describing persistent objects based on Python properties
- Automatic creation of tables based on the persistent object definition.
- A native Python notation to describe queries.
- Full support for object-oriented programming (encapsulation,
inheritance)
- Persistent objects may refer to other persistent objects and
queries understand this.
- References to objects of a particular type may also refer to
subclasses of that type.
- Queries on a type, may return subclasses of that type.
- Interfaces to several SQL backends, including:
- PostgreSQL, using pyPgSQL by Billy G. Allie.
- MySQL, using MySQL-Python by Andy Dustman.
- SQLite, using PySQLite by Michael Owens and Gerhard Haring.
Some desirable features are still missing.
- PyORQ does not check if the definition of a previously created
persistent object still matches the table definition.
(Before modifying a persistent object, use db.drop_table()
to remove
the table).
- No support for multiple inheritance (Don't do it).
- Potential name-mangling problems are not checked.
(Assume that persistent attributes are case-insensitive, and you should be
OK).
See Also:
- pyPgSQL
- For the Python interface
to PostgreSQL by Billy G. Allie.
- MySQL-Python
- For the
Python interface to MySQL by Andy Dustman.
- PySQLite
- For the Python
interface to SQLite by Michael Owens and Gerhard Haring.