Palladion Software
user icon Guest

Dumping and Reloading CMF Content

A proposal for an architecture supporting dump and reload of content in a CMF site.

Created by tseaver. Last modified 2005-09-23 13:25:27.

Overview

When moving content between systems, or when migrating the CMS between software versions, being able to dump the content to a "useful" filesystem representation can be amazingly freeing. This proposal outlines a pluggable architecture for enabling such operations, leveraging the mechanisms offered by the CMFSetup framework.

Lossy vs. Lossless Dump

Some usecases need to preserve all bits for content objects; such dumps are isomorphic with the ZODB export formats, with every attribute and subobject included, often in formats which are not "useful" (because they are opaque). Even the XML version of the ZODB export format is not very useful (although a sufficiently enterprising team of XSLT hackers might, in time, get something useful out of the format).

Many other applications, however, do not require lossless export; some may even have reasons to want to abandon some of the bits (e.g., to clean out cruft).

The architecture proposed in this document does not mandate either lossy or lossless export / import, treating that choice as a policy left to the plugins which do the actual work.

Comparison with Zope3's fssync

Zope3 offers a somewhat similar framework for serialization of content to the filesystem. The focus of fssync differs from this proposal: the primary usecase for fssync is to facilitate checking content out of the Zope3 application, modifying it on the filesystem with traditional tools, and then checking it back into Zope.

In order to support this use case, fssync chooses to create a "lossless" representation, as follows:

CMFSetup Architecture

CMFSetup offers a couple of useful abstractions for this task:

Framework Interfaces

The adapters which must be supplied in order for content objects to play in this framework implement the following interfaces:

    class IFilesystemExporter(Interface):
        """ Plugin interface for site structure export.
        """
        def export(export_context, subdir):
            """ Export our 'context' using the API of 'export_context'.

            o 'export_context' must implement
              Products.GenericSupport.interfaces.IExportContext.

            o 'subdir', if passed, is the relative subdirectory containing our
              context within the site.
            """
        def listExportableItems():
            """ Return a sequence of the child items to be exported.

            o Each item in the returned sequence will implement
              IFilesystemExporter.
            """
    class IFilesystemImporter(Interface):
        """ Plugin interface for site structure export.
        """
        def import_(import_context, subdir):
            """ Import our 'context' using the API of 'import_context'.

            o 'import_context' must implement
              Products.GenericSupport.interfaces.IImportContext.

            o 'subdir', if passed, is the relative subdirectory containing our
              context within the site.
            """

Issues