Ben Sizer wrote:
Data is all-important. I should never have to clear a single thing out
of any database just to make a small change to a model, or when I want
to remove the "beta" flag from my product and call it a release
version. I can certainly appreciate that it's hard to get all the
possibly migration cases from one model.py to another right. But why
should Turbogears choke just because I added a line like "newCol =
IntCol()" in there?

Because the intent of a new line like that is ambiguous, exponentially
so if you make more than one change like it at a time. I would also be
extremely worried that a stray keystroke would cause irreparable harm
to a deployed app if such a feature existed. For safety reasons, you
should at least have to run a special "upgrade" command out-of-band
from the normal app execution (like in an admin script, for example).

One example is an extra table I had to insert in a PHP project earlier
this year. This consisted of creating the table, searching for joins
where it would be used, and adding the relevant extra inner join to
each one. Done in about 30 minutes. Not a single problem. In
Turbogears/SQLObject? Well, I have to add the table in the model, as
well as explicitly note backwards references. But that won't propagate
down to the database, so I have to add the table there too, and hope
that the declarations map across properly, including any magic name
mangling SQLObject is doing behind the scenes.

You mean add by hand with SQL? Yuck.

Or I can drop the whole
lot and re-add it, having had to write and execute both export and
import scripts, which is a large waste of time when 99.9% of the data
is going right back in exactly the same tables, unchanged.

You mean dump the whole DB? That is truly horrific.

For some time now, Dejavu has had an optional Schema class which you
can use to version your schema changes. Here's the first two methods
from my main app:

class MissionControlSchema(dejavu.Schema):

   latest = 22

   def upgrade_to_2(self):
       # Change Project.Pastor to Project.PastorID.
       self.arena.rename_property(mcontrol.Project, "Pastor",
"PastorID")

       box = self.arena.new_sandbox()
       for col in box.recall(endue.ListColumn, lambda x: "Pastor" in
x.FieldName):
           col.FieldName = col.FieldName.replace("Pastor", "PastorID")
       box.flush_all()

   def upgrade_to_3(self):
       # Remove MissionTrip.TripCoorTitle and .ZipCode
       self.arena.drop_property(mcontrol.MissionTrip, "TripCoorTitle")
       self.arena.drop_property(mcontrol.MissionTrip, "ZipCode")

Obviously, if you don't already have data in your store, there's no
need to go through all those migrations--the install should give you a
store that matches the latest schema version.

I find it hard to believe that SQLObject doesn't have something
similar. And indeed,
http://www.sqlobject.org/sqlobject/mysql/mysqlconnection.py.html shows
addColumn and dropColumn methods, at least...

Then I still
have to go through my code and search for all the special cases I had
to write because SQLObject's 'complex' queries are crippled by design.
(And since when was "SELECT LibraryUser INNER JOIN Loan INNER JOIN Book
WHERE Loan.expiry > Now" complex, anyway? Seems that way with
SQLObject, unless you want the query to run in quadratic time, that is.

Blurg. In Dejavu, you can get that SQL with:

   now = datetime.datetime.now()
   recall(LibraryUser & Loan & Book, lambda lu, loan, b: loan.expiry >
now)

What does SQLObject's equivalent look like?


Robert Brewer
System Architect
Amor Ministries
[EMAIL PROTECTED]


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"TurboGears" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/turbogears?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to