Table Oriented Programming

Yermat loic at
Fri Feb 13 12:31:46 CET 2004

"Michael Hobbs" <michael at> wrote in message news:<mailman.2.1076613028.31398.python-list at>...
> Yeah, yeah, another X-Oriented paradigm, but please hear me out.
> I have recently been studying up on EJB's in order to extend my resume.
> I have looked at J2EE several times over the past years, but have never
> been impressed by it. Now that I've studied it in detail, I know why. A
> strongly typed language such as Java is poorly suited to model tables
> and relations. 
> I got to thinking that a more dynamically typed language, such as
> Python, would be a more natural fit. I've always been fond of the
> table-oriented programming ideas described in
>, so I'm thinking that if
> Python could be extended to handle table-oriented programming as
> seamlessly as it handles object-oriented programming, it could become a
> really valuable language for writing enterprise components, a la EJB.
> Does anyone know if anyone has already walked this path?
> I've given it a little thought myself, and here are some of my
> [incomplete] ideas:
> - Tables would be first-class values, just as classes are.
> - A table may be stored completely in memory, or it may represent a
> table stored in a database engine.
> - A table may represent the result of a query.
> - Queries are performed using a sequence of operators, rather than
> relying on SQL.
> Consider this example code:
>   departments = DepartmentTable
>   employees = EmployeeTable
>   johnsDepartment = (departments * employees) / 
>     (employees.dept == departments.dept) /
>     ( == 'John') %
>   print johnsDepartment[0].name
> In the code above, the "*" operator performs a cartesian product, the
> "/" operator performs a selection, and the "%" operator performs a
> projection. If the DepartmentTable and the EmployeeTable are stored in a
> database engine, the expression above would generate a SQL query similar
> to "select from (select * from department, employee
> where employee.dept = department.dept) where = 'John'". If
> the expression had been written "(departments * employees) /
> (employees.dept == departments.dept and == 'John') %
>", the resulting SQL would be similar to "select
> from department, employee where employee.dept =
> department.dept and = 'John'", that is, without the nested
> Of course, the entire code above could be reduced to a single line:
>   print ((DepartmentTable * EmployeeTable) / (EmployeeTable.dept ==
> DepartmentTable.dept and == 'John') %
> Perhaps the list-comprehension syntax may be better suited than
> arithmetic operators. Like I said, my ideas are still a little
> incomplete.
> Please forgive me if this has already been discussed to death,
> - Michael Hobbs

What about the following code ?
I think there is not too much to make it work...


class TOP(object):
    def __div__(self,other):
        return Selection(self,other)

    def __mul__(self,other):
        return CartesianProduct(self,other)

    def __eq__(self,other):
        return Equality(self,other)

    def __mod__(self,other):
        return Projection(self,other)

    def execute(self,connexion):
        self._cursor = connexion.cursor()

    def __getitem__(self,item):
        if not hasattr(self,'_result'):
            self._result = self._cursor.fetchall()
        return self._result[item]

    def __iter__(self):
        return self._iter

    def _iter(self):
        set = self._cursor.nextset()
        while set:
            yield set
            set = self._cursor.nextset()

class Table(TOP):
    def __init__(self,name):
        self._name = name
    def __getattr__(self,attr):
        return Field(self,attr)

    def __str__(self):
        return self._name

class Field(TOP):
    def __init__(self,table,fieldName):
        self._table = table
        self._name = fieldName

    def __str__(self):
        return "%s.%s" % (self._table,self._name)

class Equality(TOP):
    def __init__(self,a,b):
        self.a = a
        self.b = b

class Selection(TOP):
    def __init__(self,a,b):
        self.a = a
        self.b = b

class CartesianProduct(TOP):
    def __init__(self,a,b):
        self.a = a
        self.b = b

class Projection(TOP):
    def __init__(self,a,b):
        self.a = a
        self.b = b

class ToSql:
    def __init__(self):

    def toSql(self,obj):
        methodName = "toSql" + obj.__class__.__name__
        if hasattr(self,methodName):
            toSql = getattr(self,methodName)
            return toSql(obj)
            #print methodName
            return '"%s"' % str(obj)

    def toSqltuple(self,tuple):
        return ",".join(map(lambda o: self.toSql(o),tuple))

    def toSqlTable(self,table):
        return str(table)

    def toSqlField(self,field):
        return str(field)

    def toSqlCartesianProduct(self,prod):
        return "%s,%s" % (self.toSql(prod.a),self.toSql(prod.b))

    def toSqlEquality(self,eq):
        return "%s == %s" % (self.toSql(eq.a),self.toSql(eq.b))

    def toSqlSelection(self,sel):
        if isinstance(sel.a,Selection):
            return "%s AND %s" % (self.toSql(sel.a),self.toSql(sel.b))
            return "%s WHERE %s" %

    def toSqlProjection(self,proj):
        if isinstance(proj.a,Projection):
            return "?"
            return "SELECT %s FROM %s" % (self.toSql(proj.b),

translator = ToSql()

departments = Table("DepartmentTable")
employees = Table("EmployeeTable")

johnsDepartment = ( departments * employees) / (employees.dept ==
departments.dept)  / ( == "John") %
johnsDepartmentBis = ( departments * employees) / (employees.dept ==
departments.dept)  / ( == "John") %

print translator.toSql(johnsDepartment)
print translator.toSql(johnsDepartmentBis)

##print johnsDepartment[0]

##for item in johnsDepartmentBis:
##    print item

More information about the Python-list mailing list