Jim Steil | 12 May 19:57

Log changes to rows

Hi:

Is there an easy way to log CRUD changes to a table?  I know that I 
could do it by overriding all of the update methods, but that seems to 
be not right.  Googling for things like 'sqlobject log changes' just 
bring back references to logging at a lower level.  Any pointers would 
be appreciated.

    -Jim

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft 
Defy all challenges. Microsoft(R) Visual Studio 2008. 
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
Oleg Broytmann | 12 May 20:34
X-Face
Picon
Favicon

Re: Log changes to rows

On Mon, May 12, 2008 at 12:58:37PM -0500, Jim Steil wrote:
> Is there an easy way to log CRUD changes to a table?  I know that I 
> could do it by overriding all of the update methods

   Or setup listeners for signals. SQLObject send signals almost on every
action, and even allow the listeners to setup callbacks to be called after
the action. See http://sqlobject.org/SQLObject.html#events-signals

Oleg.
--

-- 
     Oleg Broytmann            http://phd.pp.ru/            phd <at> phd.pp.ru
           Programmers don't die, they just GOSUB without RETURN.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft 
Defy all challenges. Microsoft(R) Visual Studio 2008. 
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
Jim Steil | 12 May 21:03

Re: Log changes to rows

Oleg Broytmann wrote:
On Mon, May 12, 2008 at 12:58:37PM -0500, Jim Steil wrote:
Is there an easy way to log CRUD changes to a table? I know that I could do it by overriding all of the update methods
Or setup listeners for signals. SQLObject send signals almost on every action, and even allow the listeners to setup callbacks to be called after the action. See http://sqlobject.org/SQLObject.html#events-signals Oleg.
Thanks Oleg, I saw that too, but was confused by it.  I took a look at the code and I think I understand it now.

Thanks

    -Jim
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft 
Defy all challenges. Microsoft(R) Visual Studio 2008. 
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
sqlobject-discuss mailing list
sqlobject-discuss <at> lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sqlobject-discuss
Jim Steil | 13 May 17:48

Re: Log changes to rows

Jim Steil wrote:
Oleg Broytmann wrote:
On Mon, May 12, 2008 at 12:58:37PM -0500, Jim Steil wrote:
Is there an easy way to log CRUD changes to a table? I know that I could do it by overriding all of the update methods
Or setup listeners for signals. SQLObject send signals almost on every action, and even allow the listeners to setup callbacks to be called after the action. See http://sqlobject.org/SQLObject.html#events-signals Oleg.
Thanks Oleg, I saw that too, but was confused by it.  I took a look at the code and I think I understand it now.

Thanks

    -Jim
------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ _______________________________________________ sqlobject-discuss mailing list sqlobject-discuss <at> lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/sqlobject-discuss
Ok, I've gotten my events to work, but now have another newb question that I can't seem to find the answer to.  In the update listener I get the kwargs sent in to find which columns have been changed.  I can reference them as a dictionary.  I want to compare the fields sent in to see if they've changed and to get the previous value of them, but cannot find how to reference the specific column using a variable.  What I'd like to do is the following:

def updateListener(currentValues, newValues):
    for columnName in newValues:
       newValue = newValues[columnName]
       currentValue = currentValues[columnName]  ----- This is what doesn't work
       #  log changes here

The currentValues[columnName] doesn't work.  How can I get the old value of the changed column?

I'm guessing there is something really obvious that I'm just not grasping this morning.  Obviously, I could test all values explicitly, but I'd really rather not do that, and keep this listener really generic.

    -Jim
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft 
Defy all challenges. Microsoft(R) Visual Studio 2008. 
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
sqlobject-discuss mailing list
sqlobject-discuss <at> lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sqlobject-discuss
Oleg Broytmann | 13 May 18:20
X-Face
Picon
Favicon

Re: Log changes to rows

