Re: [SQLObject] thoughts on structure and components
SQLObject is a Python ORM.
Brought to you by:
ianbicking,
phd
From: Ian B. <ia...@co...> - 2003-05-09 03:13:08
|
Well, some random thoughts (composed bottom-up, if that helps it make sense) On Thu, 2003-05-08 at 04:37, Bud P.Bruegger wrote: > Hi everyone, > > Been thinking these days and would like to share some of what I came > up with. I suppose this could be of interest just for academic > purposes or for a possible future refactoring of SQLObject. If it's > not of interest, just ignore. > > My thinking was triggered by: > - My wish for higher-level physical types that users construct > depending on the application > - My difficulties to easily add the things to SQLObject that I > expected to be easy: e.g., foreign keys... I feel confident that foreign keys are hard, and I'm okay with that. Which is to say -- the interface could use improvement (e.g., remove the double defining of the foreign key and the external join), but I don't think there's deep problems. > - I have an intuition (that I cannot materialize) that there is some > strong coupling in SqlObject that steepens the learning curve and > makes some behavior unintuitive. It may be that also the issues of > difficulties of subclassing etc. are falling in this area... As I > said, I have no overly clear ideas to offer. > > So my first product out of this is just a clarification of what > concepts (classes) there should be and how they relate with each > other. A first rough writeup of my ideas follows here: > > Concepts: > --------- > > Application Object: > An Application Object is independent of backend storage Independent of "backend storage", or independent of any particular backend storage that fits the rest of the model? I.e., independent like SQLObject currently is (by changing _connection), or something more (like, doesn't inherit from SQLObject)...? > Storable: > A superclass that makes application objects storable. > It adds methods that interact with the Backend in order to > - store > - update > - delete > the object > In addition, it provided methods to easily access related objects I can see how this might be stylistically different from the SQLObject class, but how is it otherwise different? (Well, there's SQLObject and MetaSQLObject, but those are tightly coupled, and I think justifiably so). SQLObject is tightly coupled to DBConnection (i.e., they chat a lot, there's no well defined interface between the two, and information that's available between the two of them isn't necessarily otherwise public). I can imagine them being decoupled, but only after SQLObject had a long time to mature. Now, SQLObject does place some restrictions on how you can create your classes, and some (though less) restrictions on the backend (the backend is less restricted because an RDBMS is already a much more restricted environment than Python). But SQLObject is *not* an OODBMS (with RDBMS backends). It's not ZODB or any of those... they use the RDBMS as a backend, where in SQLObject the Python class is more-or-less the slave to the RDBMS model and backend. There's a strong conceptual tie as well, which is a large benefit -- even if you let SQLObject create you schema, and don't touch the database except through SQLObject, you are using relational metaphors, which many people are comfortable with (and for more reasons than familiarity). Inheritance falls into this, IMHO. You can't support Python inheritance in an RDBMS. You can support something that vaguely approximates Python inheritance, and can solve some of the same problems, but it's not the same thing. But maybe you are really thinking of a super-superclass, i.e., something that SQLObject would inherit from, as well as other significantly different kinds of storage mechanisms. > Backend: > An object that manages the interaction with the actual database. > It has the following components: > - mapping > - dbDriver > - dbConnection > A first version can live with a single driver and connection--a later > version may be able to work with multiple databases > > Connection: > An actual connection or connection pool that interacts with the dbms > > DBdriver: > A class that provides functionality that depends on the kind of connection > used, typically depending on: > - dbms used (e.g., postgres) > - DBI module (and version) > The DBdriver supports a subset of dbCols BConnection is something of a misnomer -- DBDriver would probably be a better name (especially for the poorly named DBMConnection, which doesn't connect to anything). Well, in the beginning DBConnection was really just a primitive form of connection pool, but that part is relatively small now. There's nothing particularly important about the way they are joined. If they weren't, though, the interface would look pretty much the same (since the type of connection you make implies which DBDriver you would use). Separating DBConnection from DBDriver isn't a very significant change, since they are naturally coupled. Now, there is the possibility of different kinds of connection pooling and general connection usage, but that's orthogonal to both connections themselves, and the drivers for those connections. > Mapping: > Description of the physical representation in a dbms-independent way. > The mapping is described by the following components: > - Attributes of Storable Objects > - Relationships of Storable Objects Now, if I'm reading it right, this would be the most significant difference with SQLObject -- a mapping object is a separate from the class. But why? Hmm... on second thought I see a reason that while you would potentially define fields in the class, you may wish to define the way those map to a database separately. Then the class wouldn't be tied so much to SQLObject -- a very different kind of mapping could be used to take the same class and store it over SOAP. I still think the current definitions would be easier and clearer for most uses. At some point you may put it on a different backend, that may have different database names (for instance). Right now you could hack something together to do this by using a Style subclass that fed off a mapping table (instead of using algorithms to map names). But maybe I'm not clear on what you envision for mapping, since I would expect it would belong to the class (with the class having N mappings for N backends). I don't see how it would be part of the backend, so maybe you have something else in mind. > DbCol: > A low level physical type to represent a single field in the dbms. It is an > abstraction of the actual SQL type since different DBdrivers can map it to > different SQL expressions. The types are named closely to standard SQL. > Types such as TIMESTAMP could for example be translated to DateTime by a > mySQL dbDriver. Pretty much Col... > Attribute: > A high-level physical type to represent the higher-level physical rep. This > includes marshalling to and from a lower-level representation. Marshalling > can do things such as encoding structured objects (phone number with country > and area code) to strings, pickling, mapping a single attribute (a point) to > multiple columns (x, y or lat,long), etc. And something like this will come around at some point, it's just not developed yet. Ian |