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 |