Thread: Re: [SQLObject] SQLObject's inheritance patch
SQLObject is a Python ORM.
Brought to you by:
ianbicking,
phd
From: Daniel S. <sql...@xs...> - 2004-01-26 15:05:08
|
Hello Ian, Ian Bicking wrote: > Daniel Savard wrote: > >> Here is a patch that add simple inheritance to SQLObject 0.8.1. >> If you try it, please send me some comments (to the list or my >> email). Thanks. > > > Thanks for contributing this. It looks like it required less > modifications than I expected. One thing I wondered about: will this > work with the addColumn class method? It doesn't seem like it -- the > inheritance structure seems to be constructed entirely at the time of > class instantiation. To do this, superclasses would need to know > about all their subclasses, so they could add the column to subclasses > as well. It is possible to keep a dictionary of child classes at construct time. This is what I did until I found the SQLObject's global registry. This dictionary may be used to tell children when adding columns to a parent class. >> A new class attribute '_inheritable' is added. When this new >> attribute is set to 1, the class is marked 'inheritable' and two >> colomns will automatically be added: childID (INT) and childName >> (TEXT). When a class inherits from a class that is marked >> inheritable, a new colomn (ForeignKey) will automatically be added: >> parent. > > > Is childID needed? It seems like the child should share the parent's > primary key. It should be done. Is it simpler ? There will only be hole in the id sequence (but delete will also creates holes...) May it confuse the sequence getter ? (It will not be used anymore on children classes) >> The columns childID and childName will respectivly contain the id >> and the name of the child class (for exemple, 1 and 'Employee'. This >> will permit to call a new function: getSubClass() that will return a >> child class if possible. > > The column parent is a foreign key that point to the parent > class. It works as all SQLObject's foreign keys. There will also be > a parentID attribute to retreive the ID of the parent class. > > These seem weird to me, but I think that's the disconnect between > RDBMS inheritance (which is really just another kind of relationship), > and OO inheritance. > > I'd rather see Person(1) return an Employee object, instead of having > to use getSubClass(). Or, call getSubClass() simply "child", so that > someEmployee.child.parent == someEmployee. It may be more 'phytonic' to return the subclass directly. I will look for that. As all attributes of Person will be available there should be no distinction for the caller if we return a child instead of the wanted class. > But at that point, it really doesn't look like inheritance. Rather we > have a polymorphic one-to-one (or one-to-zero) relation between Person > and Employee, and potentially other tables (exclusive with the > Employee relation). The functional difference is that the join is in > some ways implicit, in that Employee automatically brings in all of > Person's columns. At which point Employee looks kind of like a view. > > Could this all be implemented with something like: > > class Person(SQLObject): > child = PolyForeignKey() > # Which creates a column for the table name, and maybe one for the > # foreign ID as well. > > class Employee(SQLObject): > parent = ColumnJoin('Person') > # ColumnJoin -- maybe with another name -- brings in all the columns > # of the joined class. > > This seems functionally equivalent to this inheritance, but phrased as > relationships. And, phrased as a relationship, it's more flexible. > For instance, you could have multiple ColumnJoins in a class, without > it being very confusing, and multiple PolyForeignKeys, for different > classes of objects. This may be OK for relationship but not for inheritance as there may be non-SQLObject attributes and functions that we need to inherits from parent class. > Ian Daniel Savard |
From: Daniel S. <sa...@gn...> - 2004-01-26 17:27:22
|
Hello Ian, Ian Bicking wrote: > Daniel Savard wrote: > >> Here is a patch that add simple inheritance to SQLObject 0.8.1. >> If you try it, please send me some comments (to the list or my >> email). Thanks. > > > Thanks for contributing this. It looks like it required less > modifications than I expected. One thing I wondered about: will this > work with the addColumn class method? It doesn't seem like it -- the > inheritance structure seems to be constructed entirely at the time of > class instantiation. To do this, superclasses would need to know > about all their subclasses, so they could add the column to subclasses > as well. It is possible to keep a dictionary of child classes at construct time. This is what I did until I found the SQLObject's global registry. I may re-add a child class dictionary to be able to tell each child class about the new column. Same for deleting a column. >> A new class attribute '_inheritable' is added. When this new >> attribute is set to 1, the class is marked 'inheritable' and two >> colomns will automatically be added: childID (INT) and childName >> (TEXT). When a class inherits from a class that is marked >> inheritable, a new colomn (ForeignKey) will automatically be added: >> parent. > > > Is childID needed? It seems like the child should share the parent's > primary key. It should be done. Is it simpler ? There will only be hole in the id sequence (but delete will also creates holes...). May this cause confuse the sequence function in the SQL database ? >> The columns childID and childName will respectivly contain the id >> and the name of the child class (for exemple, 1 and 'Employee'. This >> will permit to call a new function: getSubClass() that will return a >> child class if possible. > > The column parent is a foreign key that point to the parent > class. It works as all SQLObject's foreign keys. There will also be > a parentID attribute to retreive the ID of the parent class. > > These seem weird to me, but I think that's the disconnect between > RDBMS inheritance (which is really just another kind of relationship), > and OO inheritance. > > I'd rather see Person(1) return an Employee object, instead of having > to use getSubClass(). Or, call getSubClass() simply "child", so that > someEmployee.child.parent == someEmployee. It may be more 'phytonic' to return the subclass directly as you suggest. Also, it should be easy to implements. As all attributes of Person will be available there should be no distinction for the caller. > But at that point, it really doesn't look like inheritance. Rather we > have a polymorphic one-to-one (or one-to-zero) relation between Person > and Employee, and potentially other tables (exclusive with the > Employee relation). The functional difference is that the join is in > some ways implicit, in that Employee automatically brings in all of > Person's columns. At which point Employee looks kind of like a view. > > Could this all be implemented with something like: > > class Person(SQLObject): > child = PolyForeignKey() > # Which creates a column for the table name, and maybe one for the > # foreign ID as well. > > class Employee(SQLObject): > parent = ColumnJoin('Person') > # ColumnJoin -- maybe with another name -- brings in all the columns > # of the joined class. > > This seems functionally equivalent to this inheritance, but phrased as > relationships. And, phrased as a relationship, it's more flexible. > For instance, you could have multiple ColumnJoins in a class, without > it being very confusing, and multiple PolyForeignKeys, for different > classes of objects. This may be OK for relationship but not for inheritance as there may be non-SQLObject attributes and functions that we need to inherits. > Ian Daniel |
From: Ian B. <ia...@co...> - 2004-02-05 05:57:36
|
On Jan 26, 2004, at 11:27 AM, Daniel Savard wrote: > Hello Ian, > > Ian Bicking wrote: > >> Daniel Savard wrote: >> >>> Here is a patch that add simple inheritance to SQLObject 0.8.1. >>> If you try it, please send me some comments (to the list or my >>> email). Thanks. >> >> >> Thanks for contributing this. It looks like it required less >> modifications than I expected. One thing I wondered about: will this >> work with the addColumn class method? It doesn't seem like it -- the >> inheritance structure seems to be constructed entirely at the time of >> class instantiation. To do this, superclasses would need to know >> about all their subclasses, so they could add the column to >> subclasses as well. > > It is possible to keep a dictionary of child classes at construct > time. This is what I did until I found the SQLObject's global > registry. > I may re-add a child class dictionary to be able to tell each child > class about the new column. Same for deleting a column. > >>> A new class attribute '_inheritable' is added. When this new >>> attribute is set to 1, the class is marked 'inheritable' and two >>> colomns will automatically be added: childID (INT) and childName >>> (TEXT). When a class inherits from a class that is marked >>> inheritable, a new colomn (ForeignKey) will automatically be added: >>> parent. >> >> >> Is childID needed? It seems like the child should share the parent's >> primary key. > > It should be done. Is it simpler ? > > There will only be hole in the id sequence (but delete will also > creates holes...). May this cause confuse the sequence function in > the SQL database ? A hole shouldn't really matter. IDs just have to be unique, not sequential. Holes also happen when transactions are rolled back. OTOH, separate keys could be more general for other sets of tables. So maybe I'm neutral. >>> The columns childID and childName will respectivly contain the >>> id and the name of the child class (for exemple, 1 and 'Employee'. >>> This will permit to call a new function: getSubClass() that will >>> return a child class if possible. >> >> The column parent is a foreign key that point to the parent >> class. It works as all SQLObject's foreign keys. There will also be >> a parentID attribute to retreive the ID of the parent class. >> >> These seem weird to me, but I think that's the disconnect between >> RDBMS inheritance (which is really just another kind of >> relationship), and OO inheritance. >> >> I'd rather see Person(1) return an Employee object, instead of having >> to use getSubClass(). Or, call getSubClass() simply "child", so that >> someEmployee.child.parent == someEmployee. > > It may be more 'phytonic' to return the subclass directly as you > suggest. Also, it should be easy to implements. As all attributes of > Person will be available there should be no distinction for the > caller. > >> But at that point, it really doesn't look like inheritance. Rather >> we have a polymorphic one-to-one (or one-to-zero) relation between >> Person and Employee, and potentially other tables (exclusive with the >> Employee relation). The functional difference is that the join is in >> some ways implicit, in that Employee automatically brings in all of >> Person's columns. At which point Employee looks kind of like a view. >> >> Could this all be implemented with something like: >> >> class Person(SQLObject): >> child = PolyForeignKey() >> # Which creates a column for the table name, and maybe one for the >> # foreign ID as well. >> >> class Employee(SQLObject): >> parent = ColumnJoin('Person') >> # ColumnJoin -- maybe with another name -- brings in all the >> columns >> # of the joined class. >> >> This seems functionally equivalent to this inheritance, but phrased >> as relationships. And, phrased as a relationship, it's more >> flexible. For instance, you could have multiple ColumnJoins in a >> class, without it being very confusing, and multiple PolyForeignKeys, >> for different classes of objects. > > This may be OK for relationship but not for inheritance as there may > be non-SQLObject attributes and functions that we need to inherits. Hmm... true. I've been trying to think of a good compromise, but I haven't yet. I've been thinking about some changes to columns, and maybe some of this can fit in too. Like we can attach columns to a specific table, which means that Employee would inherit Person's columns, but those columns would be bound to the person table. That doesn't really deal with Person being polymorphic (i.e., that a Person can actually be an Employee). But it's still reasonable that Person would understand that it was a superclass, and have knowledge of its subclasses. I'll definitely keep thinking about this, though. -- Ian Bicking | ia...@co... | http://blog.ianbicking.org |