Field not automatically updated with update param in constructor

33 views
Skip to first unread message

Vinicius Assef

unread,
Nov 8, 2010, 1:51:11 PM11/8/10
to web...@googlegroups.com
Buddies, this is what is happening, step by step:

http://pastebin.com/b14HLy39

This test was made with latest stable version: Version 1.88.2
(2010-10-29 23:04:43)

Again, am I missing something?

I don't think there is a bug here. I expect I am making a really big
and stupid mistake.
This is too important to not be working out.

By the way: I'm using Ubuntu 9.04.

--
Vinicius Assef.

On Mon, Nov 8, 2010 at 3:13 PM, Vinicius Assef <vinic...@gmail.com> wrote:
> Massimo, I expect the correct way is:
>
> a) When inserting (sql insert) a new record:
> 1) was_inserted_on receives request.now contents (this is ok)
> 2) was_updated_on receives null
>
> b) When updating (sql update) a record:
> 1) was_inserted_on doesn't change is value (this is ok)
> 2) was_update_on receives request.now
>
>
> What is happening here, with web2py 1.87.3 and SQLite:
>
> a) When inserting (sql insert) a new record:
> 1) was_inserted_on receives request.now content
> 2) was_updated_on receives request.now content
>
> b) When updating (sql update) a record:
> 1) was_inserted_on doesn't change its value
> 2) was_update_on doesn't change its value
>
> Am I loosing something?
>
> --
> Vinicius Assef.
>
>
> On Mon, Nov 8, 2010 at 2:27 PM, mdipierro <mdip...@cs.depaul.edu> wrote:
>> What you expect is correct and I cannot reproduce the problem. how do
>> you update the record?
>>
>> On Nov 8, 8:54 am, Vinicius Assef <vinicius...@gmail.com> wrote:
>>> I have this model just for test:http://pastebin.com/vF4VBLLM
>>>
>>> Field 'was_inserted_on' is working all right. It has default insert
>>> value and it isn't updated across record updates. It's ok.
>>>
>>> But 'was_updated_on' is working the same way.
>>>
>>> I imagined it was null when record is inserted and in every record
>>> update, it would be this column updated.
>>>
>>> At least, it was what I got from we2bpy manual in Record
>>> Representation section (DAL chapter).
>>>
>>> Where did I misunderstood?
>>>
>>> By the way, I solved that using compute in was_updated_on field and
>>> returning request.now.
>>>
>>> --
>>> Vinicius Assef.
>

mdipierro

unread,
Nov 8, 2010, 1:58:42 PM11/8/10
to web2py-users
This is misunderstanding. Yes what you have is correct.

The default=datetime.now() and update=datetime.now() is evaluated only
ONCE when the table is defined therefore when you insert and update
the values are always the same.

BUT

when the code is in a web2py controller, the model is run again at
every http request and therefore the values of default and request
will be updated.

Massimo



On Nov 8, 12:51 pm, Vinicius Assef <vinicius...@gmail.com> wrote:
> Buddies, this is what is happening, step by step:
>
> http://pastebin.com/b14HLy39
>
> This test was made with latest stable version: Version 1.88.2
> (2010-10-29 23:04:43)
>
> Again, am I missing something?
>
> I don't think there is a bug here. I expect I am making a really big
> and stupid mistake.
> This is too important to not be working out.
>
> By the way: I'm using Ubuntu 9.04.
>
> --
> Vinicius Assef.
>
> On Mon, Nov 8, 2010 at 3:13 PM, Vinicius Assef <vinicius...@gmail.com> wrote:
> > Massimo, I expect the correct way is:
>
> > a) When inserting (sql insert) a new record:
> > 1) was_inserted_on receives request.now contents (this is ok)
> > 2) was_updated_on receives null
>
> > b) When updating (sql update) a record:
> > 1) was_inserted_on doesn't change is value (this is ok)
> > 2) was_update_on receives request.now
>
> > What is happening here, with web2py 1.87.3 and SQLite:
>
> > a) When inserting (sql insert) a new record:
> > 1) was_inserted_on receives request.now content
> > 2) was_updated_on receives request.now content
>
> > b) When updating (sql update) a record:
> > 1) was_inserted_on doesn't change its value
> > 2) was_update_on doesn't change its value
>
> > Am I loosing something?
>
> > --
> > Vinicius Assef.
>

