Re: [SQLObject] alternateMethodName and creating SQL
SQLObject is a Python ORM.
Brought to you by:
ianbicking,
phd
From: Ian B. <ia...@co...> - 2003-03-13 09:44:33
|
On Thu, 2003-03-13 at 02:52, Luke Opperman wrote: > > same should happen with the database creation. SQLObject should pass > > the database connection a couple parameters (_table and _idName should > > be enough), along with the list of columns, and the database connection > > has the responsibility from there. > > Agreed. There's no reason my code has to be in SQLObject (where it now resides) > except for _table and _idName, yes. RelatedJoins still make life messy, because > from a single object you can't tell what it's own column in the intersection > table might be called, and so my first thought tells me you need an equivalent > of needSet/classRegistry... I suppose those things (perhaps the entire list of > generated tables, if i could see a point to it...) could be held in the > DBConnection though. I must admit I've only recently been learning Postgres, so I still initially think about MySQL behavior, where relations are just implicit. So I'm not entirely sure of the correct behavior... if you can give a small class definition and the appropriate class definition, that'd help me. > Hmm, now that I think about it some more, maybe I'm less opposed to simply > switching imports. Right now, here create a local subclass of SQLObject called > CoreObject which contains the _connection attribute. So switching Databases is > in one spot for our entire library of objects. In the same way, at the > CoreObject level we would import the proper (database-specific) set of Columns, > and re-export (__all__) them from there. Then rather than each Object importing > CoreObject from CoreObject, and * from PostgresColumns, they would simply > import * from CoreObject, and hence get the database-specific connection and the > database-specific columns. And if I needed to create a column type not > pre-existing in SQLObject, I'd put it somewhere, and import it at CoreObject, > and continue on in the same manner (when building specific objects one would > never know or care where a column definition was really coming from). I still don't like that. Then in the docs I have to go through this complex description of how you should set up your modules if you want to change databases in the future. The Right Way should also be the easy way. I'm strongly leaning towards putting database compatibility into the Col subclasses. It does mean that DBConnection won't be the sole location for compatibility code, but I don't think that's too big a deal. > > I don't want to use imports for choosing a database. Right now you can > > change databases really easily and dynamically. I don't see any reason > > that has to change. > > Is there some way that you use it where you change the _connection between > instances / dynamically by re-assigning _connection during runtime. I can see > that this is *possible* now, but I'm not seeing why you'd do such a thing > (effectively, move databases/migrate data while leaving the objects in place in > a live system...?) doesn't mean there's not a valid reason to, but elaborate for > me. After you've started using the class changing _connection would do weird stuff. Though potentially you could pass the connection object into the constructor (like you'd do with transactions)... that actually would work right now, but strange things might start happening when you did joins or otherwise mixed the objects. Definitely bad stuff. But what I want to be able to support is pre-instantiation dynamicism. For instance, an application might allow the user to select their database in a configuration file or even something more interactive. Selecting the kind of database can go right alongside selecting the connection parameters. Also, by putting compatibility code into the Col subclasses, the SQLObject user is shielded from that detail. But if it's done with imports then it's exposed. More conceptual overhead. > > ValidatorConverters seem too general to me, but validation functions > > would certainly be useful. It seems like all the interface you need for > > SQLObject would be a function. It could just raise ValueError when > > necessary. Maybe take three arguments -- the SQLObject instance that is > > having its value set, the Col object for the column that's being set, > > and of course the value that's being set. > > Hmm. I'm not seeing how ValidatorConverters are too general yet. Where would the > function you describe go? For us, using a list of validators is as easy as > calling them (single function, just takes value) when a column is set (in > SQLObject), and if a ValueError happens, it just bubbles up and away (SQLObject > is not made more complicated except the need to run through the list). Well, the whole converting is weird. SQLBuilder does some conversion, but it's very limited. I'm not sure how conversion works into everything else. And ValidatorConverter already badly needs an unconverter interface, among other additions, which will make it more complicated. The validation functions would be pretty much like ValidatorConverters, and you'd use them like you're using them currently. So you could do something like Col(contraint=Range(10, 20)) where Range looked like: class Range: def __init__(self, min, max): self.min, self.max = min, max def __call__(self, obj, col, value): if not value >= self.min and value < min: raise ValueError, "Not in range [%s, %s): %s" \ % (self.min, self.max, value) Other validators could be even simpler. I suppose some columns, like IntCol, would add their own validators in addition to the user-provided validators. > > Actual integration between SQLObject and FunFormKit should come about at > > some time, but I don't think there's actually much code that needs to be > > shared between them. At some point I'd like to make some sort of > > builder that takes a SQLObject class and builds a FormDefinition -- I'd > > have to expand the introspection some, though. > > Is planned from us, and should come about in the next few weeks. You're exactly > right, there's very little code shared between them in our planned > implementation, and I will admit that part of the reason we're using > ValidatorConverters is to ease the transition. :) I'll send you details of this > as it gets closer on my radar. It would be easy to take these validators and use a wrapper to turn them into ValidatorConverters. Though there would still be issues of converting values to and from strings, which this doesn't support. Ian |