MiddleKit 0.9 Release Notes

MiddleKit version 0.9 released on 11/13/05

Incompatible Changes

There are some MiddleKit improvements that break compatibility with previous versions of MiddleKit, although all are easy to address. In a nutshell, if you are upgrading MiddleKit for an existing project, take the following steps:

Below are more details about the incompatible changes. Below that are more general notes on this release.

Obj Ref Columns

A long standing flaw in MiddleKit was the use of 64-bit integer SQL columns to store references/pointers to objects. The first 32-bits were for the class id and the second 32-bits were for the object id, information that is necessary because of inheritance and the creation of one SQL table per Python class. These 64-bit columns, packed with two numbers, are difficult to work with from SQL. For example, an object reference to (classId=1, objId=1) showed as 4294967297 in SQL and could not be readily joined with other tables.

The new approach is to break these values into two SQL columns. If the attribute name is "foo" then the SQL columns will be named "fooClassId" and "fooObjId". If, for some reason, you don't like those suffixes, you can customize them through the setting ObjRefSuffixes. As always, the class ids are stored in the _MKClassIds table that MiddleKit automatically generates.

Another useful benefit is that the fooClassId columns are now given default values to match the class id of the target class (in other words, the integer id of class Foo). When the target class has no subclasses then the fooClassId column can be safely ignored in INSERTs, UPDATEs and SELECTs. The point of this is to make the database even easier to work with from SQL.

If you are upgrading Webware then your database schema will no longer be compatible with MiddleKit. The easy way to fix this is to set UseBigIntObjRefColumns to True in Settings.config (see User's Guide - Configuration for more information). This will give you the old behavior. The hard way is to fix up your schema and migrate the data from the old columns to the new.

Serial Number Column

MiddleKit creates a SQL table for every concrete class, and each table has a column for the serial number of a record. This column is the primary key for the table. Its new default name is serialNum which matches the MiddleObject method of the same name and fits MiddleKit naming conventions. You can control this with a new setting.

SQLGenerator.config

There used to be another config file, besides Settings.config, named SQLGenerator.config, with a single setting, DropStatements. That file is no longer used and the setting has been moved to Settings.config. If you have SQLGenerator.config in a model directory, move the setting over.

MS SQL Support

The float type now yields a SQL type of float rather than decimal, because that matches the semantics of Python's float type more closely (perhaps identically). If you want decimal, use decimal; it is a valid MiddleKit datatype.

The serial primary key field is now typed as int instead of bigint. This matches the MiddleKit approach for other databases and also allows object id columns to be foreign keys to this primary key (MS SQL will give an error if an int column tries to reference a bigint column).

Protection against losing changes

Depending on the application, certain call sequences can cause uncommitted changes to be lost. This might be due to programmer error (i.e. forgetting to call saveChanges when necessary), but can also happen due to the implementation of store.deleteObject(), which executes SQL queries (and refreshes objects) when locating and resolving object references (i.e. cascade, detach).

In order to protect the programmer against such errors, which may be very subtle and difficult to detect, MiddleKit will raise an assertion error when a changed object's attributes are about to be refreshed from the database. The programmer should then add calls to store.saveChanges() to ensure that data loss cannot occur.

Since this change may break existing applications, a new setting called "AllowRefreshOfChangedObject" has been added. This setting defaults to false (strongly recommended), but for existing applications you may set it to true to avoid ever getting an assertion failure.

New Features

Improvements and Refinements

Bugfixes