Vinicius Assef

unread,
Nov 8, 2010, 2:02:33 PM11/8/10
to web...@googlegroups.com
Thanks, Massimo.

But, when the record is inserted, the field with "update" param
shouldn't be None?

--
Vinicius Assef.

mdipierro

unread,
Nov 8, 2010, 2:09:07 PM11/8/10
to web2py-users
no. if you have update but not default, default==update.

On Nov 8, 1:02 pm, Vinicius Assef <vinicius...@gmail.com> wrote:
> Thanks, Massimo.
>
> But, when the record is inserted, the field with "update" param
> shouldn't be None?
>
> --
> Vinicius Assef.
>

Vinicius Assef

unread,
Nov 8, 2010, 2:35:29 PM11/8/10
to web...@googlegroups.com
OK. Understood.

But I must say it doesn't conform with web2py documentation.

About default, the book says: default sets the default value for the
field. The default value is used when performing an insert if a value
is not explicitly specified. It is also used to pre-populate forms
built from the table using SQLFORM.

Assuming default==update may be a source of confusion and unexpected
behaviour. I tried it today. I lost almost a day trying to figure it
out.
In spite of that, how can I have my example field filled with None
when inserted and just populated when updated?
Note that I'm running from shell because I intent to run this process
by a cron job. So, http requests are not present here.

About update, the book says: update contains the default value for
this field when the record is updated.

Well, again, assuming default==update is not what manual says.
When developing database applications, update is understood as an
event that occurs when something changes in your *existing* record (or
row, if purists read this.). So, assume default content is equal
update content may not be a good practice here, and, again, source of
confusion.

Another comment, if allowed, is about datetime.now() be evaluated just
when the table is defined. It is not explicit in book, too.
If I have a background process listening to some semaphores and
updating and inserting records through a cron job, it's worthless and,
again, my be a source of misunderstanding.


Massimo, I ask you to think about that and inform us if web2py way of
doing theses things will change or documentation will be updated to
reflect this behaviour.

--
Vinicius Assef.

mdipierro

unread,
Nov 8, 2010, 2:49:38 PM11/8/10
to web2py-users
Hi Vinicius,

I think there are two issues.

The fact that models are executed at every http request and therefore
values are set there is explained in the manual.
I can understand the confusion when coming form other frameworks but
there is nothing new there.

About the update. I agree there is a discrepancy between
implementation and documentation.
This sentence for example "The default value is used when performing
an insert if a value
is not explicitly specified" does not make sense and should be "The
default value is used when performing an insert if a value
is explicitly specified."

The current design is motivated by the fact that it is not a good idea
to leave those values NULL (None) because they are supposed to be
dates. If you have None in there, you end up needing a lots of check
in the code when you try to format the dates to take care of None
dates.

update='...' is used for timestamps therefore its value should not be
displayed in the form. If it were to be displayed it would be wrong
anyway, because the stored value would be recomputed with the second
http request that performs the insert.

The current design still allows you to check whether a field was or
not updated by comparing the created_on with the updated_on date.

