|
From: Edmund L. <el...@in...> - 2003-05-30 04:33:14
|
Ian,
I've been banging away at SQLObject all day, trying to jam a small
portion of my data model into it, or else rewrite it so it would fit.
Here are my thoughts so far, each worth $0.02, and in no particular order.
I have appended + and minus signs to indicate strength of feeling. More
of either = stronger positive or negative reation. +- = no reaction.
1. Being able to autogenerate schema is nice, and this is how I've been
using testing SQLObject (SO). ++
2. Support for multiple DBs, particularly PostgreSQL, is good. +++
3. There needs to be an object.delete() method that does not require you
to supply the object ID. When not supplied, it deletes the current
object. There is a bug in this right now. When you do
object.destroySelf(), the corresponding row is deleted from the DB, but
the instance data is not invalidated. +-
4. Being able to supply a callable object for the default value of a
column is good. +++
5. Being able to override table name is important because when you have
lots of tables floating around, you often want to control their names so
that you group them together is a specific way when the table names are
sorted. ++++
6. Need to have some way of specifying unique constraints for single and
groups of columns for auto schema generation. --- See (7) below.
7. I don't use enums at all. For table driven applications, I use
primary keys coupled with foreign key constraints. This allows you to
change the allowed values of a column by varying the contents of another
table. This is one argument against using synthetic primary keys. But
using synthetic primary keys is still OK so long as unique columns can
be specified, and the foreign key constraint can take the name of a column.
8. There is no way to specify (at least not that I can see), outer
joins. These are important. ---
9. Method of specifying joins seems a tad clumsy. Object Relational
Membrane's method is cleaner.
10. There needs to be a way to specify a not null constraint.
11. As an extension of (7), it is clumsy to have to pass in an object
(A) when creating another object (B) that has a foreign key constraint
refering to a column in (A). Here's an example that assumes I can add
unique (6), not null constraints (10), and name a column for a foreign
key (7) to a column:
class Gender(SQLObject):
_columns = [
StringCol("name", unique=1, nullable=0)]
class Person(SQLObject):
_columns = [
StringCol("name"),
StringCol("gender", nullable=0, foreignKey="Gender.name")]
With this schema, one should be able to do:
Gender.new(name="Male") # Done once
Gender.new(name="Female") # Done once
man = Person(name="Geoff", gender="Male") # somewhere else in the code
If one has to pass in an instance of Gender, then it becomes very clumsy
and slow, because you have to instantiate the object you want first. i.e.:
male = Gender.select(Gender.q.name=="Male")
man = Person(name="Geoff", gender=male)
A big yuk. Makes table driven applications awful. ----
12. Similarly, if a class/table is just being used for integrity checks,
returning an object rather than the referenced column within the row is
clumsy. Assuming the schema in (11), one would like:
target = Person.select(Person.q.name=="Geoff")
print target.gender
"Male"
When an object is returned, one would have to know the name of the
column and then dereference it:
target = Person.select(Person.q.name=="Geoff")
print target.gender.name
"Male"
13. Being able to add and drop columns at runtime is great. This removes
the need to regenerate the tables in a live database. +++
14. Modeling (which seems rather hard to get into) seems to have very
expressive ways to get complex joins. I haven't tried it at all, but
have browsed the docs. Might be worth stealing some ideas from them. But
gee, theyReallyLikeLongMethodNames! Or maybe I'm sensitive to them due
to RSI...
...Edmund.
|