Re: [SQLObject] Composed Primary key

On Thu, 2003-07-24 at 13:18, Brad Bollenbach wrote:
> > > here's another feature I need for my project : I have several tables
> > > whose primary key is composed of two or three columns.
> >
> > Well, if there's going to be composite keys, that might as well be
> > generalized to all the columns (i.e., any attribute could be a composite
> > of several columns).
>
> What's the use case for this?
Well, there's the possibility of things like a point type or something,
where there's more than one column that gets turned into one Python
object (immutable, of course).
But I waver. Now I think I agree with you. There's lots of things that
SQLObject *could* do, but I don't think it should do all those. So long
as there are ways to code, manually, what you want to do, this is enough
for most of these cases. Only when something is really common or really
hairy or just not possible with the current code should we add more
features.
Like you said, we can do this with properties, and it's not too hard.
For the id it's a bit more difficult, and I can deal with improving
that. In combination with the non-integer keys, composite keys might
not be too bad. (Though I draw the line at mutable primary keys!) And
you can't do them with properties.
I'd like to do some type coercion stuff, like I've mentioned but not
implemented for a long time. Then I have to hold off on more features,
because SQLObject could become difficult to understand. I think it's
much more readable to do:
class Position(SQLObject):
x = FloatCol()
y = FloatCol()
def _get_pos(self):
return (self.x, self.y)
def _set_pos(self, value):
self.set(x=value[0], y=value[1])
Than to do:
class Position(SQLObject):
pos = CompositeCol(FloatCol('x'), FloatCol('y'))
Oh, sure, that's much more elegant looking, much more economical in
typing. But it obscures what is made very explicit in the first
example. And if you really wanted to you could always do:
class TupleComposite(object):
def __init__(self, *cols):
self.cols = cols
def __get__(self, obj, objtype):
return tuple([getattr(obj, attr) for attr in self.cols])
def __set__(self, obj, value):
obj.set(**dict(zip(self.cols, value)))
class Position(SQLObject):
x = FloatCol()
y = FloatCol()
pos = TupleComposite('x', 'y')
But then it's up to you to explain what TupleComposite is, and
DictComposite, and StructComposite, and whatever else you end up
creating -- instead of SQLObject coming to be what is perceived to be a
monolithic and complex system that is inaccessible to newcomers (which
happens to a lot of projects).
Anyway, which is a long way of saying I now agree, just composite ids
are called for. They might look like:
class Whatever(SQLObject):
domain = StringCol()
subdomain = StringCol()
id = ('domain', 'subdomain')
Ian