Because this is not clear in the docs we either have to revise the
docs or change its behavior (the latter would break some users'code)
and I think fixing the docs is a better approach.

Anyway, I'd like to hear more opinions about this.

Massimo

Vinicius Assef

unread,
Nov 8, 2010, 5:11:29 PM11/8/10
to web...@googlegroups.com
On Mon, Nov 8, 2010 at 5:49 PM, mdipierro <mdip...@cs.depaul.edu> wrote:
> Hi Vinicius,
>
> I think there are two issues.
>
> The fact that models are executed at every http request and therefore
> values are set there is explained in the manual.

I couldn't find that in DAL chapter (http://web2py.com/book/default/chapter/06).
Where is it?

> I can understand the confusion when coming form other frameworks but
> there is nothing new there.

Actually, I didn't bring my expectation from other frameworks. I
brought it from my database experience.
Even defining the default clausule in CREATE TABLE, it is evaluated
every time a new row is stored.

About the update param, again I thought in terms of database events,
not about http request event.

As web2py intends to serve mainly database driven apps, I thought it
would have the same behaviour. In spite of where the request is coming
from: http, cron or shell.

It would be *very* nice if we have this kind of behaviour centralized
in models, independent of forms.
New records with new dynamic default/update values, ie, datetime.now().


>
> The current design is motivated by the fact that it is not a good idea
> to leave those values NULL (None) because they are supposed to be
> dates. If you have None in there, you end up needing a lots of check
> in the code when you try to format the dates to take care of None
> dates.

OK. I agree with you if notnull=True. But if I allow some Field to
have null value, where is the problem?
If the database allows me, why web2py shouldn't?


>
> update='...' is used for timestamps therefore its value should not be
> displayed in the form. If it were to be displayed it would be wrong
> anyway, because the stored value would be recomputed with the second
> http request that performs the insert.

I agree with you.

But if the field is datetime, I would write 'default=None,
update=datetime.now()'. It leads developer to think: "this field will
be empty when inserted, and populated only when updated".

To work as you implemented, it would be explicit:
'default=datetime.now(), update=datetime.now()'. It leads developer to
think: "this field will have datetime.now() when inserted and will be
updated with the new datetime.now() when updated."

Explicit is better than implicit, right?

I made one workaround to achieve my needs: "default='1900-01-01
00:00:00', update=datetime.now()'.
This worked here and is an applicable solution to my case.

Again, I think this behaviour (default=update in absense of the first)
must be explicit in the manual. Please.


>
> The current design still allows you to check whether a field was or
> not updated by comparing the created_on with the updated_on date.

Right. :-)

But an index search by "where updated_on > '1900-01-01 00:00:00'" is
much faster than "where updated_on = created_on", right?


>
> Because this is not clear in the docs we either have to revise the
> docs or change its behavior (the latter would break some users'code)
> and I think fixing the docs is a better approach.

Massimo, IMO one of the great web2py characteristics is keeping
backwards compatibility.
Actually, this what most motivated me to learn and use web2py. Knowing
that what I make will work forever is too comfortable. :-)

There are ways of doing all of that, creating new params at table or
field level to reflect new behaviour, if necessary, and also keeping
backwards compatibility.

About inserting refreshed default and update values:
refresh_value_on_each_call=False/True.
About not assuming default=update:
default_equals_to_update_if_absent=False/True.

To end my participation here, I loved web2py and my comments is to
help building a more intuitive and robust solution. It's *not* to
criticize your great work.

As I have large experience with corporate development, I'm used to see
some smells of possible mess, sometimes.

I'm here to help, not to perturb you all.

--
Vinicius Assef.

mdipierro

unread,
Nov 8, 2010, 5:25:30 PM11/8/10
to web2py-users
On Nov 8, 4:11 pm, Vinicius Assef <vinicius...@gmail.com> wrote:
> On Mon, Nov 8, 2010 at 5:49 PM, mdipierro <mdipie...@cs.depaul.edu> wrote:
> > Hi Vinicius,
>
> > I think there are two issues.
>
> > The fact that models are executed at every http request and therefore
> > values are set there is explained in the manual.
>
> I couldn't find that in DAL chapter (http://web2py.com/book/default/chapter/06).
> Where is it?


GRRRRRR. you are right! This is the most important issue and it is so
important that I assumed I spelled it clearly but looks like I did
not.
This calls for a major revision of chapter 3. Thanks for pointing this
out.

About your comments below. Let's hear form more people and I will also
sleep on it.

Massimo

mdipierro

unread,
Nov 8, 2010, 5:38:12 PM11/8/10
to web2py-users
I have a possible solution in trunk.

If you say default=None it does what you say and oncreate ignores
update. If you do not specify a default but you do specify an update,
default==update.

Would this be acceptable?

Massimo
> ...
>
> read more »

Vinicius Assef

unread,
Nov 8, 2010, 7:45:51 PM11/8/10
to web...@googlegroups.com
On Mon, Nov 8, 2010 at 8:38 PM, mdipierro <mdip...@cs.depaul.edu> wrote:
> I have a possible solution in trunk.
>
> If you say default=None it does what you say and oncreate ignores
> update. If you do not specify a default but you do specify an update,
> default==update.
>
> Would this be acceptable?

Massimo, it sounds reasonable to me.

But, more important than working this or that way, the documentation
must express this behaviour.

Congrats.

--
Vinicius Assef.

Reply all
Reply to author
Forward
0 new messages