Re: [SQLObject] alternateMethodName and creating SQL
SQLObject is a Python ORM.
Brought to you by:
ianbicking,
phd
|
From: Luke O. <lu...@me...> - 2003-03-13 09:05:06
|
> 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.
> But that's only part of it. I'm blanking out on a good example of a
> case where MySQL and Postgres differ on data type definitions, though
> there's a ton of them. Presumably a column type should know how to
> represent itself in the create statement, but it has to do that with the
> database connection in mind. It's an NxM kind of problem (N being the
> kinds of columns, M being the supported databases). Maybe each column
> should simply have a postgresCreate, mysqlCreate, etc. methods. I think
> that's probably as good as it will get. But then that moves SQL
> generation back into the SQLObject module and away from DBConnection.
Yes, the NxM problem leads to having either separate imports (which you oppose
below, and I agree with you on the switching database reason, so screw that
idea), or explicit knowledge of what dbtypes or columntypes exist in the
opposite piece (DBConnection.createSql('String') lookup or
String.createSQL('postgresconnection') lookup or equivalent like your
postgresSqlCreate/mySqlCreate curry).
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).
(Maybe you could take this one step further, so that it's "from
SQLObject.PostgresConnection import *", and that gives you the actual
PostgresConnection and the Columns. But that doesn't make it as easy for someone
to write their own extensions/additions to the list of available Columns. Hmm.)
Solves it from my end, in that there's still only one file I need to change
Database-specific stuff in (and I already had to change it there regardless of
DB-specific columns). But it's a slightly less pretty setup (requires a smart
local setup outside of SQLObject's direct control). But the current situation
can promote hard-to-change code too, if you were to define the DBConnection for
each Object in it's specific source file, you'd have to go through and modify
them all.
> 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.
> I'd like to make import * reasonably clean, so I'd probably prefer names
> like StringCol (and StringCol is still shorter than SQLObject.String);
> but otherwise that seems like the right way to do it. Of course you can
> always do "import SQLObject as SO", and SO.String isn't any worse to
> type than StringCol. Hmm...
Understand and agree with your point, somewhat undecided. I'd say StringCol is
nicer, but that's just me.
> 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).
> 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.
- Luke
|