Thread: Re: [SQLObject] Log changes to rows
SQLObject is a Python ORM.
Brought to you by:
ianbicking,
phd
From: Jim S. <ji...@ql...> - 2008-05-14 15:37:43
|
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 |
From: Jim S. <ji...@ql...> - 2008-05-14 15:38:06
|
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 |
From: Oleg B. <ph...@ph...> - 2008-05-14 20:41:58
|
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/ ph...@ph... Programmers don't die, they just GOSUB without RETURN. |
From: Jim S. <ji...@ql...> - 2008-05-14 20:58:31
|
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. > |
From: Jim S. <ji...@ql...> - 2008-05-14 21:22:18
|
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 |
From: Jim S. <ji...@ql...> - 2008-05-14 21:46:10
|
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 |
From: Jim S. <ji...@ql...> - 2008-05-14 22:49:27
|
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 |
From: Oleg B. <ph...@ph...> - 2008-05-14 23:18:00
|
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/ ph...@ph... Programmers don't die, they just GOSUB without RETURN. |
From: Oleg B. <ph...@ph...> - 2008-05-14 21:14:34
|
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/ ph...@ph... Programmers don't die, they just GOSUB without RETURN. |
From: Oleg B. <ph...@ph...> - 2008-05-14 21:33:09
|
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/ ph...@ph... Programmers don't die, they just GOSUB without RETURN. |
From: Oleg B. <ph...@ph...> - 2008-05-14 22:47:33
|
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/ ph...@ph... Programmers don't die, they just GOSUB without RETURN. |