Programmatic creation/update of ZSQL methods
I've got about 60 or so ZSQL methods that I maintain in my Zope. Actually, I don't maintain them: our Oracle expert changes them then I have to translate them into DTML, split them into little chunks, and upload them into zope. Since I'm terribly lazy I've automated the DTMLification and the splitting. But the third step of uploading the ZSQL bodies is tricker. Currently I'm uploading them via FTP but this requires that the methods already exist (due to a lack of object type magic). I've also tried using xmlrpc but manage_addZSQLMethod does not seem to live on Folder so I'm not sure how I can call it. So my question is: How can I create ZSQL methods from an external program (a python script in this case)? I've got the body, the id, the destination, the connection id, the parameters... everything but a clue. I know about PUT_factory but I didn't have much luck with that either.
Charlie Reiman writes:
I've got about 60 or so ZSQL methods that I maintain in my Zope. Actually, I don't maintain them: our Oracle expert changes them then I have to translate them into DTML, split them into little chunks, and upload them into zope.
Since I'm terribly lazy I've automated the DTMLification and the splitting. But the third step of uploading the ZSQL bodies is tricker. Currently I'm uploading them via FTP but this requires that the methods already exist (due to a lack of object type magic). I've also tried using xmlrpc but manage_addZSQLMethod does not seem to live on Folder so I'm not sure how I can call it.
So my question is: How can I create ZSQL methods from an external program (a python script in this case)? I've got the body, the id, the destination, the connection id, the parameters... everything but a clue.
Its maybe ugly, but how about faking the ZMI form by doing something like: lynx -dump -auth admin:clear_text_passwd \ 'http://localhost:8080/my_sql_folder/manage_addZSQLMethod?id=new_sql_method&t...' Afterwards the SQL method should be there and may be edited via FTP. Or is this too ugly? Maybe someone else one the list knows a better way to add arbitrary typed objects programatically. Cheers, Clemens
After thinking about it more, it looks like this (HTTP POST) will be the way to go. Directly accessing the ZODB is nifty but would involve stopping Zope while I update which just adds a step to my process. Still, I'm disappointed that xmlrpc can't do this. I thought it would support everything I can do via HTTP plus more. And I was so looking forward to being buzzword compliant. Ah well, live and learn.
-----Original Message----- From: zope-admin@zope.org [mailto:zope-admin@zope.org]On Behalf Of Clemens Robbenhaar Sent: Thursday, October 31, 2002 12:27 PM To: zope@zope.org Subject: [Zope] Programmatic creation/update of ZSQL methods
Charlie Reiman writes:
I've got about 60 or so ZSQL methods that I maintain in my Zope. Actually, I don't maintain them: our Oracle expert changes them then I have to translate them into DTML, split them into little chunks, and upload them into zope.
Since I'm terribly lazy I've automated the DTMLification and the splitting. But the third step of uploading the ZSQL bodies is tricker. Currently I'm uploading them via FTP but this requires that the methods already exist (due to a lack of object type magic). I've also tried using xmlrpc but manage_addZSQLMethod does not seem to live on Folder so I'm not sure how I can call it.
So my question is: How can I create ZSQL methods from an external program (a python script in this case)? I've got the body, the id, the destination, the connection id, the parameters... everything but a clue.
Its maybe ugly, but how about faking the ZMI form by doing something like:
lynx -dump -auth admin:clear_text_passwd \
'http://localhost:8080/my_sql_folder/manage_addZSQLMethod?id=new_s ql_method&title=foo&connection_id=my_db&arguments=&template:text=select+*'
Afterwards the SQL method should be there and may be edited via FTP. Or is this too ugly? Maybe someone else one the list knows a better way to add arbitrary typed objects programatically. Cheers, Clemens
Charlie, I think you will have to use Zope's Python interface to do what you want. Get the Zope Developer's Handbook and read up on the Debugger. It exposes Zope's app object - with that you can programmatically add objects to the ZODB, just remember to commit the transaction. Joseph On Thu, 31 Oct 2002 11:49:08 -0800, Charlie Reiman wrote
I've got about 60 or so ZSQL methods that I maintain in my Zope. Actually, I don't maintain them: our Oracle expert changes them then I have to translate them into DTML, split them into little chunks, and upload them into zope.
Since I'm terribly lazy I've automated the DTMLification and the splitting. But the third step of uploading the ZSQL bodies is tricker. Currently I'm uploading them via FTP but this requires that the methods already exist (due to a lack of object type magic). I've also tried using xmlrpc but manage_addZSQLMethod does not seem to live on Folder so I'm not sure how I can call it.
So my question is: How can I create ZSQL methods from an external program (a python script in this case)? I've got the body, the id, the destination, the connection id, the parameters... everything but a clue.
I know about PUT_factory but I didn't have much luck with that either.
_______________________________________________ Zope maillist - Zope@zope.org http://lists.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://lists.zope.org/mailman/listinfo/zope-announce http://lists.zope.org/mailman/listinfo/zope-dev )
PCL Internet WebMail (http://www.pclnet.net)
Charlie Reiman writes:
... Since I'm terribly lazy I've automated the DTMLification and the splitting. But the third step of uploading the ZSQL bodies is tricker. Currently I'm uploading them via FTP but this requires that the methods already exist (due to a lack of object type magic). You may look at "PUTFactory" -- HowTo on Zope.org...
I've also tried using xmlrpc but manage_addZSQLMethod does not seem to live on Folder so I'm not sure how I can call it. The usual way (there are a few exceptions, mainly very old products) to call constructors is
<ObjectManager>.manage_addProduct[<yourProduct>].<contructor>(<arguments>) In URL form (this is what you need for XMLRFC), this is <URLToObjectManager>/manage_addProduct/<yourProduct> There, you call "<contructor>(<arguments>)".
... I know about PUT_factory but I didn't have much luck with that either. But, you do not tell us about the kind of problems....
Dieter
Dieter sez:
The usual way (there are a few exceptions, mainly very old products) to call constructors is
<ObjectManager>.manage_addProduct[<yourProduct>].<contructor>(<arguments>)
In URL form (this is what you need for XMLRFC), this is
<URLToObjectManager>/manage_addProduct/<yourProduct>
There, you call "<contructor>(<arguments>)".
... I know about PUT_factory but I didn't have much luck with that either. But, you do not tell us about the kind of problems....
Well, let's just ignore PUT_factory for the moment. I've almost got xmlrpc working (pardon my word wrap): srv = xmlrpclib.Server("http://srvr/test/manage_addProduct/ZSQLMethods", transport = BasicAuthTransport(username="xxx", password="yyyy")) err= srv.manage_addZSQLMethod('amethod', 'atitle' 'zfly', 'one two', 'select sysdate from dual', 'xxx') I'm still not sure what to invoke on srv. The above is as close as I have come. It does create an object but it issues a 302 error response and the object has incorrect paramters. I'm pretty certain that this is not the right method to invoke (as it will expect an ObjectManager as the first parameter, which I can't really pass across xmlrpc and it's designed for TTW creation). However, I was unable to invoke the SQL constructor which is what I think I need as that's what manage_addZSQLMethod calls. If I call srv.SQL, I just get a "Cannot location object at:" exception. If I call srv.SQL.__init__, I get some very strange things. First, it demands 3 arguments (SQL.__init__ should take 5). The call seems to be successful as the call returns None. But no object is created. I'll go have another look at my PUT_factory effort and see if I can make that work.
Got PUT_factory working. For those interested, here's my current PUT_factory. I also found a typo in my xml test but fixing it didn't help. I still can't create ZSQLMethods via xmlrpc. But now it doesn't bother me so much. # Implement the "hookable PUT" hook. import re, OFS.DTMLMethod import Products.ZSQLMethods.SQL import sys TEXT_PATTERN = re.compile( r'^text/.*$' ) ZSQL_PATTERN = re.compile( r'<params>([^<]+)</params>(.*)', re.DOTALL ) # New behaviors: # Support for ftp put of ZSQL methods (sorta). Connection ID is hardcoded. # Default doctype is DTMLMethod, not DTMLDocument. def PUT_factory( self, name, typ, body ): """ """ if TEXT_PATTERN.match( typ ): grps = ZSQL_PATTERN.match(body) if grps: return Products.ZSQLMethods.SQL.SQL(name, '', 'Oracle_database_connection', grps.group(1), grps.group(2)) else: return OFS.DTMLMethod.DTMLMethod( '', __name__=name ) return None
On Friday 01 November 2002 04:44 pm, Charlie Reiman wrote:
Got PUT_factory working. For those interested, here's my current PUT_factory. I also found a typo in my xml test but fixing it didn't help. I still can't create ZSQLMethods via xmlrpc. But now it doesn't bother me so much.
You might be able to if you send a request to: folder.manage_addProduct['ZSQLMethods'].manage_addZSQLMethod( name, '', dba, params, body) Did you try that? -Casey
-----Original Message----- From: Casey Duncan [mailto:casey@zope.com] Sent: Friday, November 01, 2002 2:06 PM To: Charlie Reiman; Dieter Maurer Cc: zope@zope.org Subject: Re: [Zope] Programmatic creation/update of ZSQL methods
On Friday 01 November 2002 04:44 pm, Charlie Reiman wrote:
Got PUT_factory working. For those interested, here's my current PUT_factory. I also found a typo in my xml test but fixing it didn't help. I still can't create ZSQLMethods via xmlrpc. But now it doesn't bother me so much.
You might be able to if you send a request to:
folder.manage_addProduct['ZSQLMethods'].manage_addZSQLMethod( name, '', dba, params, body)
Did you try that?
-Casey
No, that doesn't work. I'm not sure how it would from an xmlrpc client, although I think it probably would from within Zope. If you mean I should add this to zope then call that via xmlrpc: that probably work but I can already create the object via HTTP by faking the form submission. If I need to add a crutch to zope to make XMLRPC do what I can already do via HTTP without a crutch, then I'd rather use HTTP. Thanks for everyone's help but I think the FTP solution is superior in this case since I don't have to delete any existing objects before uploading. This makes my upload script a little easier and probably faster.
Charlie Reiman writes:
srv = xmlrpclib.Server("http://srvr/test/manage_addProduct/ZSQLMethods", transport = BasicAuthTransport(username="xxx", password="yyyy")) err= srv.manage_addZSQLMethod('amethod', 'atitle' 'zfly', 'one two', 'select sysdate from dual', 'xxx')
I'm still not sure what to invoke on srv. The above is as close as I have come. It does create an object but it issues a 302 error response and the object has incorrect paramters. The first problem (302 redirect) is easily explained:
"manage_addZSQLMethod" is a management function that tries to give you a result page using "redirect". It was not conceived to be used by XML-Rpc. The easiest way is to provide a wrapper around this function, that calls "manage_addZSQLMethod" without "REQUEST" and returns success information more appropriate for XML-RPC. The second problem (wrong parameters) is more difficult (as you do not provide enough info on how the parameters are wrong): Are you sure, you provide the parameters in the correct order? In what way are the parameters of the created object wrong?
I'm pretty certain that this is not the right method to invoke (as it will expect an ObjectManager as the first parameter, which I can't really pass across xmlrpc and it's designed for TTW creation). The "self" should be implicitely passed. In fact, it is (in your case) not an "ObjectManager" but a so called "Product Dispatcher" created by "manage_addProduct". It creates the object in its parent, an "ObjectManager".
However, I was unable to invoke the SQL constructor which is what I think I need as that's what manage_addZSQLMethod calls. Go for a PythonScript wrapper:
createZSQLMethod: Parameters: as needed Body: context.manage_addProduct[...].manage_addZSQLMethod(parameters) return 1 Dieter
participants (5)
-
Casey Duncan -
Charlie Reiman -
Clemens Robbenhaar -
Dieter Maurer -
Joseph Griffin