From: John B. <jb...@dr...> - 2003-11-09 23:03:50
|
If I have a join between A and B called AjoinB, and I remove A via A.destroySelf(); is SQLObject supposed to clean the join tables? If the answer is no, I suspect this would be a very handy feature... Also, further to my previous mail about Story and Reply, where I could not do Story.addReply (MultipleJoin), I think that's because I'm supposed to pass the Story to the Reply as I build it. I think there should also be a method of doing this via Story.addReply, where SQLObject 'commits' the 'new' Reply to the database and sets up the foreign key pointing back to the Story. That would be more consistent. John -- John Baker, (m) 07736393822 http://rant.pointful.info |
From: Ian B. <ia...@co...> - 2003-11-10 00:58:03
|
On Nov 9, 2003, at 5:01 PM, John Baker wrote: > If I have a join between A and B called AjoinB, and I remove A via > A.destroySelf(); is SQLObject supposed to clean the join tables? > > If the answer is no, I suspect this would be a very handy feature... From a quick inspection of the code, no, that's not implemented. Yes, it should be. > Also, further to my previous mail about Story and Reply, where I could > not do > Story.addReply (MultipleJoin), I think that's because I'm supposed to > pass > the Story to the Reply as I build it. I think there should also be a > method > of doing this via Story.addReply, where SQLObject 'commits' the 'new' > Reply > to the database and sets up the foreign key pointing back to the > Story. That > would be more consistent. Hmm... right now if, say, you have a many-to-one relationship between Replies and Stories, then you have Story.replies. But that's just a dumb list. I've thought about an addReply-like method, which would assign the story_id column of Reply. But I don't quite like it, because you aren't just adding the reply, you are moving it (if it previously had a story). -- Ian Bicking | ia...@co... | http://blog.ianbicking.org |
From: Ian B. <ia...@co...> - 2003-11-10 16:05:27
|
On Nov 10, 2003, at 2:02 AM, John Baker wrote: > On Monday 10 November 2003 00:57, Ian Bicking wrote: >> From a quick inspection of the code, no, that's not implemented. >> Yes, >> it should be. > > Goodo. Will it appear in the next version? Should only be a few lines > I'd > guess? Yes, it should probably go into the next version. >> Hmm... right now if, say, you have a many-to-one relationship between >> Replies and Stories, then you have Story.replies. But that's just a >> dumb list. I've thought about an addReply-like method, which would >> assign the story_id column of Reply. But I don't quite like it, >> because you aren't just adding the reply, you are moving it (if it >> previously had a story). > > Yes, that's right, and consistent. It seems rather odd assigning Reply > to a > Story through the new method on Reply ... > > Reply.new(... story = s) > > That's odder :) > > If you think in terms of OO and you're used to Collections, you think > about > adding something to a Collection. No, it's quite different from a normal collection. Normal collections -- in Python and most other languages -- are many-to-many, i.e., an object can be part of multiple collections. One-to-many relations typically imply something more like ownership. It might be reasonable to "add" a reply to a story if the reply's story is already None, but in the more general sense the reply is being "moved", not "added". -- Ian Bicking | ia...@co... | http://blog.ianbicking.org |
From: John B. <jb...@dr...> - 2003-11-10 18:23:17
|
And back to deleting objects. If A has many Bs, there should be a way of declaring it an 'owned relationship', in terms of 'when I delete A, all my Bs are deleted'. Perhaps a flag on MultipleJoin. destroyChildrenWhenDestroyed=True john On Monday 10 November 2003 16:05, you wrote: > On Nov 10, 2003, at 2:02 AM, John Baker wrote: > > On Monday 10 November 2003 00:57, Ian Bicking wrote: > >> From a quick inspection of the code, no, that's not implemented. > >> Yes, > >> it should be. > > > > Goodo. Will it appear in the next version? Should only be a few lines > > I'd > > guess? > > Yes, it should probably go into the next version. > > >> Hmm... right now if, say, you have a many-to-one relationship between > >> Replies and Stories, then you have Story.replies. But that's just a > >> dumb list. I've thought about an addReply-like method, which would > >> assign the story_id column of Reply. But I don't quite like it, > >> because you aren't just adding the reply, you are moving it (if it > >> previously had a story). > > > > Yes, that's right, and consistent. It seems rather odd assigning Reply > > to a > > Story through the new method on Reply ... > > > > Reply.new(... story = s) > > > > That's odder :) > > > > If you think in terms of OO and you're used to Collections, you think > > about > > adding something to a Collection. > > No, it's quite different from a normal collection. Normal collections > -- in Python and most other languages -- are many-to-many, i.e., an > object can be part of multiple collections. One-to-many relations > typically imply something more like ownership. > > It might be reasonable to "add" a reply to a story if the reply's story > is already None, but in the more general sense the reply is being > "moved", not "added". > > -- > Ian Bicking | ia...@co... | http://blog.ianbicking.org -- John Baker, (m) 07736393822 http://rant.pointful.info |
From: Sidnei da S. <si...@aw...> - 2003-11-10 19:17:27
|
On Mon, Nov 10, 2003 at 06:20:47PM +0000, John Baker wrote: | And back to deleting objects. If A has many Bs, there should be a way of | declaring it an 'owned relationship', in terms of 'when I delete A, all my Bs | are deleted'. | | Perhaps a flag on MultipleJoin. destroyChildrenWhenDestroyed=True Like a cascade delete? BTW, I wanted to know if there is cascade delete support on SQLObject. I'm going to need it RSN :) -- Sidnei da Silva <si...@aw...> http://awkly.org - dreamcatching :: making your dreams come true http://plone.org/about/team#dreamcatcher This screen intentionally left blank. |
From: Ian B. <ia...@co...> - 2003-11-10 20:40:26
|
On Nov 10, 2003, at 1:12 PM, Sidnei da Silva wrote: > On Mon, Nov 10, 2003 at 06:20:47PM +0000, John Baker wrote: > | And back to deleting objects. If A has many Bs, there should be a > way of > | declaring it an 'owned relationship', in terms of 'when I delete A, > all my Bs > | are deleted'. > | > | Perhaps a flag on MultipleJoin. destroyChildrenWhenDestroyed=True > > Like a cascade delete? > > BTW, I wanted to know if there is cascade delete support on > SQLObject. I'm going to need it RSN :) No, no support. Right now you can do it manually by overriding destroySelf, e.g.: class Story(SQLObject): def destroySelf(self): for reply in self.replies: reply.destroySelf() super(Story, self).destroySelf() Certainly it could be added without great difficulty... a number of things need to happen with joins (like one-to-one joins need to be written, and a clearly documented many-to-many-with-extra-info join, like employee to client + rate). Then there's the possibility of making joins smarter, like SelectResults, so that you'd do things like employee.clients.append(aClient). -- Ian Bicking | ia...@co... | http://blog.ianbicking.org |
From: John B. <jb...@dr...> - 2003-11-10 19:18:56
|
On Monday 10 November 2003 19:12, Sidnei da Silva wrote: > On Mon, Nov 10, 2003 at 06:20:47PM +0000, John Baker wrote: > | And back to deleting objects. If A has many Bs, there should be a way of > | declaring it an 'owned relationship', in terms of 'when I delete A, all > | my Bs are deleted'. > | > | Perhaps a flag on MultipleJoin. destroyChildrenWhenDestroyed=True > > Like a cascade delete? > > BTW, I wanted to know if there is cascade delete support on > SQLObject. I'm going to need it RSN :) Yes! Having come from www.objectmatter.com, and spent plenty of time helping them develop that, I feel like I've gone back in time :) We really need to discuss superset mappings at some point too ;-) -- John Baker, (m) 07736393822 http://rant.pointful.info |
From: Ian B. <ia...@co...> - 2003-11-10 20:36:19
|
On Nov 10, 2003, at 1:16 PM, John Baker wrote: > We really need to discuss superset mappings at some point too ;-) What're those? -- Ian Bicking | ia...@co... | http://blog.ianbicking.org |
From: John B. <jb...@dr...> - 2003-11-10 20:44:55
|
On Monday 10 November 2003 20:36, Ian Bicking wrote: > On Nov 10, 2003, at 1:16 PM, John Baker wrote: > > We really need to discuss superset mappings at some point too ;-) > > What're those? class Area (SQLObject): class Office (Area): class Home (Area): SQLObject creates three tables, with a foreign key from Home -> Area and Office -> Area. This means I can do: class Person (SQLObject): areas = ReferenceJoin("Area"...) and map a Person to a number of Areas, without having to map him to Office and Home via two join tables. Someone said superset mapping wouldn't be happening, which is a shame, as it's the most obvious and logical choice of the majority of OO mapping. John -- John Baker, (m) 07736393822 http://rant.pointful.info |
From: Ian B. <ia...@co...> - 2003-11-10 20:56:52
|
On Nov 10, 2003, at 2:42 PM, John Baker wrote: > class Area (SQLObject): > > class Office (Area): > > class Home (Area): > > SQLObject creates three tables, with a foreign key from Home -> Area=20= > and > Office -> Area. > > This means I can do: > > class Person (SQLObject): > areas =3D ReferenceJoin("Area"...) > > and map a Person to a number of Areas, without having to map him to=20 > Office and > Home via two join tables. > > Someone said superset mapping wouldn't be happening, which is a shame,=20= > as it's > the most obvious and logical choice of the majority of OO mapping. That was probably me. I find it difficult to map between class=20 hierarchies and tables, and I don't like the ambiguity or arbitrariness=20= of how that mapping has to happen. =1F Which isn't to say I'd be opposed to superset mapping, I'd just rather=20= that it not look like Python inheritance. To me it's more of an=20 implicit join. Or the folding together of multiple tables. Or... I=20 don't know. When I see a metaphor that looks better, and hopefully=20 doesn't involve terms (or even concepts) like "implicit" or "folding",=20= then maybe I'll feel more enthusiastic. I'm trying to avoid magic to=20 the degree possible, which is where my reluctance comes from. -- Ian Bicking | ia...@co... | http://blog.ianbicking.org |
From: Andy T. <an...@ha...> - 2003-11-11 09:56:58
|
Ian Bicking wrote: > On Nov 10, 2003, at 2:42 PM, John Baker wrote: > >> class Area (SQLObject): >> >> class Office (Area): >> >> class Home (Area): >> >> SQLObject creates three tables, with a foreign key from Home -> Area and >> Office -> Area. >> >> This means I can do: >> >> class Person (SQLObject): >> areas = ReferenceJoin("Area"...) >> >> and map a Person to a number of Areas, without having to map him to >> Office and >> Home via two join tables. >> >> Someone said superset mapping wouldn't be happening, which is a shame, >> as it's >> the most obvious and logical choice of the majority of OO mapping. > > > That was probably me. I find it difficult to map between class > hierarchies and tables, and I don't like the ambiguity or arbitrariness > of how that mapping has to happen. > > Which isn't to say I'd be opposed to superset mapping, I'd just rather > that it not look like Python inheritance. To me it's more of an > implicit join. Or the folding together of multiple tables. Or... I > don't know. When I see a metaphor that looks better, and hopefully > doesn't involve terms (or even concepts) like "implicit" or "folding", > then maybe I'll feel more enthusiastic. I'm trying to avoid magic to > the degree possible, which is where my reluctance comes from. > > -- > Ian Bicking | ia...@co... | http://blog.ianbicking.org > In relational data modelling this is implemented via an 'arc' relationship. At the logical level the relationship can be to either the supertype (area) or one of its subtypes (home or office). When this is translated to a physical model you, usually, end up with one table with the same name as the super type. This table then has a 'type' column which indicates what sort of sub-type it is. Then all of the foreign keys can be to the super type table and any further restrictions (e.g. this fk is only for this specific sub-type) can be enforced with constraints. Unless, of course, you do it the other way round ;-) But implementing each of the subtypes as its own table brings many more problems (as mentioned by the op) and is only really a good idea when the sub types have very little in common - in which case are they really sub types? All of which is fine until you introduce objects, with their associations and inheritance which are just about close to what I've described, but not quite close enough. So how this should work in an object relational mapper I leave to more experienced heads. Regards, Andy -- -------------------------------------------------------------------------------- From the desk of Andrew J Todd esq - http://www.halfcooked.com/ |
From: Luke O. <lu...@me...> - 2003-11-10 21:42:02
|
I'm a little unclear whether by superset mappings you are referring to Python class inheritance, or a more generic concept that happens to often be modelled by OO inheritance. Part of the question, we've looked briefly at various ways of modeling inheritance, and currently take the approach of "one table for every concrete class, no shared attributes". This does ignore the possibly handy person.areas example you give, but doesn't have to make any guesses about what the coder meant by OO inheritance. What does person.areas return? Areas, or Homes and Offices? (just curious to make sure I'm understanding your example correctly.) That's my key reason for agreeing with this current approach: Python (and most other OO languages) don't make a distinction between the various uses for inheritance, so let's not make a guess. :) So then, do we 'extend' python syntax to say "Home.subsetOf(Area)" and say that we always map that as your foreignKey representation? Doesn't sound half-bad to me, but there are alternate ways to represent it, and gets back to the magic-representation guessing I'd rather avoid. - Luke Quoting John Baker <jb...@dr...>: > On Monday 10 November 2003 20:36, Ian Bicking wrote: > > On Nov 10, 2003, at 1:16 PM, John Baker wrote: > > > We really need to discuss superset mappings at some point too ;-) > > > > What're those? > > class Area (SQLObject): > > class Office (Area): > > class Home (Area): > > SQLObject creates three tables, with a foreign key from Home -> Area and > Office -> Area. > > This means I can do: > > class Person (SQLObject): > areas = ReferenceJoin("Area"...) > > and map a Person to a number of Areas, without having to map him to Office > and > Home via two join tables. > > Someone said superset mapping wouldn't be happening, which is a shame, as > it's > the most obvious and logical choice of the majority of OO mapping. > > > John > |
From: John B. <jb...@dr...> - 2003-11-10 21:52:22
|
On Monday 10 November 2003 21:41, Luke Opperman wrote: > I'm a little unclear whether by superset mappings you are referring to > Python class inheritance, or a more generic concept that happens to often It's a more generic terminology. > be modelled by OO inheritance. Part of the question, we've looked briefly > at various ways of modeling inheritance, and currently take the approach of > "one table for every concrete class, no shared attributes". This does > ignore the possibly handy person.areas example you give, but doesn't have > to make any guesses about what the coder meant by OO inheritance. > > What does person.areas return? Areas, or Homes and Offices? (just curious > to make sure I'm understanding your example correctly.) Actual concrete objects. So, you can either do SELECT's across all tables that extend Area to find the objects, or you can be more clever: person.getAreas("Home") to tell SQLObject that although the collection can contain any type of Area, you know (in this case), you've stored Home objects. Or you may just wish to get the Home objects. :) > That's my key reason for agreeing with this current approach: Python (and > most other OO languages) don't make a distinction between the various uses > for inheritance, so let's not make a guess. :) So then, do we 'extend' > python syntax to say "Home.subsetOf(Area)" and say that we always map that > as your foreignKey representation? Doesn't sound half-bad to me, but there > are alternate ways to represent it, and gets back to the > magic-representation guessing I'd rather avoid. But without it you get inefficent mappings, as I've highlighted. If I had large structures, such as: Item (has unique id, primary key, which we refer to for tedious reasons within the code, say for storing unique files associated with each Item) Channel extends Item (has unique field specifying a channel id) Periodic extends Channel NonPeriodic extends Channel Meter extends Item Meter --* Channel Location extends Item (location has a unique field, say a postcode/zipcode) Site extends Location House extends Location SiteGroup *--* Location Location --* Meter You can see that flat tables just won't work nicely. How do you express a unique key for both Periodic and NonPeriodic channels? The inheritence is of vital importance in some designs. 'Superset' mapping isn't always the answer, as it can be inefficient, but once you get past noddy examples it's absolutely obvious. There's a nice write up of mapping techniques here: http://www.objectmatter.com/vbsf/docs/maptool/ormapping.html John -- John Baker, (m) 07736393822 http://rant.pointful.info |
From: John B. <jb...@dr...> - 2003-11-10 21:04:54
|
On Monday 10 November 2003 20:56, Ian Bicking wrote: > doesn't involve terms (or even concepts) like "implicit" or "folding", > then maybe I'll feel more enthusiastic. I'm trying to avoid magic to > the degree possible, which is where my reluctance comes from. I didn't really find a real reason in there ;-) Superset mapping makes obvious logical sense when you present the model to an OO programmer. If you are talking objects, you map with supersets. Some of my code to cope with the above example is absolutely sick, but I have no choice. However SQLObject is free, so I'm not going to worry too much - I'll just implement it for you one day :-) Consider other cases where you have a collection of objects that you want to map back to one parent, regardless if you are actually mapping to a child. You might have a "Property", and you might want any object to have a collection of Properties. In OO, you'd define something like: class Item (SQLObject): properties = MultipleJoin("Property") name = StringCol() class Bill (Item): value = FloatCol() .. and many other extension of Item and every extension has access to the list of Properties. We define OO structures to reduce our code and reuse objects, and mappings to tables should work in exactly the same way. After all, why should the OO developer have to worry about tables? The OO developer wants to store something, he/she doesn't want to worry about how it's stored... I'll get on with my work now :) John -- John Baker, (m) 07736393822 http://rant.pointful.info |
From: Ian B. <ia...@co...> - 2003-11-10 21:54:13
|
On Nov 10, 2003, at 3:02 PM, John Baker wrote: > On Monday 10 November 2003 20:56, Ian Bicking wrote: > >> doesn't involve terms (or even concepts) like "implicit" or "folding", >> then maybe I'll feel more enthusiastic. I'm trying to avoid magic to >> the degree possible, which is where my reluctance comes from. > > I didn't really find a real reason in there ;-) > > Superset mapping makes obvious logical sense when you present the > model to an > OO programmer. If you are talking objects, you map with supersets. > Some of my > code to cope with the above example is absolutely sick, but I have no > choice. > However SQLObject is free, so I'm not going to worry too much - I'll > just > implement it for you one day :-) Sure. But I'm more likely to commit it if it fits my sensibilities ;) But who knows, it all depends on what the implementation looks like. Actually, the description of the implementation will be of the greatest interest to me. If you can concisely, unambiguously, and completely describe how to use it, including all the corner cases and likely gotchas, then I'll be convinced. (Keeping in mind that for SQLObject a description of use has to include the Python interface, the SQL schema required, and the queries produced; and, as a tool, extension and customization have to be accounted for) If the implementation is a mess, that can be fixed -- if the semantics are a mess you're stuck. > Consider other cases where you have a collection of objects that you > want to > map back to one parent, regardless if you are actually mapping to a > child. > You might have a "Property", and you might want any object to have a > collection of Properties. In OO, you'd define something like: > > class Item (SQLObject): > properties = MultipleJoin("Property") > name = StringCol() > > class Bill (Item): > value = FloatCol() > > .. and many other extension of Item > > and every extension has access to the list of Properties. And this is just what makes me nervous. What does the Item table look like? How does it relate to the rest of the system, and how does it grow? Presumably Bill and other classes are keyed off of item_id, but how do you know which kind of Item you are working with? Superclasses shouldn't have to be aware of subclasses, but I don't see how that can happen with this system. Also, you get all sorts of weirdness in class creation -- essentially Item.__new__ will have to return a Bill instance, or some other instance, depending on the ID. What looks like inheritance isn't really inheritance, it's something else. I don't know what to call it, but I don't want to create a false cognate by phrasing it incorrectly -- especially when its in relation to something with the complex semantics of a Python class. > We define OO structures to reduce our code and reuse objects, and > mappings to > tables should work in exactly the same way. After all, why should the > OO > developer have to worry about tables? The OO developer wants to store > something, he/she doesn't want to worry about how it's stored... I can appreciate this sentiment, but I'm also wary of it. There are other Python ORMs that do better at distinguishing between business logic and persistence logic, but SQLObject is coming from a bit different perspective -- it's mapping tables to Python objects, not mapping Python classes to tables. Ultimately I am unconvinced that you can get the persistence for free, that you can map arbitrary Python onto a DBMS -- at least without making the DBMS pointless. Now, that's not to say SQLObject won't move more towards being a "seamless" persistency for objects; I have several ideas that could help improve this. But I don't even know what "seamless" really means in this context -- no seamless persistence *can* exist in Python, because the status-quo is non-persistence (which will continue to be a viable option for a large number of objects and situations). But I'm wandering off onto tangents. -- Ian Bicking | ia...@co... | http://blog.ianbicking.org |
From: Nick <ni...@dd...> - 2003-11-10 22:02:10
|
On Mon, 2003-11-10 at 15:54, Ian Bicking wrote: > I can appreciate this sentiment, but I'm also wary of it. There are > other Python ORMs that do better at distinguishing between business > logic and persistence logic, but SQLObject is coming from a bit > different perspective -- it's mapping tables to Python objects, not > mapping Python classes to tables. Ultimately I am unconvinced that you > can get the persistence for free, that you can map arbitrary Python > onto a DBMS -- at least without making the DBMS pointless. I think one of the real advantages of SQLObject's approach is that the database schema is still generally useful to non-Python/SQLObject interactions. Otherwise you'd be stuck with a particular schema paradigm that may not be easily/sanely implemented in a different language. And it could be a nightmare for your DBA who may have to tweak data (let's face it, your PHB will make you do it) using a database browser or SQL command line. Nick |
From: John B. <jb...@dr...> - 2003-11-10 22:12:22
|
On Monday 10 November 2003 22:02, Nick wrote: > I think one of the real advantages of SQLObject's approach is that the > database schema is still generally useful to non-Python/SQLObject > interactions. Otherwise you'd be stuck with a particular schema > paradigm that may not be easily/sanely implemented in a different > language. And it could be a nightmare for your DBA who may have to > tweak data (let's face it, your PHB will make you do it) using a > database browser or SQL command line. There's no reason why it can't support many mapping types. Superset and (I'll call the current one) Subset are both perfectly valid. I care about writing code that you know is wrong, and I'm certainly not going to stop a DBA (if those people still actually exist ;-) me doing that. :) -- John Baker, (m) 07736393822 http://rant.pointful.info |
From: John B. <jb...@dr...> - 2003-11-10 22:10:18
|
On Monday 10 November 2003 21:54, Ian Bicking wrote: > And this is just what makes me nervous. What does the Item table look > like? How does it relate to the rest of the system, and how does it > grow? Presumably Bill and other classes are keyed off of item_id, but > how do you know which kind of Item you are working with? You don't. That's how it starts to become efficient. However a common method is to add a 'filter' column to your top level table to say what type of object it is. > Superclasses shouldn't have to be aware of subclasses, but I don't see > how that can happen with this system. Also, you get all sorts of > weirdness in class creation -- essentially Item.__new__ will have to > return a Bill instance, or some other instance, depending on the ID. There's no reason why they can't be aware, in the form of a "key" column. But stop worrying about that, you're writing an object storage system. The person writing objects to map to a database shouldn't and won't care about all of this. They shouldn't even have to know SQL, all they care about is using a system that persists objects. In a perfect world, the system of storage is irrelevant to the person writing the code. Files/SQL/ObjectDatabases/SmokeSignals/Pigeons. It doesn't matter, the magic should be nothing more than a transparent interface to storage and retrieval, without them having to worry about "not being able to do this because the mapping tool doesn't support superset mappings". I realise the world isn't perfect. :) > What looks like inheritance isn't really inheritance, it's something > else. I don't know what to call it, but I don't want to create a false > cognate by phrasing it incorrectly -- especially when its in relation > to something with the complex semantics of a Python class. Think OO! Why do we even bother with object structures? We bother to separate functionality and appropriate variables. You can't just clump it all together in lots of different tables. Unless you're writing a noddy system, but once you get complex (unique keys, mapping Person --* Area), it starts to fall apart. > I can appreciate this sentiment, but I'm also wary of it. There are > other Python ORMs that do better at distinguishing between business > logic and persistence logic, but SQLObject is coming from a bit > different perspective -- it's mapping tables to Python objects, not > mapping Python classes to tables. Ultimately I am unconvinced that you > can get the persistence for free, that you can map arbitrary Python > onto a DBMS -- at least without making the DBMS pointless. Now, that's > not to say SQLObject won't move more towards being a "seamless" > persistency for objects; I have several ideas that could help improve > this. But I don't even know what "seamless" really means in this > context -- no seamless persistence *can* exist in Python, because the > status-quo is non-persistence (which will continue to be a viable > option for a large number of objects and situations). > > But I'm wandering off onto tangents. No, they are valid points. Seamless is where you want to be. But if you carry on along the path of "we won't do superset" then your building on foundations that won't hold very much. Better to think about it now, than have to start again later. I've been through all of this with Objectmatter .. :-) I don't think superset mappings will be easily to implement at this stage, but it will be even harder 12 months down the line. :) Luckily, I won't be using Python for anything complex until I do see an object mapping tool going in this direction. I guess I could have picked something else, but SQLObject can just about cope with my 'not very complex' case. Yet it's already quite ugly: # All of our database object definitions class Area (SQLObject): _connection = getConnection() areaId = StringCol() title = StringCol() description = StringCol() # Removing makes for not so nice OO # contacts = RelatedJoin('Contact', joinColumn='area', # otherColumn='contact', intermediateTable='AreaContactJoin') # branches = RelatedJoin('Branch', joinColumn='area', # otherColumn='branch', intermediateTable='AreaBranchJoin') # events = RelatedJoin('Event', joinColumn='area', # otherColumn='event', intermediateTable='EventAreaJoin') class Ward (Area): _connection = getConnection() # Should be in parent class if nice OO contacts = RelatedJoin('Contact', joinColumn='ward', otherColumn='contact', intermediateTable='WardContactJoin') branches = RelatedJoin('Branch', joinColumn='ward', otherColumn='branch', intermediateTable='WardBranchJoin') events = RelatedJoin('Event', joinColumn='ward', otherColumn='event', intermediateTable='WardEventJoin') class Constituency (Area): _connection = getConnection() description = StringCol() sittingMP = ForeignKey("Contact") # Should be in parent class if nice OO contacts = RelatedJoin('Contact', joinColumn='const', otherColumn='contact', intermediateTable='ConstContactJoin') branches = RelatedJoin('Branch', joinColumn='const', otherColumn='branch', intermediateTable='ConstBranchJoin') events = RelatedJoin('Event', joinColumn='const', otherColumn='event', intermediateTable='ConstEventJoin Spot the repeated code. And when you're forced to do that, what you're doing is wrong. :) John -- John Baker, (m) 07736393822 http://rant.pointful.info |
From: Andy T. <an...@ha...> - 2003-11-11 10:07:22
|
John Baker wrote: > On Monday 10 November 2003 21:54, Ian Bicking wrote: > > [snip] > > There's no reason why they can't be aware, in the form of a "key" column. But > stop worrying about that, you're writing an object storage system. The person > writing objects to map to a database shouldn't and won't care about all of > this. They shouldn't even have to know SQL, all they care about is using a > system that persists objects. > > In a perfect world, the system of storage is irrelevant to the person writing > the code. Files/SQL/ObjectDatabases/SmokeSignals/Pigeons. It doesn't matter, > the magic should be nothing more than a transparent interface to storage and > retrieval, without them having to worry about "not being able to do this > because the mapping tool doesn't support superset mappings". > > I realise the world isn't perfect. :) > [snip] > <rant> I'm not. I'm writing an application which stores its data in a relational database but which is written in an object oriented style. If I wanted an object persistence mechanism I'd use something like ZODB or PyPerSyst. This is something that irks me when working with colleagues who have limited exposure to technologies other than, for instance, Java. They are always in conflict with their DBAs (who do still exist btw) justifying data models where one side is simply using the db as a persistence mechanism and the other is trying to use the database 'properly'. In general, the right solution is somewhere in the middle. Some of the more esoteric object associations don't map nicely to databases and code has to be written in your application to accomodate them. Likewise you can't always have a third normal form relational model in your database, sometimes you have to live with a little duplication or non-optimal storage structures to make the application easier to code. Its all about compromise </rant> Sorry about that, but *I* feel better now. Regards, Andy -- -------------------------------------------------------------------------------- From the desk of Andrew J Todd esq - http://www.halfcooked.com/ |
From: John B. <jb...@dr...> - 2003-11-11 10:20:54
|
On Tue, Nov 11, 2003 at 10:04:56AM +0000, Andy Todd wrote: > John Baker wrote: > <rant> > I'm not. I'm writing an application which stores its data in a > relational database but which is written in an object oriented style. If > I wanted an object persistence mechanism I'd use something like ZODB or > PyPerSyst. > > This is something that irks me when working with colleagues who have > limited exposure to technologies other than, for instance, Java. They > are always in conflict with their DBAs (who do still exist btw) > justifying data models where one side is simply using the db as a > persistence mechanism and the other is trying to use the database > 'properly'. > > In general, the right solution is somewhere in the middle. Some of the > more esoteric object associations don't map nicely to databases and code > has to be written in your application to accomodate them. Likewise you > can't always have a third normal form relational model in your database, > sometimes you have to live with a little duplication or non-optimal > storage structures to make the application easier to code. Its all about > compromise > </rant> > > Sorry about that, but *I* feel better now. That's ok :-) DBAs are a dieing breed. After all, who needs a DBA for MySQL or Postgres? Alright, so you may be using Oracle, and I pity you :) If SQLObject is to be aimed at a very limited set of solutions, that don't lend themselves towards proper OO programming, then perhaps clearly stating this on the website would be a step forward. But at this point in time, without superset mapping, you cannot model anything more than trivial relationships. This makes it rather unhelpful, which is a shame because it's actually quite easy to use. Databases are there to store data. They should do no more. I do not subscribe to the Oracle approach of, "Let's throw lots of crap into a product [nat/firewall/multiple redo files]" in a desperate attempt to provide a reason for an upgrade. I've got a bunch of databases, some of which have tables that are a mere 500megs, mapped using superset mappings. I see no performance issues, although I am using MySQL :) To the developer, how the data is stored is totally irrelevant. But when your developer can't actually model relationships because the system of persistence is restrictive, then we have a problem. I've already provided two or three examples that clearly demonstrates that SQLObject can't do what I want it to do, and I'm hardly trying :-) It's not my project, and superset mappings would be tricky to implement. But as it is, assuming you can't have this type of mapping, the foundations of the project are extremely limited. And as we all, as good OO developers know, if you build on poor foundations, you regret it later in life. John |
From: Andy T. <an...@ha...> - 2003-11-11 10:39:24
|
John Baker wrote: > On Tue, Nov 11, 2003 at 10:04:56AM +0000, Andy Todd wrote: > >>John Baker wrote: >><rant> >>I'm not. I'm writing an application which stores its data in a >>relational database but which is written in an object oriented style. If >>I wanted an object persistence mechanism I'd use something like ZODB or >>PyPerSyst. >> >>This is something that irks me when working with colleagues who have >>limited exposure to technologies other than, for instance, Java. They >>are always in conflict with their DBAs (who do still exist btw) >>justifying data models where one side is simply using the db as a >>persistence mechanism and the other is trying to use the database >>'properly'. >> >>In general, the right solution is somewhere in the middle. Some of the >>more esoteric object associations don't map nicely to databases and code >>has to be written in your application to accomodate them. Likewise you >>can't always have a third normal form relational model in your database, >>sometimes you have to live with a little duplication or non-optimal >>storage structures to make the application easier to code. Its all about >>compromise >></rant> >> >>Sorry about that, but *I* feel better now. > > > That's ok :-) > > DBAs are a dieing breed. After all, who needs a DBA for MySQL or > Postgres? Alright, so you may be using Oracle, and I pity you :) Well I still get called one occasionally, but in reality I'm what Scott Ambler calls a 'generalising specialist' (http://www.agiledata.org/essays/becomingAgile.html). Never mind Oracle (all hail Larry), have you tried using DB2? Oracle is great compared to that lumbering dinosaur. Regardless, though, you still need to apply rigour and method to your use of a database be it MySQL, Oracle, DB2 or even SQLite. You may want to call them DBA tasks, I call them development activities. > > If SQLObject is to be aimed at a very limited set of solutions, that don't > lend themselves towards proper OO programming, then perhaps clearly > stating this on the website would be a step forward. But at this point in > time, without superset mapping, you cannot model anything more than > trivial relationships. This makes it rather unhelpful, which is a shame > because it's actually quite easy to use. Very limited? Virtually every system I come across these days, both professionally and in my own time, has the application code written in an OO language and the data stored in a relational database. I don't believe that this is entirely because everyone has these Oracle (or Sybase or MySQL) licenses lying about and says "Oh, I know, lets use this for storing our objects". Its because the relational database supplies benefits over and above storing your objects in flat files. Otherwise everyone would be using shelve, right? > > Databases are there to store data. They should do no more. I do not > subscribe to the Oracle approach of, "Let's throw lots of crap into a > product [nat/firewall/multiple redo files]" in a desperate attempt to > provide a reason for an upgrade. I've got a bunch of databases, some of > which have tables that are a mere 500megs, mapped using superset > mappings. I see no performance issues, although I am using MySQL :) And I come to the situation from the other side, if you are *just* using a databsae to store data then why not just get a decent journalled file system on a RAID disk system and use flat files. That way you aren't constrained by Mr Codd's nasty rules. > > To the developer, how the data is stored is totally irrelevant. But when > your developer can't actually model relationships because the system of > persistence is restrictive, then we have a problem. I've already provided > two or three examples that clearly demonstrates that SQLObject can't do > what I want it to do, and I'm hardly trying :-) Correct. But the developer isn't the only actor in this drama. What about extracting data from an operational system to a data warehouse? Or writing summary reports on working data sets? Or replication? Or point-in-time recovery? Or, shock horror - non OO access to your data? > > It's not my project, and superset mappings would be tricky to > implement. But as it is, assuming you can't have this type of mapping, the > foundations of the project are extremely limited. > > And as we all, as good OO developers know, if you build on poor > foundations, you regret it later in life. And I return to my earlier point. If you want pure OO don't use a database. > > > John I'm not trying to start an argument here, its plain from our posts that we have slightly different points of view. I for one am just happy to agree to disagree. Its of benefit to the community (at large and the users of SQLObject) to have people with as broad a variety of backgrounds (and technical inclinations) as possible. Regards, Andy -- -------------------------------------------------------------------------------- From the desk of Andrew J Todd esq - http://www.halfcooked.com/ |
From: Ian B. <ia...@co...> - 2003-11-11 17:14:49
|
On Nov 11, 2003, at 4:20 AM, John Baker wrote: > If SQLObject is to be aimed at a very limited set of solutions, that > don't > lend themselves towards proper OO programming, then perhaps clearly > stating this on the website would be a step forward. But at this point > in > time, without superset mapping, you cannot model anything more than > trivial relationships. This makes it rather unhelpful, which is a shame > because it's actually quite easy to use. You have to understand, it's easy to use because the mapping is simple and clear. I am trying to avoid frameworkification in SQLObject, which is a difficult task. To me, exposed object hierarchies are one of the creepers which can overwhelm a project if left unchecked. Now, I'm not sure if that's the case with this example, since the object hierarchies we're talking about are in user code, not the library code. Still, I'm wary of all things inheritance-related. Call it the Zope syndrome. My intention with SQLObject is not that it be all things to all people, but rather that you can build all things on it. The more complex SQLObject is, the more disconnect there will be when the complexity of your problem doesn't match the complexity of SQLObject. As it is SQLObject is clearly an easier foundation for building superset objects than the DBAPI. To do so it may be a little ad hoc right now, but you have to build ad hoc designs before generalizing anyway, and a little ad hoc design never killed anyone. Maybe having done that you'll desperately want to generalize this particular recipe. I can only say that I would be much happier seeing it phrased in an explicit manner using composition of objects, rather than inheritance, perhaps because I don't treasure inheritance the way a "real OO programmer" might (which is true), or perhaps because I dislike false cognates and subtle disconnects. > To the developer, how the data is stored is totally irrelevant. But > when > your developer can't actually model relationships because the system of > persistence is restrictive, then we have a problem. I've already > provided > two or three examples that clearly demonstrates that SQLObject can't do > what I want it to do, and I'm hardly trying :-) FWIW, you don't have to code those examples as inheritance, and I naturally wouldn't do so. Composition is quite powerful, even if mundane, and is pleasantly explicit. > And as we all, as good OO developers know, if you build on poor > foundations, you regret it later in life. As all good agile developers know, you make it up as you go along ;) -- Ian Bicking | ia...@co... | http://blog.ianbicking.org |
From: John B. <jb...@dr...> - 2003-11-11 10:54:32
|
On Tue, Nov 11, 2003 at 10:36:59AM +0000, Andy Todd wrote: > > DBAs are a dieing breed. After all, who needs a DBA for MySQL or > > Postgres? Alright, so you may be using Oracle, and I pity you :) > > Well I still get called one occasionally, but in reality I'm what Scott > Ambler calls a 'generalising specialist' Quite. Someone who sits in a room importing/exporting DBAs doesn't really provide much useful input into modern life. Code monkeys, which is how I > > lend themselves towards proper OO programming, then perhaps clearly > > stating this on the website would be a step forward. But at this point in > > time, without superset mapping, you cannot model anything more than > > trivial relationships. This makes it rather unhelpful, which is a shame > > because it's actually quite easy to use. > > Very limited? Virtually every system I come across these days, both > professionally and in my own time, has the application code written in > an OO language and the data stored in a relational database. I don't Then demonstrate how to map my simple example of House/Office/Area/Person, as posted in a previous mail. > Sybase or MySQL) licenses lying about and says "Oh, I know, lets use > this for storing our objects". Its because the relational database > supplies benefits over and above storing your objects in flat files. > Otherwise everyone would be using shelve, right? They'd use something which supported a mapping type that allows them to do what they want to do. Only a real idiot would use flat files (I know one, he's sitting behind me ... :-) over a DB, and the DB can support the type of structure we require. But SQLObject can't. > And I come to the situation from the other side, if you are *just* using > a databsae to store data then why not just get a decent journalled file > system on a RAID disk system and use flat files. That way you aren't > constrained by Mr Codd's nasty rules. Too slow. Writing your own optimised system of storing data to flat files is a complete waste of your time. A DB will do it perfectly well, this isn't in dispute. But SQLObject is restrictive and won't let us. > Correct. But the developer isn't the only actor in this drama. What > about extracting data from an operational system to a data warehouse? Or > writing summary reports on working data sets? Or replication? Or > point-in-time recovery? Or, shock horror - non OO access to your data? Extracting: Dump the tables. You need to do no more than back up the data. Summary reports: You use the system, and objects, you have defined, along with SQLObject, to write your reports. Writing them any other way would be silly. Replication: That's a db server activity, and there's no reason why a developer would need to care. They are storing something, taking care of the data is another issue. Recover: DB issue again. This is why we use a DB to store the data, it does all this for us :) Non-OO: Then you're being silly... :-) But you write some struts and a database interface layer to attempt the translation. Again, not an issue we care about. Are you trying to say I should write OO code in a non OO manner, just because somewhere in the world, some weirdo might wake up one day and think, "I know, I'll try to access this data with a non-OO environment". Well that doesn't bother me, if that's a requirement, you write the system like that from the outset. > And I return to my earlier point. If you want pure OO don't use a database. Everyone uses a database to store stuff. OO works perfectly, and there are thouands of examples we can look at. Personally, I've just spent five years (about to move on) helping develop a Java system (www.objectmatter.com) for my company to store hundreds of objects in a DB. The databases are massive: mysql> select count(*) from BillSummaryTag; +----------+ | count(*) | +----------+ | 9801390 | +----------+ Superset mapping used, I hardly notice the time taken to retrieve an object. That's why we use SQL and databases, and with the world virtually stuck on OO, that's the future. At the end of the day, if you think we shouldn't use a database to store OO, then perhaps we should all write in PL/SQL ;-) I haven't had the pleasure of DB2 yet - I'm looking forward to it :) John |
From: Luke O. <lu...@me...> - 2003-11-11 16:49:53
|
> > Superset mapping used, I hardly notice the time taken to retrieve an > object. That's why we use SQL and databases, and with the world virtually > stuck on OO, that's the future. > > At the end of the day, if you think we shouldn't use a database to store > OO, then perhaps we should all write in PL/SQL ;-) I don't really need to fuel this argument, I happen to be in the "relational calculus is able to represent all my data" camp (Yes, CJ Date writes my nighttime prayers :) But there's no reason why we need to agree on this, from what's been discussed so far as functionality for SQLObject, go for it. Just need to realize, those of us who are using SQLObject as a "mapping from rtables to objects, not objects to tables" aren't going to be on the front edge of adding these changes. Although there are still lots of places where we'll have the same desires (more featureful existing Joins for instance) and more eyes on the code etc. - Luke p.s. I'm not trying to say your modelling is "not relational". If you understand Date's problems with people tossing around "it's OO, no need for relational data anymore" then you understand me too. But you seem to be more grounded than most OO proponents, so it's probably just a visceral reaction on my part. But it's not really an argument for this list, nor an argument that tends to convert either side. :) |
From: John B. <jb...@te...> - 2003-11-11 16:55:20
|
On Tuesday 11 November 2003 16:49, Luke Opperman wrote: > I don't really need to fuel this argument, I happen to be in the "Discussion". > "relational calculus is able to represent all my data" camp (Yes, CJ Date > writes my nighttime prayers :) But there's no reason why we need to agree > on this, from what's been discussed so far as functionality for SQLObject, > go for it. If only I was that 3l13t3 at Python ;-) > Just need to realize, those of us who are using SQLObject as a "mapping > from rtables to objects, not objects to tables" aren't going to be on the It can do both! But you (the people who own the project) need to decide which side of the wall to sit on. If you're going to go the superset way, then it needs to be thought of now rather than later. Perhaps looking over www.objectmatter.com would benefit a few. That does both mapping from tables to Java objects, and vice versa. John -- John Baker, Senior Developer, TEAM. http://www.teamenergy.com Views expressed in this mail are my own. |