[orm-devel] Access to attributes before a query
Sat, 16 Nov 2002 13:32:08 -0800 (PST)
Diedrich Vorberg said:
> I can see your point however, that this seems a little absurd
> considering that the class' (=the tables) attributes (columns) have been
> previously defined using the columns dict.
[Warning, half backed ideas coming]
Yes - that's where I'm coming from. It would be nice to extend the class
so that it can be used a little more naturally both before there's an
'instance' of it in the DB and afterwards (which ORM does beautifully).
> Two questions to consider:
> o if you expect an unset attribute to contain something, what should
> it contain? None, 0 or "" or a previously defined default value?
My superficial thinking was to run through the columns() and initialize
all as class attributes to None.
> o another problem I have thought about: SQL allows for the
> definition of default values. Fixed default values would be no
> problem to implement, but what about values that call a
> SQL function like NOW() or NEXTVAL(some_sequence)? Should we make a
> SELECT after each INSERT to retrieve this kind of data from the db?
> We have to do a SELECT to get the NEXTVAL() for SERIAL or AUTO
> INCREMENT columns anyway.
And carrying on from there, inserts would ignore all attributes->columns
which remain None.
Updates aren't an issue with the current scheme, anyway...
>># populate a form with instance defaults or data if editing an existing
>>form.add_widget('hidden', 'id' , value=group_id)
>>form.add_widget("string", "code", title="Code", value=g.code, size=20,
>>self.add_widget("string", "name", title="Group name", value=g.name,
>> size=20, required=1)
>>value=num_bool(g.is_login_allowed), title="Allow login?")
> I've run accross the same problem. This is how my code looks:
> if item.oid(): # the oid() function returns a PostgreSQL OID value or
> # simply 1 if we don't use PostgreSQL. The function #
> should probably be renamed/aliased isStored() or so. # If
> the dbobj has not been inserted, yet, it will # return
> title = item.title
> description = item.description
> price = "%5.2f" % item.price
> title = ""
> description = ""
> price = "0.0"
> # create form...
Yes that's certainly one option although it sure adds a lot of code. It
would be great to use the class whether its new (never stored) or an
existing object. That would feel more pythonic.
> Also, bear in mind that
> g = Groups()
> results in an SQL query as
> INSERT INTO item () VALUES ()
> which simply won't work. You need to populate the instance (dbobj) with
> some data to get a valid query. The reason I did it this way is, we
> can't just insert NULL for an unset column, because there is a
> difference in inserting NULL and insering nothing. Take a relation like
> this for instance (this is PostgreSQL btw):
> CREATE TABLE TEST
> id SERIAL,
> test VARCHAR(20),
> created TIMESTAMP DEFAULT NOW()
> and then do
> INSERT INTO test (test, created) VALUES (NULL, NULL);
> INSERT INTO test (test) VALUES (NULL);
> you'll get
> test=# select * from test;
> id | test | created
> 3 | |
> 4 | | 2002-11-16 18:00:08.602113+01
> (2 rows)
> the first created an all-empty column, the latter did what we wanted.
> Any comment or suggestions on how to deal with this kind of problem is
> very welcome!
I agree - still thinking that attributes set to None would be ignored -
maybe we need an ORM "null" type
g.name = 'foo'
g.access = orm.NULL
(and the other attributes g.created, g.modifed would be still set to None,
and therefore skipped on the initial insert, re-read at that point where
they would inherit whatever the DB record actually reflects then)