On Tue, May 13, 2008 at 10:48:24AM -0500, Jim Steil wrote:
> Ok, I've gotten my events to work, but now have another newb question 
> that I can't seem to find the answer to.  In the update listener I get 
> the kwargs sent in to find which columns have been changed.  I can 
> reference them as a dictionary.  I want to compare the fields sent in to 
> see if they've changed and to get the previous value of them, but cannot 
> find how to reference the specific column using a variable.  What I'd 
> like to do is the following:
> 
> def updateListener(currentValues, newValues):
>    for columnName in newValues:
>       newValue = newValues[columnName]
>       currentValue = currentValues[columnName]  ----- This is what 
> doesn't work
>       #  log changes here
> 
> The currentValues[columnName] doesn't work.  How can I get the old value 
> of the changed column?

   I believe 'currentValues' is the object (SQLObject) to be changed, not
a dictionary. Get the values by calling getattr(currentValues, columnName).

Oleg.
--

-- 
     Oleg Broytmann            http://phd.pp.ru/            phd <at> phd.pp.ru
           Programmers don't die, they just GOSUB without RETURN.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft 
Defy all challenges. Microsoft(R) Visual Studio 2008. 
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
Jim Steil | 14 May 17:36

Re: Log changes to rows

Oleg Broytmann wrote:
On Tue, May 13, 2008 at 10:48:24AM -0500, Jim Steil wrote:
Ok, I've gotten my events to work, but now have another newb question that I can't seem to find the answer to. In the update listener I get the kwargs sent in to find which columns have been changed. I can reference them as a dictionary. I want to compare the fields sent in to see if they've changed and to get the previous value of them, but cannot find how to reference the specific column using a variable. What I'd like to do is the following: def updateListener(currentValues, newValues): for columnName in newValues: newValue = newValues[columnName] currentValue = currentValues[columnName] ----- This is what doesn't work # log changes here The currentValues[columnName] doesn't work. How can I get the old value of the changed column?
I believe 'currentValues' is the object (SQLObject) to be changed, not a dictionary. Get the values by calling getattr(currentValues, columnName). Oleg.
Is there a way in the RowCreatedSignal event to capture the name of the object (table) that is being inserted into?

    -Jim
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft 
Defy all challenges. Microsoft(R) Visual Studio 2008. 
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
sqlobject-discuss mailing list
sqlobject-discuss <at> lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sqlobject-discuss
Oleg Broytmann | 14 May 22:41
X-Face
Picon
Favicon

Re: Log changes to rows

On Wed, May 14, 2008 at 10:37:31AM -0500, Jim Steil wrote:
> Is there a way in the RowCreatedSignal event to capture the name of the 
> object (table) that is being inserted into?
[skip]
> I've been trying to get my logging working now for the 
> RowCreatedSignal.  I was having some issues with the kwargs parm.  
> Instead of returning a dict with the values of my table, it is returning 
> a dict with the class, and the keyfield value of the new record.  Ex:  
> {'class': <class 'motion.model.Contact'>, 'id': 11L}

   The table's name is kw['class'].sqlmeta.table.

> When I changed the event from RowCreatedSignal to RowCreateSignal, 
> everything worked as expected, with the kwargs argument giving me the 
> values of the new record.  Ex:  {'changedOn': datetime.datetime(2008, 5, 
> 13, 16, 44, 57, 73000), 'county': '', 'distributor': None, 'city': '', 
> 'district': 58, 'title': '', 'state': '', 'address1': '', 'email': '', 
> 'fax': None, 'mobilePhone': None, 'companyName': '', 'phone2': None, 
> 'phone3': None, 'address2': '', 'phone1': None, 'zipCode': '', 
> 'hardcopyPriceLists': False, 'createdOn': datetime.datetime(2008, 5, 13, 
> 16, 44, 57, 73000), 'pager': None, 'homePhone': None, 'firstName': 
> u'Lou', 'lastName': u'Reichers', 'notes': None, 'customerNumber': None, 
> 'coopId': None, 'emailPriceLists': False}
> 
> I was expecting these two events to function the same.  Is this a bug in 
> the code, or something that I'm not understanding correctly?

   I think there is a misdesign. All signals should be sent 'self' as the
first parameter (and proper keywords where apropriate). As this would be
a major API change I can't just fix it in the current codebase. Will write
a TODO entry for the trunk; the fix will be in 0.11.

Oleg.
--

-- 
     Oleg Broytmann            http://phd.pp.ru/            phd <at> phd.pp.ru
           Programmers don't die, they just GOSUB without RETURN.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft 
