update existing instances of a class?
Aloha, I have a python product that I have modified (most importantly by adding some properties). Some instances already exist that were created prior to adding these properties. I have heard it is possible to update the existing instances (so that they get the new properties) - is this true? If so, where might I find info on how to do this? thanks, John S. __________________________________ Do you Yahoo!? New and Improved Yahoo! Mail - 100MB free storage! http://promotions.yahoo.com/new_mail
John Schinnerer wrote:
I have a python product that I have modified (most importantly by adding some properties). Some instances already exist that were created prior to adding these properties.
I have heard it is possible to update the existing instances (so that they get the new properties) - is this true?
Yep, using an external method, and maybe a bit of help from: http://www.zope.org/Members/chrisw/UpdateSupport Also, you could just add class variables to your object's class which have sensible default. cheers, Chris -- Simplistix - Content Management, Zope & Python Consulting - http://www.simplistix.co.uk
Aloha, --- Chris Withers <chris@simplistix.co.uk> wrote:
I have heard it is possible to update the existing instances (so that they get the new properties) - is this true?
Yep, using an external method, and maybe a bit of help from: http://www.zope.org/Members/chrisw/UpdateSupport
I don't see how UpdateSupport applies to updating existing class instances...it seems to be for some 2.3.x catalog upgrades and Core Session Tracking? Anyone know of more info anywhere on updating existing class instances when the class (in a python product) is modified by adding some properties?
Also, you could just add class variables to your object's class which have sensible default.
I don't understand - previous instances will not have the properties unless they are updated, correct? I need to update existing instances so that values for the 'new' properties added can be added to the existing instances. thanks, John S. __________________________________ Do you Yahoo!? Yahoo! Mail - Helps protect you from nasty viruses. http://promotions.yahoo.com/new_mail
Am Freitag, 10. September 2004 01:14 schrieb John Schinnerer:
Anyone know of more info anywhere on updating existing class instances when the class (in a python product) is modified by adding some properties?
Also, you could just add class variables to your object's class which have sensible default.
I don't understand - previous instances will not have the properties unless they are updated, correct?
not exactly, I think. If you change the definition of the class to have new attributes, every instances of that class will have these attributes, too. Of course, they will only have their default values, all the same. but at least you can be sure that every instance has the attributes. next step would be to touch every instance to give them their own values. this might be a simple as class MyClass: attr = None # new attr2 = '' # new def updateAttr(self, attr, attr2): self.attr = attr self.attr2 = attr2 Than you might write a PythonScript to find your instances and call the updateAttr() method on them. Hope that helps a bit, Sascha
Aloha,
If you change the definition of the class to have new attributes, every instances of that class will have these attributes, too.
Instances created *after* I add properties do, of course. Instances created *before* I added the properties do not...or if they do, an attribute error is generated anyway. For example: I have updated my python product code by adding properties to a class. I have refreshed the product via the ZMI. If I then go to an instance of the class created *before* the property additions and refresh, and click on the Properties tab, I get an attribute error. The error is generated in PropertyManager.py, on a call to getProperty. The error value is the name of the first property that is *not* present in the "old" instance of the class (any instance created before adding properties to the product and refreshing). So it doesn't appear to me that "old" instances automagically get the new properties, since they generate an attribute error when trying to access the first of the new properties. That is my question - is there any way to 'touch' the old instances so that they get the new properties? Or do they all have to be re-created and re-populated? Or am I totally mis-understanding everyone's answers thus far? thanks, John S. _______________________________ Do you Yahoo!? Shop for Back-to-School deals on Yahoo! Shopping. http://shopping.yahoo.com/backtoschool
On Sat, Sep 11, 2004 at 06:06:55PM -0700, John Schinnerer wrote:
For example: I have updated my python product code by adding properties to a class. I have refreshed the product via the ZMI. If I then go to an instance of the class created *before* the property additions and refresh, and click on the Properties tab, I get an attribute error. The error is generated in PropertyManager.py, on a call to getProperty. The error value is the name of the first property that is *not* present in the "old" instance of the class (any instance created before adding properties to the product and refreshing).
So it doesn't appear to me that "old" instances automagically get the new properties, since they generate an attribute error when trying to access the first of the new properties.
If it was just a vanilla attribute and not a Property, you could get away with having a default immutable value in the class, e.g. class Foo: new_property_id = 0 ... But there are two things the PropertyManager implementation does when you add a property: 1) it sets an attribute with the property's id. 2) it adds an entry to the instance's _properties dictionary (which is a mapping of property id to type). If _properties does not contain this entry, then getProperty(foo) will raise an error as you've noticed. This means that you really do need to touch all instances if you want them all to get a new property.
That is my question - is there any way to 'touch' the old instances so that they get the new properties?
There are two: 1) write some lazy auto-updating code in one of your class methods. e.g. (pseudocode): def getProperty(self, id, default=None): """ get the property""" if id in [list of the properties i'm adding]: if not self.hasProperty(id): self.setProperty(id, some_default_value) return PropertyManager.getProperty(self, The nice thing about this code is that it works "on demand". The problem is that you can never get rid of it unless you are sure you have asked for all relevant properties from all existing instances. In which case you might as well go to option 2. 2) write a Script that uses ZopeFind to find all instances of your class and call setProperty() on each of them. Run this script once and you're done. This is what I've always done. I think there are examples on zopelabs.com. -- Paul Winkler http://www.slinkp.com
Aloha, Here's a link to zopelabs that I think will answer my question about adding new properties to old class instances, in case it's useful to others: http://www.zopelabs.com/cookbook/1016047651 Unfortunately for my searching, the recipie title uses 'schema' instead of 'class' or 'instance' so it took me a while to find. Also, to simply batch update values for existing properties: http://www.zopelabs.com/cookbook/1022683717 cheers, John S. _______________________________ Do you Yahoo!? Shop for Back-to-School deals on Yahoo! Shopping. http://shopping.yahoo.com/backtoschool
Hello, I am trying to use the below code (from zopelabs) to update my existing class instances. When I run the python script to invoke the external method, I get an Attribute error on REQUEST. I have no idea why, or how to fix - and, I don't really understand the first part of the external method that has references to REQUEST and sets up the value of root. Any help appreciated... code/comments from zopelabs recipie is: ------------- #create a file in $ZOPE/Extensions called schema.py def addPropertyToObjectType(self, meta_type, property, prop_type=None): """ does a find for all meta_type's and then attaches this proeprty to them if they dont already ahve it """ root=None if self.REQUEST.has_key('VirtualRootPhysicalPath'): root = self.REQUEST.VirtualRootPhysicalPath else: root = ('',) root = self.restrictedTraverse(root) for result in self.ZopeFind(root, obj_metatypes=(meta_type, ), search_sub=1): id, o = result[0], result[1] if not hasattr(o, property): setattr(o, property, prop_type) #create a External Method id:addPropertyToMetaType #module = schema.py and function = addPropertyToObjectType #Now create a (Script)Python called add_body_text context.addPropertyToMetaType('DTML Document', 'my_CustomProperty') return 'fin' -------------- thanks, John S. __________________________________ Do you Yahoo!? New and Improved Yahoo! Mail - 100MB free storage! http://promotions.yahoo.com/new_mail
John Schinnerer wrote at 2004-9-13 15:33 -0700:
I am trying to use the below code (from zopelabs) to update my existing class instances. When I run the python script to invoke the external method, I get an Attribute error on REQUEST.
Be warned that the automatic "self" passing to ExternalMethods does not work reliably when the External Methods has optional arguments (as in your case). Pass the "self" explicitely.
... #create a file in $ZOPE/Extensions called schema.py def addPropertyToObjectType(self, meta_type, property, prop_type=None): """ does a find for all meta_type's and then attaches this proeprty to them if they dont already ahve it """ root=None if self.REQUEST.has_key('VirtualRootPhysicalPath'): ... context.addPropertyToMetaType('DTML Document', 'my_CustomProperty')
Use "context.addProperty...(context, ...) -- Dieter
John Schinnerer wrote:
I don't see how UpdateSupport applies to updating existing class instances...it seems to be for some 2.3.x catalog upgrades and Core Session Tracking?
Nope, those are example updaters, the idea is that you write one that does what you need, you can look at them for clues though...
Also, you could just add class variables to your object's class which have sensible default.
I don't understand - previous instances will not have the properties unless they are updated, correct?
Aha, you're talking about properties... yeah, you'll want an updater for this :-/ cheers, Chris -- Simplistix - Content Management, Zope & Python Consulting - http://www.simplistix.co.uk
participants (5)
-
Chris Withers -
Dieter Maurer -
John Schinnerer -
Paul Winkler -
Sascha Ottolski