From philipp at weitershausen.de Thu Jan 5 16:42:11 2006 From: philipp at weitershausen.de (Philipp von Weitershausen) Date: Thu, 05 Jan 2006 16:42:11 +0100 Subject: [Z3-sqlos] Re: sqlos, sites and local utilities In-Reply-To: <88d0d31b0601030803q2140e966y7ab3e85e1017024b@mail.gmail.com> References: <200511120805.22071.srichter@cosmos.phy.tufts.edu> <200601030932.46761.srichter@cosmos.phy.tufts.edu> <88d0d31b0601030803q2140e966y7ab3e85e1017024b@mail.gmail.com> Message-ID: <43BD3E53.8070007@weitershausen.de> Jeff Shell wrote: > What about using zope.app.component.hooks.setSite? It sets the site on > a zope.thread.local based object, and I believe most utility lookups > fall back on that setting if context is not supplied. All component look-ups *first* look at the closest site (which comes from the thread local) and then cascade back to less local sites until the global site is queried. Describing this as "falling back" on local sites for "most utility lookups" is incorrect. Now, the Component Architecture itself doesn't actually know about the site in the thread local. It needs to be told to look there. That's where the component hooks play a role. zope.app.component install those to make zope.component look for the thread local. Unless these hooks aren't installed, a site in the thread local won't be found. In Zope X3 3.0, these hooks were set via ZCML, in Zope 3.1+ you have to call zope.app.component.hooks.setHooks(). That bit me at least twice when I ported Five to Zope 3.2. Philipp From philipp at weitershausen.de Thu Jan 5 16:44:47 2006 From: philipp at weitershausen.de (Philipp von Weitershausen) Date: Thu, 05 Jan 2006 16:44:47 +0100 Subject: [Z3-sqlos] Re: sqlos, sites and local utilities In-Reply-To: <88d0d31b0601030803q2140e966y7ab3e85e1017024b@mail.gmail.com> References: <200511120805.22071.srichter@cosmos.phy.tufts.edu> <200601030932.46761.srichter@cosmos.phy.tufts.edu> <88d0d31b0601030803q2140e966y7ab3e85e1017024b@mail.gmail.com> Message-ID: <43BD3EEF.7010605@weitershausen.de> Jeff Shell wrote: > What about using zope.app.component.hooks.setSite? It sets the site on > a zope.thread.local based object, and I believe most utility lookups > fall back on that setting if context is not supplied. All component look-ups *first* look at the closest site (which comes from the thread local) and then cascade back to less local sites until the global site is queried. Describing this as "falling back" on local sites for "most utility lookups" is incorrect. Now, the Component Architecture itself doesn't actually know about the site in the thread local. It needs to be told to look there. That's where the component hooks play a role. zope.app.component install those to make zope.component look for the thread local. Unless these hooks aren't installed, a site in the thread local won't be found. In Zope X3 3.0, these hooks were set via ZCML, in Zope 3.1+ you have to call zope.app.component.hooks.setHooks(). That bit me at least twice when I ported Five to Zope 3.2. Philipp From christian.lueck at ruhr-uni-bochum.de Mon Jan 9 21:17:04 2006 From: christian.lueck at ruhr-uni-bochum.de (=?ISO-8859-1?Q?Christian_L=FCck?=) Date: Mon, 09 Jan 2006 20:17:04 +0000 Subject: [Z3-sqlos] [Fwd: Re: [z3] [Fwd: Re: [Zope3-Users] sqlos - getting factory of NoneType]] Message-ID: <43C2C4C0.5060704@ruhr-uni-bochum.de> Hi! Martijn yust asked me to forward to this list a discussion about the directive. Please refer to the following links to get it all: http://www.mail-archive.com/zope3-users at zope.org/msg00908.html http://codespeak.net/pipermail/z3/2006-January/000042.html -------- Original Message -------- Subject: Re: [z3] [Fwd: Re: [Zope3-Users] sqlos - getting factory of NoneType] Date: Mon, 09 Jan 2006 19:52:38 +0000 From: Christian L?ck To: jinty at web.de CC: z3base References: <43C007CB.2080804 at ruhr-uni-bochum.de> <20060109013813.GA8531 at minipas.home> Hi Brian! Brian Sutherland wrote: > On Sat, Jan 07, 2006 at 06:26:19PM +0000, Christian L?ck wrote: >> Hi >> >> The problem with sqlos seems: It does only work if ONE AND ONLY ONE >> factory for the content component (interface) in question is registered. >> And this one-and-only factory has to be registered with the >> zcml-directive in a special sqlos namespace, ie. >> >> > id="quotationtool.BookSQLObject" >> component=".book.Book" >> title="BookSQLObject" >> description="A book object for the sql resourcedb." >> /> >> >> When a second factory is registered for the same interface, ie. >> >> > id="quotationtool.BookWithInitialValues" >> component=".book.BookFactory" >> title="BookWithInitialValues" >> description="A factory for book object with initial values." >> /> >> >> sqlos fails to get the objects stored on the database (you get blank >> browser pages). >> The reason seems to be the implementation of >> sqlos.container.SQLObjectContainer, which maps between sql-unique-keys >> (SQLObject-names) and zope-object-names. The mapping mechanism makes use >> of the factory. > > Yes, I have seen this problem before. You cannot mix sqlos:factory and > factory and expect things to work. > > And yes, this is a _big_ problem which I think requires a re-think of > how we do this. But that re-think is not yet thunk. > > So please try this patch (untested). If it works for you, I will add it > to the source. > > Index: container.py > =================================================================== > --- container.py (revision 21506) > +++ container.py (working copy) > @@ -106,7 +106,9 @@ > (name, object) for the objects that appear in the folder. > """ > for factoryName in self.allowedFactories(): > - factory = zapi.getUtility(IISQLObject, factoryName, context=self) > + factory = zapi.queryUtility(IISQLObject, factoryName, context=self) > + if factory is None: > + continue > for obj in factory.select(): > name = '%s.%s' % (factoryName, obj.id) > yield (name, contained(obj, parent=self, name=name)) > No, this does not work for me. The problem with the "None type" was not mine. I was answering to an other email. - I was facing the analgue problem of several factories returned by the allowedFactories() method which caused errors. Well I have found a solution now. See the diff I have attached. 1) First of all we define a marker Interface ISQLObjectFactory, see what I added to interfaces.__init__.py. 2) Then we implement this marker interface by factories registered by the directive. See what I added to metaconfigure.py. 3) Then we check for this marker interface in the allowedFactories() method of SQLObjectContainer. Have a look at what I added to container.py Well, in your diff you added the check for "None type" to the items() method. I think one should rather check the factories in the allowedFactories() method already. For a) allowedFactories() could be and in fact is called somewhere else and allways only our sqlos:factory is an allowed factory for things relavat in SQLObjectContainer; b) the allowedFactory() method is sqlos specific, it's not a common thing specified in any zope interface. This way we achieve this: - sqlos gets more tyres on the standard zope3 highway: We can now register etc. besides without getting errors. - Since all changes are sqlos internal sqlos applications keep running without any changes -- provided zcml (the - directive) was used to wire things together. >> This way it works, I see the sql-objects and can even edit them :) - But >> works yust to run into the next bigger problem... (I can't create >> objects due to rollback problems) :(((( > > If you post a traceback here, there is a chance someone can give you a > quick answer. > Well, this was due to the incompatibility regarding the z3 standard two step process of adding content. You already read about my solution... Kind Regards, Christian PS. It was the first time I created a diff. I'm not sure if one can use it at all, because of the filenames. Do you know a good HOWTO, maybe zope specific? PS2. Maybe we should check for "None type", too. -------------- next part -------------- A non-text attachment was scrubbed... Name: sqlos.diff Type: text/x-patch Size: 2236 bytes Desc: not available Url : http://codespeak.net/pipermail/z3-sqlos/attachments/20060109/e092aaca/attachment.bin From christian.lueck at ruhr-uni-bochum.de Mon Jan 9 21:26:01 2006 From: christian.lueck at ruhr-uni-bochum.de (=?ISO-8859-1?Q?Christian_L=FCck?=) Date: Mon, 09 Jan 2006 20:26:01 +0000 Subject: [Z3-sqlos] [Fwd: sqlos: add view for SQLOS objects] Message-ID: <43C2C6D9.6080509@ruhr-uni-bochum.de> -------- Original Message -------- Subject: sqlos: add view for SQLOS objects Date: Sat, 07 Jan 2006 18:20:42 +0000 From: Christian L?ck To: z3base Hi! I yust found out how to implement add views for a SQLOS-inheriting content component. Since it might be interisting for others I post it here. If this should be old hat to you, sorry. The key to get an IAdding view for SQLOS objects running is that you have to leave the z3 standard two step add process. To put it short: You have to rewrite (leave away) the add() method for the add view (inherited from zope.app.form.browser.AddView or zope.formlib.form.AddFormBase). More detailed: The standard z3 prozess to add an object to a container is two steps: 1) Creation of the object by calling a factory. 2) Adding this object instance to a container. This is normally handled by a method of the add view called createAndAdd(). createAndAdd() again calls create() for step 1 and then add() for step 2. Lets have a look at zope.formlib.form.AddFormBase : class AddFormBase(FormBase): ### snip ### def createAndAdd(self, data): ob = self.create(data) zope.event.notify( zope.app.event.objectevent.ObjectCreatedEvent(ob)) return self.add(ob) def create(self, data): raise NotImplementedError( "concrete classes must implement create() or createAndAdd()") _finished_add = False def add(self, object): ob = self.context.add(object) # *<--- THE PROBLEM* self._finished_add = True return ob ### snip ### Creating an SQLOS object differs from this standard inasmuch step 2 is not only not recommended (a) but even causes errors (b). a) not recommended: As a consequence of the current sqlos implementation all instances of a content component class inheriting from SQLOS go into the same rdb table. => Each container for this content component shows all the instances of this component. Imagine two containers with preconditions set for the same content component, each one will show a set union as its items. - That's why SQLOS objects are not really locateable. Corollar: Instantiating an content object, which inherits from SQLOS, lets this instance show up in each SQLObjectContainer with matching preconditions. b) You simply can't add an SQLOS object to somewhere. someSQLObjectContainer['some_name'] = someSQLOSInstance causes diverse errors due to the logic of the current implementation. It would cost a >50 words analysis, so I leave it at the moment. This in mind a possible implementation based on formlib would be: (my example is a Book(SQLOS) object) class BookFormlibAddView(form.AddForm): form_fields = form.Fields(IBook) def create(self, data): """Call a factory to instantiate an object.""" factory = zapi.getUtility(IFactory, u"quotationtool.BookWithInitialValues") obj = factory( lang = data['lang'], is_original = data['is_original'], abbrev_orig_title = data['abbrev_orig_title'], ### snip ### series = data['series']) return obj def add(self, object): #ob = self.context.add(object) # in sqlos we don't add an object to a container, so we don't need this self._finished_add = True #return ob return object *Note that this makes use of a factory* -- which is an other major problem that one faces with the current sqlos. Please refer to my other posting on it: http://www.mail-archive.com/zope3-users at zope.org/msg01423.html Registration: This way one gets things working. Proposal / Desiderata: - sqlos.container.SQLObjectContainer should be reimplemented to get standard add views ( = views for zope.app.container.interfaces.IAdding ) going. Idea (but not more): Reimplement the methods of SQLContainerObjects which are called by the magic '+' ( = an implementation of IAdding), which is called by the standard z3 add() methods in zope.app.form.browser.add.AddView or zope.formlib.form.AddFormBase. - still before, sqlos.container.SQLObjectContainer should be recoded to get it working with many factories registrated for a contained SQLOS content component. See my other posting for this problem. - really locatable SQLOS objects would be nice, but I know this would be hard work... Kind regards, Christian PS 2006-01-09: Brian already posted an answer: http://codespeak.net/pipermail/z3/2006-January/000043.html From christian.lueck at ruhr-uni-bochum.de Tue Jan 10 00:52:54 2006 From: christian.lueck at ruhr-uni-bochum.de (=?UTF-8?B?Q2hyaXN0aWFuIEzDvGNr?=) Date: Mon, 09 Jan 2006 23:52:54 +0000 Subject: [Z3-sqlos] Re: [z3] [Fwd: Re: [Zope3-Users] sqlos - getting factory of NoneType] In-Reply-To: <20060109215955.GA8072@minipas.home> References: <43C007CB.2080804@ruhr-uni-bochum.de> <20060109013813.GA8531@minipas.home> <43C2BF06.1050208@ruhr-uni-bochum.de> <20060109215955.GA8072@minipas.home> Message-ID: <43C2F756.3090905@ruhr-uni-bochum.de> Brian Sutherland wrote: > On Mon, Jan 09, 2006 at 07:52:38PM +0000, Christian L?ck wrote: >> Hi Brian! >> >> Brian Sutherland wrote: >> > On Sat, Jan 07, 2006 at 06:26:19PM +0000, Christian L?ck wrote: >> >> Hi >> >> >> >> The problem with sqlos seems: It does only work if ONE AND ONLY ONE >> >> factory for the content component (interface) in question is registered. >> >> And this one-and-only factory has to be registered with the >> >> zcml-directive in a special sqlos namespace, ie. >> >> >> >> > >> id="quotationtool.BookSQLObject" >> >> component=".book.Book" >> >> title="BookSQLObject" >> >> description="A book object for the sql resourcedb." >> >> /> >> >> >> >> When a second factory is registered for the same interface, ie. >> >> >> >> > >> id="quotationtool.BookWithInitialValues" >> >> component=".book.BookFactory" >> >> title="BookWithInitialValues" >> >> description="A factory for book object with initial values." >> >> /> >> >> >> >> sqlos fails to get the objects stored on the database (you get blank >> >> browser pages). >> >> The reason seems to be the implementation of >> >> sqlos.container.SQLObjectContainer, which maps between sql-unique-keys >> >> (SQLObject-names) and zope-object-names. The mapping mechanism makes use >> >> of the factory. >> > >> > Yes, I have seen this problem before. You cannot mix sqlos:factory and >> > factory and expect things to work. >> > >> > And yes, this is a _big_ problem which I think requires a re-think of >> > how we do this. But that re-think is not yet thunk. >> > >> > So please try this patch (untested). If it works for you, I will add it >> > to the source. >> > >> > Index: container.py >> > =================================================================== >> > --- container.py (revision 21506) >> > +++ container.py (working copy) >> > @@ -106,7 +106,9 @@ >> > (name, object) for the objects that appear in the folder. >> > """ >> > for factoryName in self.allowedFactories(): >> > - factory = zapi.getUtility(IISQLObject, factoryName, context=self) >> > + factory = zapi.queryUtility(IISQLObject, factoryName, context=self) >> > + if factory is None: >> > + continue >> > for obj in factory.select(): >> > name = '%s.%s' % (factoryName, obj.id) >> > yield (name, contained(obj, parent=self, name=name)) >> > >> >> No, this does not work for me. > > Why? Well, as you can see from the debugging in my first email, getFactoriesFor() does not return me a None type. I have registered a factory with . So in the list of returned factories there is a object. The point is that a factory component has a getInterfaces() method, that returns all interfaces implemented by an object which can be created by this factory. See zope.component.interfaces.IFactory and p. 69. That's why allowedFactories() as currently implemented returns a set union of factories for components quontained in an SQLObjectContainer of AND . If you have the 'Person' example from README.txt as a tar ball, I would beg you to send it to me. Then we could discuss a common example. > >> The problem with the "None type" was not >> mine. I was answering to an other email. - I was facing the analgue >> problem of several factories returned by the allowedFactories() method >> which caused errors. >> >> Well I have found a solution now. See the diff I have attached. >> >> 1) First of all we define a marker Interface ISQLObjectFactory, see what >> I added to interfaces.__init__.py. > > The problem I have with a marker interface is that it introduces a > new concept, increasing the complexity of the code. If we can do the > same without this concept, and with less lines of code, we should. > > It's a little concept, I know, but still something extra you need to > understand when reading the code. Ok, so lets formulate the problem: We have to get allowedFactories() to know which factory to pick. That means there has to be a information sticking on the right factory that makes the difference. Is it already there? Well, I don't know. Maybe, because of the registration via the sqlos namespace. I did not dig deep into metaconfiguration. Now lets talk about possible implementations: An argument for a marker interface would be, that it is a peace of information that is as much independent from the implementation of the factory as could be. It's a merely semantic concept. Marking makes a difference. (Maybe I like it because I'm a student of linguistics :) > >> 2) Then we implement this marker interface by factories registered by >> the directive. See what I added to metaconfigure.py. >> >> 3) Then we check for this marker interface in the allowedFactories() >> method of SQLObjectContainer. Have a look at what I added to container.py >> Well, in your diff you added the check for "None type" to the items() >> method. I think one should rather check the factories in the >> allowedFactories() method already. > > Yes, I agree, but I also know that there are people who use > allowedFactories in their own code. So just changing the meaning of the > function is a non flyer. > > So what I would like is to deprecate it and introduce a new function > getAllowedIISQLObjectUtilities, which would return a generator of tuples > (utility name, utility) and incorporate the check for None. All users of > allowedFactories in the sqlos source can then be converted to this > function. > > So instead of introducing a new concept, we can take away an old one and > replace it with a new one. > I think that's a very good point. Well, I admit, that I haven't got enough experience to decide such things. > Also, perhaps the new function should be private? > Ok. Good! >> For a) allowedFactories() could be >> and in fact is called somewhere else and allways only our sqlos:factory >> is an allowed factory for things relavat in SQLObjectContainer; b) the >> allowedFactory() method is sqlos specific, it's not a common thing >> specified in any zope interface. >> >> This way we achieve this: >> >> - sqlos gets more tyres on the standard zope3 highway: We can now >> register etc. besides without getting errors. >> >> - Since all changes are sqlos internal sqlos applications keep running >> without any changes -- provided zcml (the - directive) >> was used to wire things together. >> I have to correct myself: Even registration via phython works, because the marker interface is implemented in the class. >> >> >> >> This way it works, I see the sql-objects and can even edit them :) - But >> >> works yust to run into the next bigger problem... (I can't create >> >> objects due to rollback problems) :(((( >> > >> > If you post a traceback here, there is a chance someone can give you a >> > quick answer. >> > >> >> Well, this was due to the incompatibility regarding the z3 standard two >> step process of adding content. You already read about my solution... > > Yeah, but what I want to know is why the two step process works for me, > but not for you. > Please send me your Person example. >> >> Kind Regards, >> Christian >> >> PS. It was the first time I created a diff. I'm not sure if one can use >> it at all, because of the filenames. > > Thanks for the diff it makes it very clear what you are talking about! > And normally the filenames are no problem as one can use the -p argument > to patch. Though it might be easier for you to generate them using 'svn > diff'. > >> Do you know a good HOWTO, maybe zope specific? >> >> PS2. Maybe we should check for "None type", too. > >> diff -urN sqlos-21844/container.py sqlos-work/container.py >> --- sqlos-21844/container.py 2006-01-09 18:13:45.000000000 +0000 >> +++ sqlos-work/container.py 2006-01-09 18:20:03.000000000 +0000 >> @@ -29,6 +29,7 @@ >> from sqlos.interfaces import ISQLObject, ISQLObjectIsolated, IISQLObject >> from sqlos.interfaces.container import ISQLObjectContainer >> from sqlos.interfaces.container import IIsolatedSQLContainer >> +from sqlos.interfaces import ISQLObjectFactory >> >> def contained(obj, parent=None, name=None): >> """An implementation of zope.app.container.contained.contained >> @@ -84,7 +85,9 @@ >> def allowedFactories(self): >> for name, factory in zapi.getFactoriesFor(ISQLObject, context=self): >> if checkFactory(self, None, factory): >> - yield name >> + # check if registered with >> + if ISQLObjectFactory.providedBy(factory): >> + yield name >> >> def keys(self): >> """ Return a sequence-like object containing the names >> diff -urN sqlos-21844/interfaces/__init__.py sqlos-work/interfaces/__init__.py >> --- sqlos-21844/interfaces/__init__.py 2006-01-09 18:13:45.000000000 +0000 >> +++ sqlos-work/interfaces/__init__.py 2006-01-09 17:44:26.000000000 +0000 >> @@ -335,3 +335,9 @@ >> >> def next(): >> """ Iterator """ >> + >> +class ISQLObjectFactory(Interface): >> + """This is a marker interface. A Factory which is registered >> + by the directive gets marked and can therefore >> + be distinguished from other factories for a content component.""" >> + pass >> diff -urN sqlos-21844/metaconfigure.py sqlos-work/metaconfigure.py >> --- sqlos-21844/metaconfigure.py 2006-01-09 18:13:45.000000000 +0000 >> +++ sqlos-work/metaconfigure.py 2006-01-09 17:33:07.000000000 +0000 >> @@ -18,9 +18,10 @@ >> from zope.component.factory import Factory, IFactory >> from sqlos.interfaces import IISQLObject, IConnectionName >> from sqlos.interfaces import IReadSQLObjectClass, IWriteSQLObjectClass >> +from sqlos.interfaces import ISQLObjectFactory >> >> class SQLObjectFactory(Factory): >> - implements(IFactory) >> + implements(IFactory, ISQLObjectFactory) > > Actually, we could probably get rid of SQLObjectFactory as well. How would that look like? Don't we need it to make python/z3 objects from rdb columns? > >> >> def handler(_context, component, id, title=None, description=None): >> if isinstance(component, basestring): > > From jinty at web.de Tue Jan 10 02:30:33 2006 From: jinty at web.de (Brian Sutherland) Date: Tue, 10 Jan 2006 02:30:33 +0100 Subject: [Z3-sqlos] Re: [z3] [Fwd: Re: [Zope3-Users] sqlos - getting factory of NoneType] In-Reply-To: <43C2F756.3090905@ruhr-uni-bochum.de> References: <43C007CB.2080804@ruhr-uni-bochum.de> <20060109013813.GA8531@minipas.home> <43C2BF06.1050208@ruhr-uni-bochum.de> <20060109215955.GA8072@minipas.home> <43C2F756.3090905@ruhr-uni-bochum.de> Message-ID: <20060110013032.GA14044@minipas.home> Hi Christian, I have implemented the changes I have been talking about on a branch, you can see the checkins, starting from this post: http://codespeak.net/pipermail/z3-checkins/2006q1/001908.html Does anyone else have any comments on this? On Mon, Jan 09, 2006 at 11:52:54PM +0000, Christian L?ck wrote: > Brian Sutherland wrote: > > On Mon, Jan 09, 2006 at 07:52:38PM +0000, Christian L?ck wrote: > >> Hi Brian! > >> > >> Brian Sutherland wrote: > >> > On Sat, Jan 07, 2006 at 06:26:19PM +0000, Christian L?ck wrote: > >> >> Hi > >> >> > >> >> The problem with sqlos seems: It does only work if ONE AND ONLY ONE > >> >> factory for the content component (interface) in question is registered. > >> >> And this one-and-only factory has to be registered with the > >> >> zcml-directive in a special sqlos namespace, ie. > >> >> > >> >> >> >> id="quotationtool.BookSQLObject" > >> >> component=".book.Book" > >> >> title="BookSQLObject" > >> >> description="A book object for the sql resourcedb." > >> >> /> > >> >> > >> >> When a second factory is registered for the same interface, ie. > >> >> > >> >> >> >> id="quotationtool.BookWithInitialValues" > >> >> component=".book.BookFactory" > >> >> title="BookWithInitialValues" > >> >> description="A factory for book object with initial values." > >> >> /> > >> >> > >> >> sqlos fails to get the objects stored on the database (you get blank > >> >> browser pages). > >> >> The reason seems to be the implementation of > >> >> sqlos.container.SQLObjectContainer, which maps between sql-unique-keys > >> >> (SQLObject-names) and zope-object-names. The mapping mechanism makes use > >> >> of the factory. > >> > > >> > Yes, I have seen this problem before. You cannot mix sqlos:factory and > >> > factory and expect things to work. > >> > > >> > And yes, this is a _big_ problem which I think requires a re-think of > >> > how we do this. But that re-think is not yet thunk. > >> > > >> > So please try this patch (untested). If it works for you, I will add it > >> > to the source. > >> > > >> > Index: container.py > >> > =================================================================== > >> > --- container.py (revision 21506) > >> > +++ container.py (working copy) > >> > @@ -106,7 +106,9 @@ > >> > (name, object) for the objects that appear in the folder. > >> > """ > >> > for factoryName in self.allowedFactories(): > >> > - factory = zapi.getUtility(IISQLObject, factoryName, context=self) > >> > + factory = zapi.queryUtility(IISQLObject, factoryName, context=self) > >> > + if factory is None: > >> > + continue > >> > for obj in factory.select(): > >> > name = '%s.%s' % (factoryName, obj.id) > >> > yield (name, contained(obj, parent=self, name=name)) > >> > > >> > >> No, this does not work for me. > > > > Why? > > Well, as you can see from the debugging in my first email, > getFactoriesFor() does not return me a None type. I have registered a > factory with . So in the list of returned factories there > is a > object. > > The point is that a factory component has a getInterfaces() method, that > returns all interfaces implemented by an object which can be created by > this factory. See zope.component.interfaces.IFactory and p. 69. > > That's why allowedFactories() as currently implemented returns a set > union of factories for components quontained in an SQLObjectContainer of > AND . Exactly. Then queryUtility(IISQLObject, factoryName) will return None for everything registered with and an object implementing IISQLObject for everything registered with . So filtering these for None will give you only the set of objects registered with . > If you have the 'Person' example from README.txt as a tar ball, I would > beg you to send it to me. Then we could discuss a common example. Have a look at the source in sqlos/testing/sampleperson.py and sqlos/ftesting.zcml. The add and edit views are tested in ftests/adding.txt. That is our functional testing infrastructure and is actually a mini-application in it's own right. > > > >> The problem with the "None type" was not > >> mine. I was answering to an other email. - I was facing the analgue > >> problem of several factories returned by the allowedFactories() method > >> which caused errors. > >> > >> Well I have found a solution now. See the diff I have attached. > >> > >> 1) First of all we define a marker Interface ISQLObjectFactory, see what > >> I added to interfaces.__init__.py. > > > > The problem I have with a marker interface is that it introduces a > > new concept, increasing the complexity of the code. If we can do the > > same without this concept, and with less lines of code, we should. > > > > It's a little concept, I know, but still something extra you need to > > understand when reading the code. > > Ok, so lets formulate the problem: > > We have to get allowedFactories() to know which factory to pick. That > means there has to be a information sticking on the right factory that > makes the difference. > Is it already there? Well, I don't know. Maybe, because of the > registration via the sqlos namespace. I did not dig deep into > metaconfiguration. > > Now lets talk about possible implementations: > > An argument for a marker interface would be, that it is a peace of > information that is as much independent from the implementation of the > factory as could be. It's a merely semantic concept. Marking makes a > difference. > (Maybe I like it because I'm a student of linguistics :) Heh;) I am an engineer, which means I generally throw a brick at it if it doesn't work. But how about this, the information needed to tell whether a factory is a good one to pick is already there. If there was no corresponding registration of an IISQLObject utility, then the factory is not one that we want. queryUtility tells us this by returning None. The key here is that registers an IISQLObject utility and and then does whatever does. By adding a marker interface you can make that very explicit, but I am not convinced it is necessary. > >> diff -urN sqlos-21844/metaconfigure.py sqlos-work/metaconfigure.py > >> --- sqlos-21844/metaconfigure.py 2006-01-09 18:13:45.000000000 +0000 > >> +++ sqlos-work/metaconfigure.py 2006-01-09 17:33:07.000000000 +0000 > >> @@ -18,9 +18,10 @@ > >> from zope.component.factory import Factory, IFactory > >> from sqlos.interfaces import IISQLObject, IConnectionName > >> from sqlos.interfaces import IReadSQLObjectClass, IWriteSQLObjectClass > >> +from sqlos.interfaces import ISQLObjectFactory > >> > >> class SQLObjectFactory(Factory): > >> - implements(IFactory) > >> + implements(IFactory, ISQLObjectFactory) > > > > Actually, we could probably get rid of SQLObjectFactory as well. > > How would that look like? Don't we need it to make python/z3 objects > from rdb columns? Well, Factory already implements IFactory, so we could just delete SQLObjectFactory and replace it with factory wherever it was used. I doubt we will need to deprecate this first. see: http://codespeak.net/pipermail/z3-checkins/2006q1/001911.html > > > >> > >> def handler(_context, component, id, title=None, description=None): > >> if isinstance(component, basestring): -- Brian Sutherland Metropolis - "it's the first movie with a robot. And she's a woman. And she's EVIL!!" From jinty at web.de Fri Jan 13 15:25:37 2006 From: jinty at web.de (Brian Sutherland) Date: Fri, 13 Jan 2006 15:25:37 +0100 Subject: [Z3-sqlos] Removal of the sqlos connection cache Message-ID: <20060113142537.GA5896@minipas.home> Hi, I have been seeing this problem on my production instances: http://mail.zope.org/pipermail/zope3-dev/2005-December/017052.html On my way to try to solve this, I noticed that if a connection "goes away" or is closed, the sqlos connection cache will still keep delivering that connection until a server restart. On further investigation, it appeared that there were a total of three thread safe caches between the connection and it being used. One in sqlobject, one in sqlos and one in zope.app.rdb (since r30682). This is obviously silly, so I tried to fix this on a branch: http://codespeak.net/svn/z3/sqlos/branch/jinty-connection but this code is quite fundamental and I would appreciate some people looking over it or testing before I commit it to the trunk. One thing I am worried about with this code is that it changes the sqlobject cache from a per-thread cache to a global cache. I am not sure if this is a good or bad thing... -- Brian Sutherland Metropolis - "it's the first movie with a robot. And she's a woman. And she's EVIL!!" From jinty at web.de Sat Jan 14 08:00:33 2006 From: jinty at web.de (Brian Sutherland) Date: Sat, 14 Jan 2006 08:00:33 +0100 Subject: [Z3-sqlos] Removal of the sqlos connection cache In-Reply-To: <20060113142537.GA5896@minipas.home> References: <20060113142537.GA5896@minipas.home> Message-ID: <20060114070033.GA9874@minipas.home> On Fri, Jan 13, 2006 at 03:25:37PM +0100, Brian Sutherland wrote: > One thing I am worried about with this code is that it changes the > sqlobject cache from a per-thread cache to a global cache. I am not sure > if this is a good or bad thing... For the record, andres re-educated me in irc about this. The cache is now a thread local cache and is cleared on every new transaction. This lead to a small cleanup of the transaction machinery. This hopefully makes it possible to use sqlos in a ZEO like way with multiple application servers using the same database. Just don't keep references to SQLOS objects over transactions. -- Brian Sutherland Metropolis - "it's the first movie with a robot. And she's a woman. And she's EVIL!!" From christian.lueck at ruhr-uni-bochum.de Fri Jan 20 22:45:00 2006 From: christian.lueck at ruhr-uni-bochum.de (=?UTF-8?B?Q2hyaXN0aWFuIEzDvGNr?=) Date: Fri, 20 Jan 2006 21:45:00 +0000 Subject: [Z3-sqlos] Re: [z3] [Fwd: Re: [Zope3-Users] sqlos - getting factory of NoneType] In-Reply-To: <20060110013032.GA14044@minipas.home> References: <43C007CB.2080804@ruhr-uni-bochum.de> <20060109013813.GA8531@minipas.home> <43C2BF06.1050208@ruhr-uni-bochum.de> <20060109215955.GA8072@minipas.home> <43C2F756.3090905@ruhr-uni-bochum.de> <20060110013032.GA14044@minipas.home> Message-ID: <43D159DC.2050609@ruhr-uni-bochum.de> Hi Brian, Brian Sutherland wrote: > Hi Christian, > > I have implemented the changes I have been talking about on a branch, > you can see the checkins, starting from this post: > > http://codespeak.net/pipermail/z3-checkins/2006q1/001908.html > > Does anyone else have any comments on this? > > On Mon, Jan 09, 2006 at 11:52:54PM +0000, Christian L?ck wrote: >> Brian Sutherland wrote: >> > On Mon, Jan 09, 2006 at 07:52:38PM +0000, Christian L?ck wrote: >> >> Hi Brian! >> >> >> >> Brian Sutherland wrote: >> >> > On Sat, Jan 07, 2006 at 06:26:19PM +0000, Christian L?ck wrote: >> >> >> Hi >> >> >> >> >> >> The problem with sqlos seems: It does only work if ONE AND ONLY ONE >> >> >> factory for the content component (interface) in question is registered. >> >> >> And this one-and-only factory has to be registered with the >> >> >> zcml-directive in a special sqlos namespace, ie. >> >> >> >> >> >> > >> >> id="quotationtool.BookSQLObject" >> >> >> component=".book.Book" >> >> >> title="BookSQLObject" >> >> >> description="A book object for the sql resourcedb." >> >> >> /> >> >> >> >> >> >> When a second factory is registered for the same interface, ie. >> >> >> >> >> >> > >> >> id="quotationtool.BookWithInitialValues" >> >> >> component=".book.BookFactory" >> >> >> title="BookWithInitialValues" >> >> >> description="A factory for book object with initial values." >> >> >> /> >> >> >> >> >> >> sqlos fails to get the objects stored on the database (you get blank >> >> >> browser pages). >> >> >> The reason seems to be the implementation of >> >> >> sqlos.container.SQLObjectContainer, which maps between sql-unique-keys >> >> >> (SQLObject-names) and zope-object-names. The mapping mechanism makes use >> >> >> of the factory. >> >> > >> >> > Yes, I have seen this problem before. You cannot mix sqlos:factory and >> >> > factory and expect things to work. >> >> > >> >> > And yes, this is a _big_ problem which I think requires a re-think of >> >> > how we do this. But that re-think is not yet thunk. >> >> > >> >> > So please try this patch (untested). If it works for you, I will add it >> >> > to the source. >> >> > >> >> > Index: container.py >> >> > =================================================================== >> >> > --- container.py (revision 21506) >> >> > +++ container.py (working copy) >> >> > @@ -106,7 +106,9 @@ >> >> > (name, object) for the objects that appear in the folder. >> >> > """ >> >> > for factoryName in self.allowedFactories(): >> >> > - factory = zapi.getUtility(IISQLObject, factoryName, context=self) >> >> > + factory = zapi.queryUtility(IISQLObject, factoryName, context=self) >> >> > + if factory is None: >> >> > + continue >> >> > for obj in factory.select(): >> >> > name = '%s.%s' % (factoryName, obj.id) >> >> > yield (name, contained(obj, parent=self, name=name)) >> >> > >> >> >> >> No, this does not work for me. >> > >> > Why? >> >> Well, I yust checked out from trunk. It works fine now. Thanks! I had a look at the checkins too. Hey, you got rid of SQLObjectFactory. Cool. Kind Regards, Christian From christian.lueck at ruhr-uni-bochum.de Sat Jan 21 01:44:55 2006 From: christian.lueck at ruhr-uni-bochum.de (=?ISO-8859-1?Q?Christian_L=FCck?=) Date: Sat, 21 Jan 2006 00:44:55 +0000 Subject: [Z3-sqlos] Re: [z3] sqlos: add view for SQLOS objects In-Reply-To: <20060109014535.GA7382@minipas.home> References: <43C0067A.4080304@ruhr-uni-bochum.de> <20060109014535.GA7382@minipas.home> Message-ID: <43D18407.2090403@ruhr-uni-bochum.de> Brian Sutherland wrote: > On Sat, Jan 07, 2006 at 06:20:42PM +0000, Christian L?ck wrote: >> Hi! >> >> I yust found out how to implement add views for a SQLOS-inheriting >> content component. Since it might be interisting for others I post it >> here. If this should be old hat to you, sorry. >> >> The key to get an IAdding view for SQLOS objects running is that you >> have to leave the z3 standard two step add process. To put it short: You >> have to rewrite (leave away) the add() method for the add view >> (inherited from zope.app.form.browser.AddView or >> zope.formlib.form.AddFormBase). >> >> More detailed: >> >> The standard z3 prozess to add an object to a container is two steps: >> 1) Creation of the object by calling a factory. >> 2) Adding this object instance to a container. >> This is normally handled by a method of the add view called >> createAndAdd(). createAndAdd() again calls create() for step 1 and then >> add() for step 2. >> >> >> Creating an SQLOS object differs from this standard inasmuch step 2 is >> not only not recommended (a) but even causes errors (b). >> >> a) not recommended: As a consequence of the current sqlos implementation >> all instances of a content component class inheriting from SQLOS go >> into the same rdb table. => Each container for this content component >> shows all the instances of this component. Imagine two containers with >> preconditions set for the same content component, each one will show a >> set union as its items. - That's why SQLOS objects are not really >> locateable. >> Corollar: Instantiating an content object, which inherits from SQLOS, >> lets this instance show up in each SQLObjectContainer with matching >> preconditions. > > Yes, though it is possible to simulate this if every container has a > unique_id which is stored on the content object itself. There is an > "Isolated" container implementation in the source which does this. > Cool, I did know that one. > There is no corresponding SQLOS implementation as the obvious > implementation is a multiple join and inheritance of 2 SQLObject > related classes was too risky. > >> >> Proposal / Desiderata: >> >> - sqlos.container.SQLObjectContainer should be reimplemented to get >> standard add views ( = views for zope.app.container.interfaces.IAdding ) >> going. Idea (but not more): Reimplement the methods of >> SQLContainerObjects which are called by the magic '+' ( = an >> implementation of IAdding), which is called by the standard z3 add() >> methods in zope.app.form.browser.add.AddView or >> zope.formlib.form.AddFormBase. > > There is a testbrowser functional test in ftests/adding.txt which > actually tests the IAdding for a sampleperson. With the standard > browser:addform directive. A first step might be to extend that test so > that it fails. Whenever I try to add an item with a view, I get the follwing exception: 2006-01-20T22:20:21 ERROR txn.-1236755536 Failed to abort resource manager: Traceback (most recent call last): File "/usr/local/src/Zope-3.2.0b2/build/lib.linux-i686-2.4/transaction/_transaction.py", line 507, in abort rm.abort(self) File "/usr/local/src/Zope-3.2.0b2/build/lib.linux-i686-2.4/transaction/_transaction.py", line 634, in abort self._datamanager.abort(transaction) File "/usr/local/src/Zope-3.2.0b2/build/lib.linux-i686-2.4/zope/app/rdb/__init__.py", line 445, in abort self._dbconn.rollback() File "/usr/local/src/Zope-3.2.0b2/build/lib.linux-i686-2.4/zope/app/rdb/__init__.py", line 391, in rollback self.conn.rollback() NotSupportedError: (1196, "Warning: Some non-transactionalchanged tables couldn't be rolled back") Traceback (most recent call last): File "/usr/local/lib/python2.4/threading.py", line 422, in run self.__target(*self.__args, **self.__kwargs) File "/usr/local/src/Zope-3.2.0b2/build/lib.linux-i686-2.4/twisted/python/threadpool.py", line 149, in _worker context.call(ctx, function, *args, **kwargs) File "/usr/local/src/Zope-3.2.0b2/build/lib.linux-i686-2.4/twisted/python/context.py", line 59, in callWithContext return self.currentContext().callWithContext(ctx, func,*args, **kw) File "/usr/local/src/Zope-3.2.0b2/build/lib.linux-i686-2.4/twisted/python/context.py", line 37, in callWithContext return func(*args,**kw) --- --- File "/usr/local/src/Zope-3.2.0b2/build/lib.linux-i686-2.4/twisted/web2/wsgi.py", line 139, in run result = self.application(self.environment, self.startWSGIResponse) File "/usr/local/src/Zope-3.2.0b2/build/lib.linux-i686-2.4/zope/app/wsgi/__init__.py", line 54, in __call__ request = publish(request, handle_errors=handle_errors) File "/usr/local/src/Zope-3.2.0b2/build/lib.linux-i686-2.4/zope/publisher/publish.py", line 146, in publish publication.handleException( File "/usr/local/src/Zope-3.2.0b2/build/lib.linux-i686-2.4/zope/app/publication/zopepublication.py", line 243, in handleException transaction.abort() File "/usr/local/src/Zope-3.2.0b2/build/lib.linux-i686-2.4/transaction/_manager.py", line 107, in abort return self.get().abort(sub, deprecation_wng=False) File "/usr/local/src/Zope-3.2.0b2/build/lib.linux-i686-2.4/transaction/_transaction.py", line 507, in abort rm.abort(self) File "/usr/local/src/Zope-3.2.0b2/build/lib.linux-i686-2.4/transaction/_transaction.py", line 634, in abort self._datamanager.abort(transaction) File "/usr/local/src/Zope-3.2.0b2/build/lib.linux-i686-2.4/zope/app/rdb/__init__.py", line 445, in abort self._dbconn.rollback() File "/usr/local/src/Zope-3.2.0b2/build/lib.linux-i686-2.4/zope/app/rdb/__init__.py", line 391, in rollback self.conn.rollback() _mysql_exceptions.NotSupportedError: (1196, "Warning: Somenon-transactional changed tables couldn't be rolled back") 127.0.0.1 - - [20/Jan/2006:22:20:21 +0100] "POST /persons/+/AddPerson.html%3D HTTP/1.1" 500 201 "http://localhost:8080/persons/+/AddPerson.html=" "Mozilla/5.0 (X11; U; Linux i686;de-DE; rv:1.7.10) Gecko/20050925 Firefox/1.0.4 (Debian package 1.0.4-2sarge5)" 127.0.0.1 - - [20/Jan/2006:22:20:21 +0100] "GET /favicon.ico HTTP/1.1" 404 4133 "-" "Mozilla/5.0 (X11; U; Linux i686; de-DE; rv:1.7.10) Gecko/20050925 Firefox/1.0.4 (Debian package 1.0.4-2sarge5)" To avoid this, I wrote a view class for my add-view. There I override the add() method which is inherited from zope.app.form.browser.add.AddView. It calls the add() method of the context, which - if I'm not totally wrong - should implemet IAdding. from zope.app.form.browser.add import AddView class PersonAddView(AddView): __used_for__ = IPerson def add(self, content): """In sqlos we yust intantiate an object and then it appears in the container, but we don't really add an object to a container. So we override this method here.""" return content Its Registration: But if sqlos wants to make it easy to plug a rdb instead of ZODB, then having to change all your add views is not acceptable.. I thought about rewriting __setitem()__ and __getitem()__ for the container class - but as far as I see, it's yust coded the way I was thinking of. Well I really don't have an idea.. Regards, Christian From jinty at web.de Sat Jan 21 18:29:09 2006 From: jinty at web.de (Brian Sutherland) Date: Sat, 21 Jan 2006 18:29:09 +0100 Subject: [Z3-sqlos] Re: [z3] sqlos: add view for SQLOS objects In-Reply-To: <43D18407.2090403@ruhr-uni-bochum.de> References: <43C0067A.4080304@ruhr-uni-bochum.de> <20060109014535.GA7382@minipas.home> <43D18407.2090403@ruhr-uni-bochum.de> Message-ID: <20060121172909.GB15762@minipas.home> On Sat, Jan 21, 2006 at 12:44:55AM +0000, Christian L??ck wrote: > Brian Sutherland wrote: > > On Sat, Jan 07, 2006 at 06:20:42PM +0000, Christian L?ck wrote: > Whenever I try to add an item with a view, I get the > follwing exception: > > 2006-01-20T22:20:21 ERROR txn.-1236755536 Failed to abort resource > manager: > Traceback (most recent call last): > File > "/usr/local/src/Zope-3.2.0b2/build/lib.linux-i686-2.4/transaction/_transaction.py", > line 507, in abort > rm.abort(self) > File > "/usr/local/src/Zope-3.2.0b2/build/lib.linux-i686-2.4/transaction/_transaction.py", > line 634, in abort > self._datamanager.abort(transaction) > File > "/usr/local/src/Zope-3.2.0b2/build/lib.linux-i686-2.4/zope/app/rdb/__init__.py", > line 445, in abort > self._dbconn.rollback() > File > "/usr/local/src/Zope-3.2.0b2/build/lib.linux-i686-2.4/zope/app/rdb/__init__.py", > line 391, in rollback > self.conn.rollback() > NotSupportedError: (1196, "Warning: Some non-transactionalchanged > tables couldn't be rolled back") > Traceback (most recent call last): > File "/usr/local/lib/python2.4/threading.py", line 422, in run > self.__target(*self.__args, **self.__kwargs) > File > "/usr/local/src/Zope-3.2.0b2/build/lib.linux-i686-2.4/twisted/python/threadpool.py", > line 149, in _worker > context.call(ctx, function, *args, **kwargs) > File > "/usr/local/src/Zope-3.2.0b2/build/lib.linux-i686-2.4/twisted/python/context.py", > line 59, in callWithContext > return self.currentContext().callWithContext(ctx, func,*args, **kw) > File > "/usr/local/src/Zope-3.2.0b2/build/lib.linux-i686-2.4/twisted/python/context.py", > line 37, in callWithContext > return func(*args,**kw) > --- --- > File > "/usr/local/src/Zope-3.2.0b2/build/lib.linux-i686-2.4/twisted/web2/wsgi.py", > line 139, in run > result = self.application(self.environment, self.startWSGIResponse) > File > "/usr/local/src/Zope-3.2.0b2/build/lib.linux-i686-2.4/zope/app/wsgi/__init__.py", > line 54, in __call__ > request = publish(request, handle_errors=handle_errors) > File > "/usr/local/src/Zope-3.2.0b2/build/lib.linux-i686-2.4/zope/publisher/publish.py", > line 146, in publish > publication.handleException( > File > "/usr/local/src/Zope-3.2.0b2/build/lib.linux-i686-2.4/zope/app/publication/zopepublication.py", > line 243, in handleException > transaction.abort() > File > "/usr/local/src/Zope-3.2.0b2/build/lib.linux-i686-2.4/transaction/_manager.py", > line 107, in abort > return self.get().abort(sub, deprecation_wng=False) > File > "/usr/local/src/Zope-3.2.0b2/build/lib.linux-i686-2.4/transaction/_transaction.py", > line 507, in abort > rm.abort(self) > File > "/usr/local/src/Zope-3.2.0b2/build/lib.linux-i686-2.4/transaction/_transaction.py", > line 634, in abort > self._datamanager.abort(transaction) > File > "/usr/local/src/Zope-3.2.0b2/build/lib.linux-i686-2.4/zope/app/rdb/__init__.py", > line 445, in abort > self._dbconn.rollback() > File > "/usr/local/src/Zope-3.2.0b2/build/lib.linux-i686-2.4/zope/app/rdb/__init__.py", > line 391, in rollback > self.conn.rollback() > _mysql_exceptions.NotSupportedError: (1196, "Warning: > Somenon-transactional changed tables couldn't be rolled back") I have seen this before and wondered if there should be a bare try: except: clause around the rollback in zope.app.rdb. If you can't rollback, you are lost anyway, no point in bringing the whole transaction machinery down with you. > 127.0.0.1 - - [20/Jan/2006:22:20:21 +0100] "POST > /persons/+/AddPerson.html%3D HTTP/1.1" 500 201 > "http://localhost:8080/persons/+/AddPerson.html=" "Mozilla/5.0 (X11; U; > Linux i686;de-DE; rv:1.7.10) Gecko/20050925 Firefox/1.0.4 (Debian > package 1.0.4-2sarge5)" > 127.0.0.1 - - [20/Jan/2006:22:20:21 +0100] "GET /favicon.ico HTTP/1.1" > 404 4133 "-" "Mozilla/5.0 (X11; U; Linux i686; de-DE; rv:1.7.10) > Gecko/20050925 Firefox/1.0.4 (Debian package 1.0.4-2sarge5)" > > > To avoid this, I wrote a view class for my add-view. There I override > the add() method which is inherited from > zope.app.form.browser.add.AddView. It calls the add() method of > the context, which - if I'm not totally wrong - should implemet IAdding. Yes, indeed it should implement IAdding, and you can adapt your SQLObjectContainer to that interface with this directive: > from zope.app.form.browser.add import AddView > > class PersonAddView(AddView): > > __used_for__ = IPerson > > def add(self, content): > """In sqlos we yust intantiate an object and then it appears > in the container, but we don't really add an object to a container. > So we override this method here.""" > return content This type of thing really shouldn't be necessary as adding objects to a sqlos container should really be a no-op. However I have a funny feeling that the interface declarations in SQLOS need some tweaking. For instance it appears possible in the zmi to add SQLOS objects even to normal Zope3 Folders. That is bound to fail unless you use an AddView like the one above. I'm sure a read about how to do this in Stephan Richter's book somewhere... > Its Registration: > > schema="sqlosperson.interfaces.IPerson" > content_factory="sqlosperson.person.Person" > class=".person.PersonAddView" > name="AddPerson.html" > label="Add Person" > permission="zope.ManageContent" > /> > > But if sqlos wants to make it easy to plug a rdb instead of ZODB, then > having to change all your add views is not acceptable.. > I thought about rewriting __setitem()__ and __getitem()__ > for the container class - but as far as I see, it's yust coded the way I > was thinking of. Well I really don't have an idea.. I think the problem here is that you are trying to add sqlos objects to normal Zope3 folders. That is really a bad idea, and probably allowing that is a bug from the sqlos side. Patches/testcases welcome! > > Regards, > Christian > -- Brian Sutherland Metropolis - "it's the first movie with a robot. And she's a woman. And she's EVIL!!" From christian.lueck at ruhr-uni-bochum.de Sat Jan 21 21:12:07 2006 From: christian.lueck at ruhr-uni-bochum.de (=?UTF-8?B?Q2hyaXN0aWFuIEzDvGNr?=) Date: Sat, 21 Jan 2006 20:12:07 +0000 Subject: [Z3-sqlos] Re: [z3] sqlos: add view for SQLOS objects In-Reply-To: <20060121172909.GB15762@minipas.home> References: <43C0067A.4080304@ruhr-uni-bochum.de> <20060109014535.GA7382@minipas.home> <43D18407.2090403@ruhr-uni-bochum.de> <20060121172909.GB15762@minipas.home> Message-ID: <43D29597.8070107@ruhr-uni-bochum.de> Brian Sutherland wrote: > On Sat, Jan 21, 2006 at 12:44:55AM +0000, Christian L?ck wrote: >> Brian Sutherland wrote: >> > On Sat, Jan 07, 2006 at 06:20:42PM +0000, Christian L?ck wrote: >> Whenever I try to add an item with a view, I get the >> follwing exception: >> >> 2006-01-20T22:20:21 ERROR txn.-1236755536 Failed to abort resource >> manager: >> Traceback (most recent call last): >> File >> "/usr/local/src/Zope-3.2.0b2/build/lib.linux-i686-2.4/transaction/_transaction.py", >> line 507, in abort >> rm.abort(self) >> File >> "/usr/local/src/Zope-3.2.0b2/build/lib.linux-i686-2.4/transaction/_transaction.py", >> line 634, in abort >> self._datamanager.abort(transaction) >> File >> "/usr/local/src/Zope-3.2.0b2/build/lib.linux-i686-2.4/zope/app/rdb/__init__.py", >> line 445, in abort >> self._dbconn.rollback() >> File >> "/usr/local/src/Zope-3.2.0b2/build/lib.linux-i686-2.4/zope/app/rdb/__init__.py", >> line 391, in rollback >> self.conn.rollback() >> NotSupportedError: (1196, "Warning: Some non-transactionalchanged >> tables couldn't be rolled back") >> Traceback (most recent call last): >> File "/usr/local/lib/python2.4/threading.py", line 422, in run >> self.__target(*self.__args, **self.__kwargs) >> File >> "/usr/local/src/Zope-3.2.0b2/build/lib.linux-i686-2.4/twisted/python/threadpool.py", >> line 149, in _worker >> context.call(ctx, function, *args, **kwargs) >> File >> "/usr/local/src/Zope-3.2.0b2/build/lib.linux-i686-2.4/twisted/python/context.py", >> line 59, in callWithContext >> return self.currentContext().callWithContext(ctx, func,*args, **kw) >> File >> "/usr/local/src/Zope-3.2.0b2/build/lib.linux-i686-2.4/twisted/python/context.py", >> line 37, in callWithContext >> return func(*args,**kw) >> --- --- >> File >> "/usr/local/src/Zope-3.2.0b2/build/lib.linux-i686-2.4/twisted/web2/wsgi.py", >> line 139, in run >> result = self.application(self.environment, self.startWSGIResponse) >> File >> "/usr/local/src/Zope-3.2.0b2/build/lib.linux-i686-2.4/zope/app/wsgi/__init__.py", >> line 54, in __call__ >> request = publish(request, handle_errors=handle_errors) >> File >> "/usr/local/src/Zope-3.2.0b2/build/lib.linux-i686-2.4/zope/publisher/publish.py", >> line 146, in publish >> publication.handleException( >> File >> "/usr/local/src/Zope-3.2.0b2/build/lib.linux-i686-2.4/zope/app/publication/zopepublication.py", >> line 243, in handleException >> transaction.abort() >> File >> "/usr/local/src/Zope-3.2.0b2/build/lib.linux-i686-2.4/transaction/_manager.py", >> line 107, in abort >> return self.get().abort(sub, deprecation_wng=False) >> File >> "/usr/local/src/Zope-3.2.0b2/build/lib.linux-i686-2.4/transaction/_transaction.py", >> line 507, in abort >> rm.abort(self) >> File >> "/usr/local/src/Zope-3.2.0b2/build/lib.linux-i686-2.4/transaction/_transaction.py", >> line 634, in abort >> self._datamanager.abort(transaction) >> File >> "/usr/local/src/Zope-3.2.0b2/build/lib.linux-i686-2.4/zope/app/rdb/__init__.py", >> line 445, in abort >> self._dbconn.rollback() >> File >> "/usr/local/src/Zope-3.2.0b2/build/lib.linux-i686-2.4/zope/app/rdb/__init__.py", >> line 391, in rollback >> self.conn.rollback() >> _mysql_exceptions.NotSupportedError: (1196, "Warning: >> Somenon-transactional changed tables couldn't be rolled back") > > I have seen this before and wondered if there should be a bare try: > except: clause around the rollback in zope.app.rdb. > > If you can't rollback, you are lost anyway, no point in bringing the > whole transaction machinery down with you. > >> 127.0.0.1 - - [20/Jan/2006:22:20:21 +0100] "POST >> /persons/+/AddPerson.html%3D HTTP/1.1" 500 201 >> "http://localhost:8080/persons/+/AddPerson.html=" "Mozilla/5.0 (X11; U; >> Linux i686;de-DE; rv:1.7.10) Gecko/20050925 Firefox/1.0.4 (Debian >> package 1.0.4-2sarge5)" >> 127.0.0.1 - - [20/Jan/2006:22:20:21 +0100] "GET /favicon.ico HTTP/1.1" >> 404 4133 "-" "Mozilla/5.0 (X11; U; Linux i686; de-DE; rv:1.7.10) >> Gecko/20050925 Firefox/1.0.4 (Debian package 1.0.4-2sarge5)" >> >> >> To avoid this, I wrote a view class for my add-view. There I override >> the add() method which is inherited from >> zope.app.form.browser.add.AddView. It calls the add() method of >> the context, which - if I'm not totally wrong - should implemet IAdding. > > Yes, indeed it should implement IAdding, and you can adapt your > SQLObjectContainer to that interface with this directive: > > name="+" > menu="zmi_actions" title="Add SQLObjects" > for="sqlos.testing.sampleperson.IMultiContainer" > permission="zope.ManageContent" > class="zope.app.container.browser.adding.Adding" > > > > > > >> from zope.app.form.browser.add import AddView >> >> class PersonAddView(AddView): >> >> __used_for__ = IPerson >> >> def add(self, content): >> """In sqlos we yust intantiate an object and then it appears >> in the container, but we don't really add an object to a container. >> So we override this method here.""" >> return content > > This type of thing really shouldn't be necessary as adding objects to a > sqlos container should really be a no-op. Yes, I have seen the code in container.py: def __setitem__(self, name, content): return name > > However I have a funny feeling that the interface declarations in SQLOS > need some tweaking. For instance it appears possible in the zmi to add > SQLOS objects even to normal Zope3 Folders. That is bound to fail unless > you use an AddView like the one above. > > I'm sure a read about how to do this in Stephan Richter's book > somewhere... > >> Its Registration: >> >> > schema="sqlosperson.interfaces.IPerson" >> content_factory="sqlosperson.person.Person" >> class=".person.PersonAddView" >> name="AddPerson.html" >> label="Add Person" >> permission="zope.ManageContent" >> /> >> >> But if sqlos wants to make it easy to plug a rdb instead of ZODB, then >> having to change all your add views is not acceptable.. >> I thought about rewriting __setitem()__ and __getitem()__ >> for the container class - but as far as I see, it's yust coded the way I >> was thinking of. Well I really don't have an idea.. > > I think the problem here is that you are trying to add sqlos objects to > normal Zope3 folders. That is really a bad idea, and probably allowing > that is a bug from the sqlos side. > > Patches/testcases welcome! > No, I am *not* trying to add sqlos objects to normal z3 folders. It's a sqlos container and it's the simple Person example from the README. If you want to reproduce the error, have a look at my attachement. >> >> Regards, >> Christian >> > -------------- next part -------------- A non-text attachment was scrubbed... Name: sqlosperson.tgz Type: application/x-compressed-tar Size: 2837 bytes Desc: not available Url : http://codespeak.net/pipermail/z3-sqlos/attachments/20060121/a0e18564/attachment.bin From jinty at web.de Sun Jan 22 03:04:40 2006 From: jinty at web.de (Brian Sutherland) Date: Sun, 22 Jan 2006 03:04:40 +0100 Subject: [Z3-sqlos] Re: [z3] sqlos: add view for SQLOS objects In-Reply-To: <43D29597.8070107@ruhr-uni-bochum.de> References: <43C0067A.4080304@ruhr-uni-bochum.de> <20060109014535.GA7382@minipas.home> <43D18407.2090403@ruhr-uni-bochum.de> <20060121172909.GB15762@minipas.home> <43D29597.8070107@ruhr-uni-bochum.de> Message-ID: <20060122020439.GC8316@minipas.home> On Sat, Jan 21, 2006 at 08:12:07PM +0000, Christian L?ck wrote: > Brian Sutherland wrote: > > On Sat, Jan 21, 2006 at 12:44:55AM +0000, Christian L?ck wrote: > > Patches/testcases welcome! > > > > No, I am *not* trying to add sqlos objects to normal z3 folders. It's a > sqlos container and it's the simple Person example from the README. > If you want to reproduce the error, have a look at my attachement. Thanks, that made it crystal clear. Look for a fix in the trunk r22484. -- Brian Sutherland Metropolis - "it's the first movie with a robot. And she's a woman. And she's EVIL!!" From christian.lueck at ruhr-uni-bochum.de Sun Jan 22 21:01:17 2006 From: christian.lueck at ruhr-uni-bochum.de (=?ISO-8859-1?Q?Christian_L=FCck?=) Date: Sun, 22 Jan 2006 20:01:17 +0000 Subject: [Z3-sqlos] problem with notNull=True on an attribute/column Message-ID: <43D3E48D.6060700@ruhr-uni-bochum.de> Hi Brian, it's me again. This time the problem seems more related to SQLObject than to sqlos. It's a problem with the 'notNull' declaration for attributes of SQLOS/SQLObject objects. The problem appears, when you set notNull=True on an attribute and try to create an object with the normal add-view ( ). To reproduce the error please refer to the simple Person app again. I yust made little changes to the column definitions in sqlosperson.person.Person - see attachement. -- You have to drop and re-create the table first... Traceback (innermost last): Module zope.publisher.publish, line 138, in publish result = publication.callObject(request, object) Module zope.app.publication.zopepublication, line 161, in callObject return mapply(ob, request.getPositionalArguments(), request) Module zope.publisher.publish, line 113, in mapply return debug_call(object, args) - __traceback_info__: Module zope.publisher.publish, line 119, in debug_call return object(*args) Module zope.app.pagetemplate.simpleviewclass, line 44, in __call__ return self.index(*args, **kw) Module zope.app.pagetemplate.viewpagetemplatefile, line 83, in __call__ return self.im_func(im_self, *args, **kw) Module zope.app.pagetemplate.viewpagetemplatefile, line 51, in __call__ sourceAnnotations=getattr(debug_flags, 'sourceAnnotations', 0), Module zope.pagetemplate.pagetemplate, line 117, in pt_render strictinsert=0, sourceAnnotations=sourceAnnotations)() Module zope.tal.talinterpreter, line 277, in __call__ self.interpret(self.program) Module zope.tal.talinterpreter, line 352, in interpret handlers[opcode](self, args) Module zope.tal.talinterpreter, line 908, in do_useMacro self.interpret(macro) Module zope.tal.talinterpreter, line 352, in interpret handlers[opcode](self, args) Module zope.tal.talinterpreter, line 538, in do_optTag_tal self.do_optTag(stuff) Module zope.tal.talinterpreter, line 523, in do_optTag return self.no_tag(start, program) Module zope.tal.talinterpreter, line 518, in no_tag self.interpret(program) Module zope.tal.talinterpreter, line 352, in interpret handlers[opcode](self, args) Module zope.tal.talinterpreter, line 878, in do_defineMacro self.interpret(macro) Module zope.tal.talinterpreter, line 352, in interpret handlers[opcode](self, args) Module zope.tal.talinterpreter, line 976, in do_defineSlot self.interpret(block) Module zope.tal.talinterpreter, line 352, in interpret handlers[opcode](self, args) Module zope.tal.talinterpreter, line 966, in do_defineSlot self.interpret(slot) Module zope.tal.talinterpreter, line 352, in interpret handlers[opcode](self, args) Module zope.tal.talinterpreter, line 878, in do_defineMacro self.interpret(macro) Module zope.tal.talinterpreter, line 352, in interpret handlers[opcode](self, args) Module zope.tal.talinterpreter, line 878, in do_defineMacro self.interpret(macro) Module zope.tal.talinterpreter, line 352, in interpret handlers[opcode](self, args) Module zope.tal.talinterpreter, line 588, in do_setLocal_tal self.engine.setLocal(name, self.engine.evaluateValue(expr)) Module zope.tales.tales, line 696, in evaluate return expression(self) - /usr/local/Zope-3.2.0b2/lib/python/zope/app/form/browser/add.pt - Line 19, Column 8 - Expression: - Names: {'args': (), 'context': , 'default': , 'loop': {}, 'nothing': None, 'options': {}, 'repeat': {}, 'request': , 'template': , 'usage': , 'view': , 'views': } Module zope.tales.expressions, line 205, in __call__ return self._eval(econtext) Module zope.tales.expressions, line 199, in _eval return ob() Module zope.app.form.browser.add, line 62, in update self.createAndAdd(data) Module zope.app.form.browser.add, line 93, in createAndAdd content = self.create(*args, **kw) Module zope.app.form.browser.add, line 74, in create return self._factory(*args, **kw) Module sqlobject.main, line 1179, in __init__ self._create(id, **kw) Module sqlobject.main, line 1198, in _create raise TypeError, "%s() did not get expected keyword argument %s" % (self.__class__.__name__, column.name) TypeError: Person() did not get expected keyword argument username I think the exception is due to the way objects are created in z3. They first get instantiated and then the attributes are set in a second step. SQLObject doesn't like that. It's in the doc there. I don't know if there's a solution for that problem. The thing I did: use zope.formlib for addviews and call a factory, which instantiates objects with initial values. -- That was even the reason why I registered a . That's the whole story... ;-) Kind regards, Christian -------------- next part -------------- A non-text attachment was scrubbed... Name: sqlosperson.tgz Type: application/x-compressed-tar Size: 2727 bytes Desc: not available Url : http://codespeak.net/pipermail/z3-sqlos/attachments/20060122/653423e7/attachment.bin From christian.lueck at ruhr-uni-bochum.de Sun Jan 22 21:13:54 2006 From: christian.lueck at ruhr-uni-bochum.de (=?ISO-8859-1?Q?Christian_L=FCck?=) Date: Sun, 22 Jan 2006 20:13:54 +0000 Subject: [Z3-sqlos] Re: [z3] sqlos: add view for SQLOS objects In-Reply-To: <20060122020439.GC8316@minipas.home> References: <43C0067A.4080304@ruhr-uni-bochum.de> <20060109014535.GA7382@minipas.home> <43D18407.2090403@ruhr-uni-bochum.de> <20060121172909.GB15762@minipas.home> <43D29597.8070107@ruhr-uni-bochum.de> <20060122020439.GC8316@minipas.home> Message-ID: <43D3E782.5020203@ruhr-uni-bochum.de> Brian Sutherland wrote: > On Sat, Jan 21, 2006 at 08:12:07PM +0000, Christian L?ck wrote: >> Brian Sutherland wrote: >> > On Sat, Jan 21, 2006 at 12:44:55AM +0000, Christian L?ck wrote: >> > Patches/testcases welcome! >> > >> >> No, I am *not* trying to add sqlos objects to normal z3 folders. It's a >> sqlos container and it's the simple Person example from the README. >> If you want to reproduce the error, have a look at my attachement. > > Thanks, that made it crystal clear. Look for a fix in the trunk r22484. > Great! From jinty at web.de Mon Jan 23 01:05:25 2006 From: jinty at web.de (Brian Sutherland) Date: Mon, 23 Jan 2006 01:05:25 +0100 Subject: [Z3-sqlos] Re: problem with notNull=True on an attribute/column In-Reply-To: <43D3E48D.6060700@ruhr-uni-bochum.de> References: <43D3E48D.6060700@ruhr-uni-bochum.de> Message-ID: <20060123000525.GA7414@minipas.home> On Sun, Jan 22, 2006 at 08:01:17PM +0000, Christian L?ck wrote: > I think the exception is due to the way objects are created in z3. They > first get instantiated and then the attributes are set in a second step. > SQLObject doesn't like that. It's in the doc there. With zope.app.form (i.e. ) there is the keyword_arguments keyword. That way you can pass any keywords you want to the factory. I would suggest that. I am sure there would be an equivalent solution with zope.app.formlib. Otherwise you can use the sqlobjct default keyword to give the columns default values until they are set with the real ones. But that may result in bad data in your database as well as more SQL statements than are necessary. -- Brian Sutherland Metropolis - "it's the first movie with a robot. And she's a woman. And she's EVIL!!" From jinty at web.de Tue Jan 24 10:35:04 2006 From: jinty at web.de (Brian Sutherland) Date: Tue, 24 Jan 2006 10:35:04 +0100 Subject: [Z3-sqlos] sqlos and per site databases In-Reply-To: <92C5D53A-4DD8-40B0-BD64-CAC066489E86@work.de> References: <20051209144105.GA11821@minipas.home> <92C5D53A-4DD8-40B0-BD64-CAC066489E86@work.de> Message-ID: <20060124093503.GB7323@minipas.home> On Mon, Dec 12, 2005 at 12:00:22PM +0100, Andreas Elvers wrote: > Hi Brian, > > thanks for your reply. I will check out your proposed changes, but since > we dropped sqlos, i have to create a new demo which should be not > too much work. There should be some time later this week. I thought you might like to know that I have fixed and enabled your functional test. It passes now. Enjoy:) > > - Andreas > > On 09.12.2005, at 15:41, Brian Sutherland wrote: > > > On Tue, Nov 01, 2005 at 01:51:29PM +0100, Andreas Elvers wrote: > >> Hi, > >> > >> I am having problems with sqlos and local utilities. I have a folder > >> which is a site. This site has a local utility which is a psycopg > >> adapter named as 'psycopg'. I have registered this name with > >> sqlos. When > >> adding a SQLObjectContainer to this site folder my guess is, that > >> this > >> container should use the db adapter 'psycopg'. > >> > >> While adding I get a "'NoneType' object is not callable" in > >> connection.py on line 96. This is because queryUtility really does > >> not > >> find my local Utility although context point to the newly created > >> SQLObjectContainer and the utility name is currect either. > > > > Hi Andreas, > > > > I found you test for the issue in the issue tracker and committed > > it to > > the trunk. Though it is disabled until the issue is fixed. > > > > I can see at least two problems: > > > > * Sometimes the connection descriptor does not have the right context > > when querying the utilities. We could probably fix that on a case by > > case basis by getting the connection before the sqlobject call with > > the right context. > > > > Here is a sci-fi replacement of the container items() method: > > > > def items(self): > > """Return a sequence-like object containing tuples of the form > > (name, object) for the objects that appear in the folder. > > """ > > # we need to get the connection ourselves to avoid breaking > > # local > > # utilities that set the connection > > ut = zapi.getUtility(IConnectionName, context=self) > > connection = getConnection(self, ut.name) > > # iterate through the factories returning all the results > > for factoryName in self.allowedFactories(): > > factory = zapi.getUtility(IISQLObject, factoryName, > > context=self) > > for obj in factory.select(connection=connection): > > name = '%s.%s' % (factoryName, obj.id) > > yield (name, contained(obj, parent=self, name=name)) > > > > * The connection cache into sqlos.connection only can cope with one > > connection name per thread. This will seriously break if you do > > something like having two local connections with the same name. > > > > Unfortunately, I don't have the time to fix these now... > > > > -- > > Brian Sutherland > > > > Metropolis - "it's the first movie with a robot. And she's a woman. > > And she's EVIL!!" > > > > o------------------------------------------------- - - > | Andreas Elvers // andreas at work.de > | n at work Internet Informationssyteme GmbH > | T: +49 40 23 88 09 0 // F: +49 40 23 88 09 29 > o--------------------------------------------------------------- - - > -- Brian Sutherland Metropolis - "it's the first movie with a robot. And she's a woman. And she's EVIL!!" From jinty at web.de Thu Jan 26 18:35:43 2006 From: jinty at web.de (Brian Sutherland) Date: Thu, 26 Jan 2006 18:35:43 +0100 Subject: [Z3-sqlos] Cleaning the sqlos house Message-ID: <20060126173543.GA5985@minipas.home> Before the next release of sqlos, I would like to purge any un-tested code still in the repository unless someone who cares/uses this stuff writes some tests for it. Specifically these modules are currently totally un-tested: * sqlos.auth * sqlos.annotations * sqlos.attributeannotations These have not seen anything but maintenance checkins since 2004/7. Any comments? -- Brian Sutherland Metropolis - "it's the first movie with a robot. And she's a woman. And she's EVIL!!" From rcampbell at pcwi.net Tue Jan 31 18:59:42 2006 From: rcampbell at pcwi.net (Rob Campbell) Date: Tue, 31 Jan 2006 09:59:42 -0800 Subject: [Z3-sqlos] SQL error in sqlos_sample Message-ID: <43DFA58E.1080501@pcwi.net> Hello, I was just trying out sqlos with Zope 3.2.0 and PostgreSQL 8.0.3. I was able to add it to Zope, but when I try to add a new person I get the following error: DatabaseException: ERROR: relation "person_id_seq" does not exist SELECT NEXTVAL('person_id_seq') Does anyone know what is causing this error? I tried looking for where it is referenced in the code, but I could not find anything about an id_seq. Rob Campbell Pacific Coast Wireless Internet