Defy all challenges. Microsoft(R) Visual Studio 2008. 
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
Jim Steil | 14 May 22:58

Re: Log changes to rows

Oleg Broytmann wrote:
On Wed, May 14, 2008 at 10:37:31AM -0500, Jim Steil wrote:
Is there a way in the RowCreatedSignal event to capture the name of the object (table) that is being inserted into?
[skip]
I've been trying to get my logging working now for the RowCreatedSignal. I was having some issues with the kwargs parm. Instead of returning a dict with the values of my table, it is returning a dict with the class, and the keyfield value of the new record. Ex: {'class': <class 'motion.model.Contact'>, 'id': 11L}
The table's name is kw['class'].sqlmeta.table.
Oleg:  When I try this, I get a -- KeyError: 'class' -- exception.  But, I then changed it to kw['sender'].sqlmeta.table and it works fine.  Does that make any sense?

    -Jim
When I changed the event from RowCreatedSignal to RowCreateSignal, everything worked as expected, with the kwargs argument giving me the values of the new record. Ex: {'changedOn': datetime.datetime(2008, 5, 13, 16, 44, 57, 73000), 'county': '', 'distributor': None, 'city': '', 'district': 58, 'title': '', 'state': '', 'address1': '', 'email': '', 'fax': None, 'mobilePhone': None, 'companyName': '', 'phone2': None, 'phone3': None, 'address2': '', 'phone1': None, 'zipCode': '', 'hardcopyPriceLists': False, 'createdOn': datetime.datetime(2008, 5, 13, 16, 44, 57, 73000), 'pager': None, 'homePhone': None, 'firstName': u'Lou', 'lastName': u'Reichers', 'notes': None, 'customerNumber': None, 'coopId': None, 'emailPriceLists': False} I was expecting these two events to function the same. Is this a bug in the code, or something that I'm not understanding correctly?
I think there is a misdesign. All signals should be sent 'self' as the first parameter (and proper keywords where apropriate). As this would be a major API change I can't just fix it in the current codebase. Will write a TODO entry for the trunk; the fix will be in 0.11. Oleg.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft 
Defy all challenges. Microsoft(R) Visual Studio 2008. 
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
sqlobject-discuss mailing list
sqlobject-discuss <at> lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sqlobject-discuss
Oleg Broytmann | 14 May 23:14
X-Face
Picon
Favicon

Re: Log changes to rows

On Wed, May 14, 2008 at 03:58:10PM -0500, Jim Steil wrote:
> Oleg Broytmann wrote:
> >>RowCreatedSignal.  I was having some issues with the kwargs parm.  
> >>Instead of returning a dict with the values of my table, it is returning 
> >>a dict with the class, and the keyfield value of the new record.  Ex:  
> >>{'class': <class 'motion.model.Contact'>, 'id': 11L}
> >
> >   The table's name is kw['class'].sqlmeta.table.
> >
> Oleg:  When I try this, I get a -- KeyError: 'class' -- exception.  But, 
> I then changed it to kw['sender'].sqlmeta.table and it works fine.  Does 
> that make any sense?

   No, I do not understand what is going on. There is the key 'class' in the
dictionary. The word 'sender' is not mentioned in main.py (where the signal
is sent).

Oleg.
--

-- 
     Oleg Broytmann            http://phd.pp.ru/            phd <at> phd.pp.ru
           Programmers don't die, they just GOSUB without RETURN.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft 
Defy all challenges. Microsoft(R) Visual Studio 2008. 
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
Jim Steil | 14 May 23:21

Re: Log changes to rows

Oleg Broytmann wrote:
On Wed, May 14, 2008 at 03:58:10PM -0500, Jim Steil wrote:
Oleg Broytmann wrote:
RowCreatedSignal. I was having some issues with the kwargs parm. Instead of returning a dict with the values of my table, it is returning a dict with the class, and the keyfield value of the new record. Ex: {'class': <class 'motion.model.Contact'>, 'id': 11L}
The table's name is kw['class'].sqlmeta.table.
Oleg: When I try this, I get a -- KeyError: 'class' -- exception. But, I then changed it to kw['sender'].sqlmeta.table and it works fine. Does that make any sense?
No, I do not understand what is going on. There is the key 'class' in the dictionary. The word 'sender' is not mentioned in main.py (where the signal is sent). Oleg.
Let me elaborate a bit.  Maybe some of the other stuff I've done has messed things up.  Here is my full method:


