最近用 collective.transmogrifier 將資料匯入 Plone 4.0.7,同時支援 CSV 和 PostgreSQL 兩種來源格式。
首先,用 paster 建立一個 my.importer 的專案,其中的 configure.zcml 內容範例如下:
<configure
xmlns="http://namespaces.zope.org/zope"
xmlns:five="http://namespaces.zope.org/five"
xmlns:genericsetup="http://namespaces.zope.org/genericsetup"
xmlns:transmogrifier="http://namespaces.plone.org/transmogrifier">
<includeDependencies package="." />
<genericsetup:registerProfile
name="default"
title="my.importer"
directory="profiles/default"
description="To set context for transmogrifier profiles."
provides="Products.GenericSetup.interfaces.EXTENSION"
/>
<include package="collective.transmogrifier" />
<include package="collective.transmogrifier" file="meta.zcml" />
<transmogrifier:registerConfig
name="my.importer.importMyNews"
title="My Importer for MyNews"
description="Transmogrifier Pipeline config to import contents."
configuration="confs/import_mynews.cfg"
/>
</configure>
在 confs 目錄裡,我們編輯 import_mynews.cfg 設定檔,範例內容如下:
[transmogrifier]
pipeline =
# csvsource
sqlsource
type-inserter
path-inserter
folders
constructor
schemaupdater
state-inserter
workflowupdater
reindexobject
#[csvsource]
#blueprint = collective.transmogrifier.sections.csvsource
#filename = my.importer:data/mynews.csv
[sqlsource]
blueprint = transmogrify.sqlalchemy
dsn = postgresql://username:secret@localhost:5432/dbname
query = SELECT id, title, description FROM my_table
[type-inserter]
blueprint = collective.transmogrifier.sections.inserter
key = string:_type
value = string:News Item
[path-inserter]
blueprint = collective.transmogrifier.sections.inserter
key = string:_path
value = string:/myfolder/${item/id}
[folders]
blueprint = collective.transmogrifier.sections.folders
[constructor]
blueprint = collective.transmogrifier.sections.constructor
[schemaupdater]
blueprint = plone.app.transmogrifier.atschemaupdater
[state-inserter]
blueprint = collective.transmogrifier.sections.inserter
key = string:_transitions
value = string:publish
[workflowupdater]
blueprint = plone.app.transmogrifier.workflowupdater
[reindexobject]
blueprint = plone.app.transmogrifier.reindexobject
來源是 SQL 資料時,使用的是 [sqlsource],來源是 CSV 資料時,就改用 csvsource,並在 data 目錄裡放好 mynews.csv 檔案,內容範例如下:
id,title,description
data1,My Data #1,Description of My Data #1
接著,編輯 my/importer/profiles/default/transmogrifier.txt 檔案,內容如下:
# this file contains transmogrifier profile names to run
# on GenericSetup transmogirifier's step
my.importer.importMyNews
以上就是 my.importer 專案的主要設定內容。最後,編輯 buildout.cfg 的內容如下:
eggs =
SQLAlchemy == 0.6.5
psycopg2
collective.transmogrifier
plone.app.transmogrifier
transmogrify.sqlalchemy
my.importer
zcml =
collective.transmogrifier-meta
collective.transmogrifier
plone.app.transmogrifier
transmogrify.sqlalchemy
上述 SQLAlchemy == 0.6.5 語法,代表要指定 (pin) 安裝 0.6.5 版本的
SQLAlchemy,不指定的話,可能會安裝太新的版本,未必合用,我的經驗是 SQLAlchemy 0.7.2 會遇到 ImportError: No module named exceptions 錯誤訊息。
一切搞定後,要讓上述設定值生效的話,可以直接到 ZMI 的 portal_setup,在 Import 頁籤裡,從 Select Profile or Snapshot 找尋 my.importer 選項,再找到 Run transmogrifier pipeline (第41項) 並勾選它,最後點選 Import selected steps 按鈕。
額外一提,PostgreSQL 裡的欄位資料如果更新為空值,執行 transmogrifier 後,也會將 Plone 表單欄位清空。