Just like there's DTMLFile and PageTemplateFile, what about ZSQL Methods? So that you can run ZSQL methods from the filesystem (for a python product) If not, I'll have to open my filesystem files and programmatically create these objects.
Peter Bengtsson wrote:
Just like there's DTMLFile and PageTemplateFile, what about ZSQL Methods? So that you can run ZSQL methods from the filesystem (for a python product)
If not, I'll have to open my filesystem files and programmatically create these objects.
I usually just create ZSQL Methods as attributes of my (product) class: import Acquisition from Products.ZSQLMethods.SQL import SQL class mySQLClass(Acquisition.Implicit): # We need Acquisition in order to find our db connection # a database connection with this id must exist! dbconnection = "the_db_connection" _sql_null = "select 1 as one" zsql_null = SQL('null', 'A dumb zsql method for testing purposes', dbconnection, '', _sql_null, ) An instance of "mySQLClass" then could call self.zsql_null just like a standard ZSQL Method For details, take a look at Products.ZSQLMethods.SQL or its superclass, Shared.DC.ZRDB.DA.DA - peter.
Just like there's DTMLFile and PageTemplateFile, what about ZSQL Methods? So that you can run ZSQL methods from the filesystem (for a python product)
If not, I'll have to open my filesystem files and programmatically create these objects.
I wrote a product for just this purpose: using ZSQLMethods in fs-based products. Has some other neat features besides. http://www.zope.org/Members/jccooper/extzsql Don't be fooled by the 0.1 designation: it just hasn't needed any changes since public release. --jcc
I wrote a product for just this purpose: using ZSQLMethods in fs-based products. Has some other neat features besides.
I'm not convinced. The solution I currently have (if it works when I start using it) is great. It looks something like this:: class MyProduct(ObjectManager, SQLClass): def helloworld(self, bar): return SelectWorldSQLStatement(foo=bar) class SQLClass(Acquisition.Implicit): pass for filename, params, statement in getFilesEndingWithDotsql(): setattr(SQLClass, SQL(filename, 'No title', DBCONNECTION, params, statement)) The "only" problem is refreshing. Not yet attempted this but it should be a good candidate:: I subclass SQL ("from Products.ZSQLMethods.SQL import SQL") and intercept the __call__ method to do something like this:: if SQL_HARD_REFRESH_MODE: self.manage_edit(... open(filename).read() ...) I bet there are going to implications that need serious python thinking, but that'll just be a challange. What do you think about this? Peter
I wrote a product for just this purpose: using ZSQLMethods in fs-based products. Has some other neat features besides.
I'm not convinced. The solution I currently have (if it works when I start using it) is great.
It looks something like this::
class MyProduct(ObjectManager, SQLClass): def helloworld(self, bar): return SelectWorldSQLStatement(foo=bar)
class SQLClass(Acquisition.Implicit): pass
for filename, params, statement in getFilesEndingWithDotsql(): setattr(SQLClass, SQL(filename, 'No title', DBCONNECTION, params, statement))
I'm not sure I understand how setattr works here with only two arguments, and none of them a string. But maybe I've just never come across it and haven't been able to research it properly.
The "only" problem is refreshing. Not yet attempted this but it should be a good candidate::
I subclass SQL ("from Products.ZSQLMethods.SQL import SQL") and intercept the __call__ method to do something like this::
if SQL_HARD_REFRESH_MODE: self.manage_edit(... open(filename).read() ...)
I bet there are going to implications that need serious python thinking, but that'll just be a challange.
What do you think about this?
That's pretty clever, and it'll probably work. Making the SQL instances class attributes takes care of some of the main problems with SQL methods in products (like having separate SQL instances in all product instances.) A few things to keep in mind from when I solved this same problem: * SQL methods outside an object instance may not like that environment, as they rely on acquisition context to find things like DAs. I dunno if creating them at the class level will be a problem or not, and if it is, I don't know how easily soluble it'll be. You'll find out when you try. * Check if and how you interact with the persistence machinery in doing this. If you do, make sure that you're making packable changes. I won't make any predictions on how this'll actually function with regard to persistence. * Such a refresh scheme will suck like mad if you leave it on in a production environment. You could (like I did) check the file modification times to see if it needs to be refreshed (it's not hard at all.) Or possibly use some other refresh policy. * If you want to use more than one data source, or a non-standard file placement, your incantations become more complicated. The four lines+some function you show above isn't bad so far as boilerplate goes, but it has the poential to become tedious if you try to do too much. These may not even be problems in your environment, and if they are, they probably won't kill you. Except maybe the first two. And to get my shameless plug out of the way, I might point out that there's already a package that deals nicely with these problems (and more). --jcc
participants (3)
-
J Cameron Cooper -
Peter Bengtsson -
Peter Sabaini