def addListener(newValues, postFunctions, tableName='', **kw):
    try:
        user = identity.current.user.id
    except:
        user = None
       
    if tableName == '':
        tableName = kw['sender'].sqlmeta.table   
    cl = ChangeLog(user=user,
                tableName=tableName,
                operation='INSERT',
                columnName='All',
                beforeImage='',
                afterImage=str(newValues))       

I added the tableName parameter for when I'm adding rows to the special table created for SQLRelatedJoins.  When adding rows/removing rows to those tables, I'm manually calling this method to log my changes.  This same method is called by the RowCreateSignal event.

    -Jim
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft 
Defy all challenges. Microsoft(R) Visual Studio 2008. 
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
sqlobject-discuss mailing list
sqlobject-discuss <at> lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sqlobject-discuss
Oleg Broytmann | 14 May 23:33
X-Face
Picon
Favicon

Re: Log changes to rows

On Wed, May 14, 2008 at 04:21:54PM -0500, Jim Steil wrote:
> def addListener(newValues, postFunctions, tableName='', **kw):
>    try:
>        user = identity.current.user.id
>    except:
>        user = None
>       
>    if tableName == '':
>        tableName = kw['sender'].sqlmeta.table   
>    cl = ChangeLog(user=user,
>                tableName=tableName,
>                operation='INSERT',
>                columnName='All',
>                beforeImage='',
>                afterImage=str(newValues))       
> 
> I added the tableName parameter for when I'm adding rows to the special 
> table created for SQLRelatedJoins.  When adding rows/removing rows to 
> those tables, I'm manually calling this method to log my changes.  This 
> same method is called by the RowCreateSignal event.

   When it is called by the RowCreateSignal event, there should be 'class'
key in the kw, not 'sender'. But I must say I have never used events, so
I don't understand fully how they are implemented and used.

Oleg.
--

-- 
     Oleg Broytmann            http://phd.pp.ru/            phd <at> phd.pp.ru
           Programmers don't die, they just GOSUB without RETURN.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft 
Defy all challenges. Microsoft(R) Visual Studio 2008. 
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
Jim Steil | 14 May 23:46

Re: Log changes to rows

Oleg Broytmann wrote:
On Wed, May 14, 2008 at 04:21:54PM -0500, Jim Steil wrote:
def addListener(newValues, postFunctions, tableName='', **kw): try: user = identity.current.user.id except: user = None if tableName == '': tableName = kw['sender'].sqlmeta.table cl = ChangeLog(user=user, tableName=tableName, operation='INSERT', columnName='All', beforeImage='', afterImage=str(newValues)) I added the tableName parameter for when I'm adding rows to the special table created for SQLRelatedJoins. When adding rows/removing rows to those tables, I'm manually calling this method to log my changes. This same method is called by the RowCreateSignal event.
When it is called by the RowCreateSignal event, there should be 'class' key in the kw, not 'sender'. But I must say I have never used events, so I don't understand fully how they are implemented and used. Oleg.
Well, I guess we can leave it at that unless anyone else has anything to add.  Here is the dict that I get when I check what is in kw:

{'signal': <class 'sqlobject.events.RowCreateSignal'>, 'sender': <class 'motion.model.Contact'>}

    -Jim
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft 
Defy all challenges. Microsoft(R) Visual Studio 2008. 
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
sqlobject-discuss mailing list
sqlobject-discuss <at> lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sqlobject-discuss
Oleg Broytmann | 15 May 00:47
X-Face
Picon
Favicon

Re: Log changes to rows

On Wed, May 14, 2008 at 04:46:08PM -0500, Jim Steil wrote:
> >>def addListener(newValues, postFunctions, tableName='', **kw):
> Here is the dict that I get when I check what is in kw:
> 
> {'signal': <class 'sqlobject.events.RowCreateSignal'>, 'sender': <class 
> 'motion.model.Contact'>}

   How did you install the listener? Did you call
events.listen(addListener, Contact, RowCreateSignal)
   ?

Oleg.
--

