Thread: Re: [SQLObject] Inheritance branch (Page 2)
SQLObject is a Python ORM.
Brought to you by:
ianbicking,
phd
From: Ian B. <ia...@co...> - 2005-02-07 16:54:17
|
Oleg Broytmann wrote: > Hello. Inheritance branch, revision 570. > > On Thu, Feb 03, 2005 at 05:34:06PM -0600, Ian Bicking wrote: > >>> I haven't subclass MetaSQLObject yet. I'll try to. Also I haven't >>>applied the latest chages in the trunk - the inheritance branch is still >>>based on SQLObject 0.6.1. > > > I split sqlobject/main.py and moved inheritance-related classes into > sqlobject/inheritance.py. Merged patches from the revisions 559:569 from > the trunk; now the branch seems to be syncronized with the trunk. > I still haven't subclass MetaSQLObject yet. Also I haven't moved my > inheritance tests to the new framework as I don't have SQLite which is > required for the new tests framework. I'm working on it. If you can put all the inheritance-related stuff into a subpackage (sqlobject/inheritance/*), then we can merge the trees and get rid of the branch. Tests for that code would go in sqlobject/inheritance/tests/ -- Ian Bicking / ia...@co... / http://blog.ianbicking.org |
From: Oleg B. <ph...@ph...> - 2005-02-09 13:31:42
|
Hello. Inheritance branch, revision 591. I merged all patches from the trunk. That was a big job, as I had to find a way to merge patches from MetaSQLObject to new __classinit__. Well, I did it! Also I moved IneritanceIteration from dbconnection.py to ineritance/iteration.py. And finally I added inheritance tests. For the new framework, of course. Oleg. -- Oleg Broytmann http://phd.pp.ru/ ph...@ph... Programmers don't die, they just GOSUB without RETURN. |
From: Barry W. <ba...@py...> - 2005-01-15 13:01:17
|
On Fri, 2005-01-14 at 17:55, Ian Bicking wrote: > First, sorry I've taken so long to respond to this. I've had a long=20 > reluctance when it comes to the object modeling in a relational=20 > database; I'm pretty comfortable with modeling a relational database as=20 > objects, but inheritance switches that around, and I feel like it's=20 > opening a can of worms. I haven't followed this entire thread (no time), and it's your project so you get to decide <wink>, but I can definitely appreciate this point of view. The deeper principle I like to strive toward is for a project to do its thing and do it really well. For me, SQLObject's primary attraction is that it does the "modeling a relational database as objects" really well. That's a good thing, and a huge benefit to Python programmers, IMO. If a developer really wants to switch that around, I think there are other options available, such as things like zodb and its variously available adapters. -Barry |
From: Ian B. <ia...@co...> - 2005-01-20 21:14:17
|
Carlos Ribeiro wrote: > When I need compound keys, I usually end up resorting to the > selectBy() method. Couldn't it be optimized a little bit? A composite > key method could be 'registered' in the class declaration, hinting at > the need for extra indexes for that columns. The example below may > seem a little bit forced, but it shows the basic idea: > > class Person(SQLObject): > firstName = StrCol() > lastName = StrCol() > byName = CompositeKey('firstName', 'lastName') > > The CompositeKey function would return a method, searching for the > firstName & lastName. The appropriate indexes can also be created > automatically. Is it a workable solution? I assume you have compound keys in addition to a single primary key, otherwise you couldn't get as far as selectBy. They may even be mutable, similar to a column marked alternateID=True. I have an idea in mind that would make this fairly easy to implement, without really being part of SQLObject, but it requires a fair amount of refactoring. One of the reasons I brought up inheritance is that I wanted to resolve this before making those changes, so that Oleg doesn't have to merge these rather large changes. In this case, I want MetaSQLObject to look for objects that have a __add_to_class__ method (or something like that -- I'm just making that name up). Then that method would be called with the class and attribute name as arguments, and if there was a return value that would be used in place of the original object. Col (and subclasses) would be one case of this -- basically they'd look like: class Col(object): def __add_to_class__(self, soClass, attrName): soClass.addColumn(attrName, self) Your CompositeKey would look like: class CompositeKey(object): def __init__(self, *colNames): self.colNames = colNames def __add_to_class__(self, soClass, attrName): return CompositeGetter(soClass, colNames) class CompositeGetter(object): def __init__(self, soClass, colNames): self.soClass = soClass self.colNames = colNames def __call__(self, *values): assert len(values) == len(self.colNames) args = dict(zip(self.colNames, values)) result = list(self.soClass.selectBy(**args)) assert len(result) == 1 return result CompositeKey.__add_to_class__ could also add an index to soClass if you wanted it to. Joins would generally be implemented in a similar way. You could also use descriptors (property or your own custom descriptor) to add attributes. I think the result will make MetaSQLObject easier to understand, and make it easier to add extensions like these. -- Ian Bicking / ia...@co... / http://blog.ianbicking.org |
From: Ian B. <ia...@co...> - 2005-01-20 21:18:02
|
Ian Bicking wrote: > In this case, I want MetaSQLObject to look for objects that have a > __add_to_class__ method (or something like that -- I'm just making that > name up). Then that method would be called with the class and attribute > name as arguments, and if there was a return value that would be used in > place of the original object. I forgot to note this post from a while ago where I mentioned the general idea: http://blog.ianbicking.org/descriptor-nit.html PJE noted the way PEAK does it, but I don't really want to introduce PyProtocols as a prerequesite, so I'm not sure how to best do it. -- Ian Bicking / ia...@co... / http://blog.ianbicking.org |
From: Carlos R. <car...@gm...> - 2005-01-21 09:45:02
|
On Thu, 20 Jan 2005 15:13:10 -0600, Ian Bicking <ia...@co...> wrote: > Carlos Ribeiro wrote: > > When I need compound keys, I usually end up resorting to the > > selectBy() method. Couldn't it be optimized a little bit? A composite > > key method could be 'registered' in the class declaration, hinting at > > the need for extra indexes for that columns. The example below may > > seem a little bit forced, but it shows the basic idea: > > > > class Person(SQLObject): > > firstName = StrCol() > > lastName = StrCol() > > byName = CompositeKey('firstName', 'lastName') > > > > The CompositeKey function would return a method, searching for the > > firstName & lastName. The appropriate indexes can also be created > > automatically. Is it a workable solution? > > I assume you have compound keys in addition to a single primary key, > otherwise you couldn't get as far as selectBy. They may even be > mutable, similar to a column marked alternateID=True. I have an idea in > mind that would make this fairly easy to implement, without really being > part of SQLObject, but it requires a fair amount of refactoring. I guess I'm getting used to SQLObject's automatic ID's. So yes, a table still has the standard primary key; the composite key is an alternate key. My idea was roughly to declare the components of the composite key as individual columns, and then to declare the composite key in such a way that SQLObject could automatically add the by<CompositeKey> method and any necessary index. > One of the reasons I brought up inheritance is that I wanted to resolve > this before making those changes, so that Oleg doesn't have to merge > these rather large changes. > > In this case, I want MetaSQLObject to look for objects that have a > __add_to_class__ method (or something like that -- I'm just making that > name up). Then that method would be called with the class and attribute > name as arguments, and if there was a return value that would be used in > place of the original object. Col (and subclasses) would be one case of > this -- basically they'd look like: > > class Col(object): > > def __add_to_class__(self, soClass, attrName): > soClass.addColumn(attrName, self) > > Your CompositeKey would look like: > > class CompositeKey(object): > > def __init__(self, *colNames): > self.colNames = colNames > > def __add_to_class__(self, soClass, attrName): > return CompositeGetter(soClass, colNames) > > class CompositeGetter(object): > > def __init__(self, soClass, colNames): > self.soClass = soClass > self.colNames = colNames > > def __call__(self, *values): > assert len(values) == len(self.colNames) > args = dict(zip(self.colNames, values)) > result = list(self.soClass.selectBy(**args)) > assert len(result) == 1 > return result > > CompositeKey.__add_to_class__ could also add an index to soClass if you > wanted it to. Joins would generally be implemented in a similar way. > You could also use descriptors (property or your own custom descriptor) > to add attributes. The standard getter & setter for a CompositeKey could possibly take a tuple as an argument, and then set each composnent column accordingly. > I think the result will make MetaSQLObject easier to understand, and > make it easier to add extensions like these. Agreed. -- Carlos Ribeiro Consultoria em Projetos blog: http://rascunhosrotos.blogspot.com blog: http://pythonnotes.blogspot.com mail: car...@gm... mail: car...@ya... |