On Thu, Feb 15, 2007 at 11:50:38AM +0100, Philipp von Weitershausen wrote: > What's already possible is to have a minimal ZODB with only one > persistent object: a SQLObject or SQLAlchemy container. That's a > container (e.g. like a folder) whose items aren't persisted in the ZODB > but come from a relational database.
This works fine in a Zope 2 / Five world too. We have apps that have nothing in the ZODB but a Z*DA instance. Then we have zope 3 views and adapters that acquire that instance and use it to talk to the database, using ZSQL to build the queries. We haven't drunk the ORM cool-aid yet. :) In other words: The ZODB may be there but you can pretty much ignore it if you don't need it :) > You seem to already have come to the conclusion that having code live in > both the filesystem and the ZODB can be painful. I think a good first > step for you would be to migrate your remaining ZODB-based code to the > filesystem. That not only makes deployment easier, you're also free to > refactor it then (e.g. using Zope 3 idioms). In the long run, this also > means saying good-bye to things like External Methods because they > require code on the filesystem and configuration in the ZODB. +1 Here's my off-the-cuff attempt at "How To Safely Move A Big Legacy App Out of the ZODB". First, get and install FSDump (google for it). Add a Dumper to a folder containing DTML (it works recursively on child folders too), configure the Dumper, click the "Save and dump" button, and voila, there's your code on the filesystem. It'll store properties too, in files named like *.metadata. Then you need a way to use the stuff from the filesystem. FileSystemSite would be ideal, because it understands those .metadata files: http://www.infrae.com/download/FileSystemSite Using it is a bit non-obvious if you're not familiar with CMF, from which it was extracted. You'll need to create a minimal Product on the filesystem that consists of: - a directory in Products, let's call it Products/mystuff - an __init__.py at Products/mystuff/__init__.py that looks like this: from Products.FileSystemSite.DirectoryView import registerDirectory registerDirectory('mysubdir, globals()) - a subdirectory at Products/mystuff/mysubdir. Put the files and directories you dumped in here. That's it. Restart Zope, add an instance of Filesystem Directory View, and you'll be prompted for the directory to choose; the only choice will be the "mysubdir" you registered above. Click OK and you're done. Check this new Product into source control and rejoice. One gotcha - files ending in .dtml will be treated as DTML Methods, not DTML Documents. So if you relied on the semantic difference between those, you will have some issues to sort out. Another gotcha - you'll need another plan to deal with those External Methods, since AFAIK neither Dumper nor FileSystemSite will handle them. One expedient if slightly tedious technique would be to just move the External Method files out of Extensions/ and into $INSTANCE_HOME/lib/python/. Then use calls to allow_module() so they can be imported by through-the-web code (google will tell you more about that). Then, delete each external method from the ZMI and in its place add a Script (Python) with the same id. Such a script would have a body something like: from my_ext_method_module import myExternalMethodFunction return myExternalMethodFunction(arguments) Once that's done, those scripts can be Dumped into your filesystem code, and all the DTML that includes calls to them should work. A final gotcha - if you have ZClasses, I can't help you :) At this point, you have the same application you started with, it's just on the filesystem. Not as clean as a rewrite, but a hell of a lot more expedient - faster and less risky. Next you'll want to start adding regression tests to your product (ZopeTestCase and Zelenium might be useful tools). Then you have a safety net so you can confidently start refactoring as needed. *This* is when you can start thinking about rewriting stuff :-) I'd put this email somewhere on zopewiki.org, but it seems to be down at the moment (Bad Gateway). > It is certainly possible to execute filesystem-based DTML (using > Globals.DTMLFile). Right. But that's a bit of a pain when you have dozens or hundreds of DTML methods and your first priority is just to get stuff out of the ZODB and into source control without breaking anything. -- Paul Winkler http://www.slinkp.com _______________________________________________ Zope maillist - Zope@zope.org http://mail.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope-dev )