-- 
     Oleg Broytmann            http://phd.pp.ru/            phd <at> phd.pp.ru
           Programmers don't die, they just GOSUB without RETURN.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft 
Defy all challenges. Microsoft(R) Visual Studio 2008. 
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
Jim Steil | 15 May 00:49

Re: Log changes to rows

Oleg Broytmann wrote:
On Wed, May 14, 2008 at 04:46:08PM -0500, Jim Steil wrote:
def addListener(newValues, postFunctions, tableName='', **kw):
Here is the dict that I get when I check what is in kw: {'signal': <class 'sqlobject.events.RowCreateSignal'>, 'sender': <class 'motion.model.Contact'>}
How did you install the listener? Did you call events.listen(addListener, Contact, RowCreateSignal) ? Oleg.
Yes
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft 
Defy all challenges. Microsoft(R) Visual Studio 2008. 
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
sqlobject-discuss mailing list
sqlobject-discuss <at> lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sqlobject-discuss
Oleg Broytmann | 15 May 01:17
X-Face
Picon
Favicon

Re: Log changes to rows

On Wed, May 14, 2008 at 05:49:17PM -0500, Jim Steil wrote:
> Oleg Broytmann wrote:
> >   How did you install the listener? Did you call
> >events.listen(addListener, Contact, RowCreateSignal)
> >  
> Yes

   Then inside
def addListener(newValues, postFunctions, tableName='', **kw):...

   newValues is a dict of values you want to inspect, and kw['sender'] is
the class 'Contact', so the table name is really
kw['sender'].sqlmeta.table.

PS. I understand events much better now. Thank you! ;)

Oleg.
--

-- 
     Oleg Broytmann            http://phd.pp.ru/            phd <at> phd.pp.ru
           Programmers don't die, they just GOSUB without RETURN.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft 
Defy all challenges. Microsoft(R) Visual Studio 2008. 
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
Jim Steil | 14 May 17:36

Re: Log changes to rows

Oleg Broytmann wrote:
On Tue, May 13, 2008 at 10:48:24AM -0500, Jim Steil wrote:
Ok, I've gotten my events to work, but now have another newb question that I can't seem to find the answer to. In the update listener I get the kwargs sent in to find which columns have been changed. I can reference them as a dictionary. I want to compare the fields sent in to see if they've changed and to get the previous value of them, but cannot find how to reference the specific column using a variable. What I'd like to do is the following: def updateListener(currentValues, newValues): for columnName in newValues: newValue = newValues[columnName] currentValue = currentValues[columnName] ----- This is what doesn't work # log changes here The currentValues[columnName] doesn't work. How can I get the old value of the changed column?
I believe 'currentValues' is the object (SQLObject) to be changed, not a dictionary. Get the values by calling getattr(currentValues, columnName). Oleg.
I've been trying to get my logging working now for the RowCreatedSignal.  I was having some issues with the kwargs parm.  Instead of returning a dict with the values of my table, it is returning a dict with the class, and the keyfield value of the new record.  Ex:  {'class': <class 'motion.model.Contact'>, 'id': 11L}

When I changed the event from RowCreatedSignal to RowCreateSignal, everything worked as expected, with the kwargs argument giving me the values of the new record.  Ex:  {'changedOn': datetime.datetime(2008, 5, 13, 16, 44, 57, 73000), 'county': '', 'distributor': None, 'city': '', 'district': 58, 'title': '', 'state': '', 'address1': '', 'email': '', 'fax': None, 'mobilePhone': None, 'companyName': '', 'phone2': None, 'phone3': None, 'address2': '', 'phone1': None, 'zipCode': '', 'hardcopyPriceLists': False, 'createdOn': datetime.datetime(2008, 5, 13, 16, 44, 57, 73000), 'pager': None, 'homePhone': None, 'firstName': u'Lou', 'lastName': u'Reichers', 'notes': None, 'customerNumber': None, 'coopId': None, 'emailPriceLists': False}

I was expecting these two events to function the same.  Is this a bug in the code, or something that I'm not understanding correctly?

    -Jim

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft 
Defy all challenges. Microsoft(R) Visual Studio 2008. 
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
sqlobject-discuss mailing list
sqlobject-discuss <at> lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sqlobject-discuss

Gmane