Hi guys. Some of you who have been tracking the SQL-CVS mailing list might have noticed the commit messages, but now it's more official-like. I've started a reimplementation of SQLObject, aimed at a big ol' cleanup and improvement of the project. Here's what I wrote on my blog, which kind of summarizes my motivations:

Not coincidentally, just before PyCon I am announcing the start of a new project, SQLObject 2 and SQL-API. To be quite honest, I have had a hard time maintaining SQLObject, and have not given it the attention it should. I expect I am not the only one who created something that I later found difficult to work with; that I myself am responsible for all the problems, and made all the bad decisions, makes it worse -- for every problem I could go and fix it, but I can't fix them all as they come in (or I might just be opening up other problems), and as a result I don't fix any. Oleg Broytmann has done a good job giving it the project the more consistent attention that I have not, but when you are working on a project written by someone else it can be hard to make certain changes. This is my own attempt to make those changes I see as necessary.

This package will both more and less than SQLObject 0.x. It does less because several things have been moved to SQL-API, and ideally SQLObject will only be asked to do what it does well, and will not have to address all needs simply because it will be friendlier to other techniques working in the same application.

SQL-API itself is intended to be a neutral front-end to DB-API compliant databases, providing many of the details that are important to usability but not included in the DB-API. Ideally SQL-API can provide infrastructure for other database packages; if you are interested please contact me, or catch me at PyCon, or IRC, or email, or whatever. I want SQL-API to be as neutral as possible, but the only way to really ensure that is for other people to use it in very different ways than I am using it in SQLObject. If you just plain can't use SQL-API for some technical reason, then that's a bug (though you don't have to use all of it to make use of some of it).



And here's the content of the web page which explains this in a bit more detail...

SQLObject 2
===========

So, what is this?

This is a project to factor out pieces of SQLObject, and make it more
comfortable to use SQLObject in combination with ad hoc queries, to
build on SQLObject, and generally to do interesting things.

Installation
------------

This should be installed like::

    easy_install -m SQLObject2==dev

You should only install it ``-m``, aka multi-version.  This way it
will not be the "default" version of ``sqlobject``, as it uses the
same package as SQLObject 0.X.  If you want to use SQLObject 2 in a
project, you should activate it like::

    import pkg_resources
    pkg_resources.require('SQLObject2')

Perhaps in an ``__init__.py`` file.  Using ``"SQLObject2"`` in a
``setup.py`` ``install_requires`` argument will also do the trick, if
*that* package is also required using ``pkg_resources.require``.

Package Decomposition
---------------------

SQLObject 2 breaks SQLObject into three parts (roughly):

* Database infrastructure that is logic-free.  This is stuff that
  could be used anywhere, and can be used in whole or in part.  This
  is what makes up SQL-API.

* Metaprogramming tricks.  These are things that aren't specific to
  SQLObject, but are just general bits of code.  Things like events,
  threadlocal configuration, metaclasses.  This is in the
  ``metasqlobject`` package.  Things will float in and out of this
  package to start.

* SQLObject itself, in the ``sqlobject`` package.  This is the
  object-relational mapper you've come to know and love.  You love it,
  right?  Sure you do.

Compatibility
-------------

Right now (Feb 2006) SQLObject 2 is pre-alpha, and is very not
compatible with SQLObject 0.X.  The test-driven development of
SQLObject 2 will be to use as many of SQLObject's existing tests as
possible.

The goal is that if you use SQLObject 2, much of what you do will work
right away.  You'll get a bunch of warnings about things that are
deprecated, and you'll get some (helpful) messages about things that
are just plain gone.

If you are digging inside SQLObject, it is very possible that your
stuff will just be broken.  But if you are using fairly public APIs,
then you should do okay.

``InheritableSQLObject`` is not part of SQLObject 2 at all at this
point.  I definitely want to change that, hopefully sooner rather than
later.  It might be possible to make that same functionality a part of
the core of SQLObject using some of the new extension techniques,
without a separate subclass.

Architecture Differences
------------------------

The package separation is a big part of the difference.

In general SQLObject also tries to move more of the data and logic out
of the core classes -- ``SQLObject`` itself is quite small (especially
when you consider that several of the functions are mostly made up of
argument checks).  ``sqlmeta`` really does the bulk of the work, but
tries to stay small as well.  Descriptors are used to greater effect.

The event system is not fully developed yet, but is going to be a core
part of the system.  SQLObject (not-2's) trunk also has an event
system.  In SQLObject 2 the event system is ad hoc, because that was
just a lot easier to handle in terms of subclassing (previously
SQLObject used PyDispatcher).  The event system will be a core part of
the way all joins will work, among other more advanced features.

Compound keys are not yet (fully) implemented, but are a core part of
the design.

Bound parameters are the only kind of queries really supported (fully
rendered SQL is supported for logging and debugging only).

SQLObject 2 tries to make up as few names as possible -- preferably no
names.  In some cases this means moving functionality elsewhere, in
some cases being a bit more explicit.  For instance ``ForeignKey``
will be deprecated, and this::

    class Foo(SQLObject):
        other = ForeignKey('Other')

Is now better done this way::

    class Foo(SQLObject):
        other_id = IntCol()
        other = Reference('Other', 'other_id')

Maybe at some future point ``other_id`` can be determined
automatically, but the basic idea of the column as a separate entity
from the reference will remain.  I'm already very happy with how this
is working.  ``ForeignKey`` now implies exactly those two columns you
see there.

Names will be moving to underscore-style (PEP 8 compliant), instead of
mixed case.  There's not that many anyway -- ``selectBy``,
``orderBy``, ``objectID``.

SQLObject will work with DB-API-like connections (actually using a
thin wrapper from SQL-API, but that wrapper goes right over DB-API
connections).  Logging happens below SQLObject now.

Caching will be carefully considered.  I want SQLObject 2 to be much
more multiprocess-friendly, and much more predictable in terms of
performance.  Right now there is no caching, which introduces some
problems (for instance, changes to an instance may not effect another
instance that represents the same row).  Probably the result will be
caching not wholely unlike SQLObject's current caching, except with
stricter thread affinity -- objects will not be cached or shared
between threads.  But we'll start from zero and work up, with firmer
promises about how caching works.

Compound queries will be possible -- i.e., fetching objects from more
than one class at a time, including left joins.  Some of the code is
already in place for this.  Features like lazy fetching of columns
should be much easier.  Lazy updates and inserts should be possible
(i.e., explicit saves).

Column objects are more powerful and more in control of their own
existance.  Column overrides are more explicit.  So what was::

    class User(SQLObject):
        password = StringCol()
        def _set_password(self, value):
            self._SO_set_password(value.encode('rot13'))

Will now be::

    class User(SQLObject):
        class password(StringCol):
            def set(self, obj, value, raw_set):
                raw_set(obj, value.encode('rot13')

Well, that's just a few things.  More to come!



--
Ian Bicking  |  [EMAIL PROTECTED]  |  http://blog.ianbicking.org


-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
_______________________________________________
sqlobject-discuss mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/sqlobject-discuss

Reply via email to