8. 迁移

的主要设计目标之一 CubicWeb 是为了支持迭代和敏捷开发。为此,提供了多个操作来促进实例的改进,尤其是在不丢失现有数据的情况下处理要应用于数据模型的更改。

文件中提供了多维数据集(以及多维数据集Web本身)的当前版本 __pkginfo__.py 作为3个整数的元组。

8.1. 迁移脚本管理

迁移脚本必须位于目录中 migration 并相应命名:

<version n° X.Y.Z>[_<description>]_<mode>.py

在哪儿:

  • x.y.z是脚本允许迁移到的模型版本号。

  • mode (在最后一个“u”和扩展名“.py”之间)用于分布式安装。它指示脚本应用于应用程序的哪个部分(RQL服务器、Web服务器)。其价值可能是:

    • common ,适用于RQL服务器和Web服务器,并更新硬盘上的文件(例如配置文件迁移)。

    • web ,仅适用于Web服务器并更新硬盘上的文件。

    • repository ,仅适用于RQL服务器并更新硬盘上的文件。

    • Any ,仅适用于RQL服务器并更新数据库中的数据(例如模式和数据迁移)。

再次出现在目录中 migration ,文件 depends.map 允许指示要迁移到特定的模型版本,必须首先迁移到特定的 CubicWeb 版本。此文件可以包含注释(行以 # )依赖项如下所示:

<model version n° X.Y.Z> : <cubicweb version n° X.Y.Z>

例如:::

0.12.0: 2.26.0
0.13.0: 2.27.0
# 0.14 works with 2.27 <= cubicweb <= 2.28 at least
0.15.0: 2.28.0

8.2. 基本上下文

迁移脚本中预先定义了以下标识符:

  • config ,实例配置

  • interactive_mode ,布尔值,指示脚本是否以交互模式执行。

  • versions_map ,已迁移版本的字典(键是多维数据集名称,包括“cubicWeb”,值是(从版本到版本)

  • confirm(question) ,函数询问用户,如果用户回答“是”,则返回“真”;否则返回“假”(非交互模式下始终返回“真”)。

  • _() 等于 unicode 允许在迁移脚本中标记要国际化的字符串。

repository 脚本,还定义了以下标识符:

  • commit(ask_confirm=True) ,请求确认并执行“提交”

  • schema ,实例架构(从数据库读取)

  • fsschema ,已在文件系统上安装架构(例如,更新模型和CubicWeb的架构)

  • repo ,存储库对象

  • session ,存储库会话对象

8.3. 新建多维数据集依赖项

如果代码依赖于一些新的多维数据集,则必须使用以下方法将它们添加到迁移脚本中:

  • add_cube(cube, update_database=True) ,添加多维数据集。

  • add_cubes(cubes, update_database=True) ,添加多维数据集列表。

这个 update_database 参数指示是否应更新数据库架构,或者只应插入相关的持久性属性(对于从现有多维数据集提取新多维数据集的情况,因此新多维数据集架构实际上已在其中)。

如果一个实例已经使用了一些添加的多维数据集,那么它们将被悄悄地跳过。

要删除多维数据集,请使用 drop_cube(cube, removedeps=False) .

8.4. 架构迁移

以下用于架构迁移的函数可用于 repository 脚本:

  • add_attribute(etype, attrname, attrtype=None, commit=True) ,将新属性添加到现有实体类型。如果未指定属性类型,则从更新的架构中提取该属性类型。

  • drop_attribute(etype, attrname, commit=True) 从现有实体类型中移除属性。

  • rename_attribute(etype, oldname, newname, commit=True) ,重命名属性

  • add_entity_type(etype, auto=True, commit=True) ,添加新的实体类型。如果 auto 如果为true,则将自动添加使用此实体类型且另一方面具有已知实体类型的所有关系。

  • drop_entity_type(etype, commit=True) ,删除一个实体类型及其使用的所有关系。

  • rename_entity_type(oldname, newname, commit=True) ,重命名实体类型

  • add_relation_type(rtype, addrdef=True, commit=True) ,添加新的关系类型。如果 addrdef 为true,将添加此类型的所有关系定义。

  • drop_relation_type(rtype, commit=True) ,删除关系类型和此类型的所有定义。

  • rename_relation_type(oldname, newname, commit=True) ,重命名关系类型。

  • add_relation_definition(subjtype, rtype, objtype, commit=True) ,添加新的关系定义。

  • drop_relation_definition(subjtype, rtype, objtype, commit=True) ,删除关系定义。

  • sync_schema_props_perms(ertype=None, syncperms=True, syncprops=True, syncrdefs=True, commit=True) ,同步以下对象的属性和/或权限:-如果ertype为none,则为整个架构-如果ertype为字符串,则为实体或关系类型架构-如果ertype为3-uple,则为关系定义(subject、relation、object)

  • change_relation_props(subjtype, rtype, objtype, commit=True, **kwargs) ,使用要更改的属性的命名参数更改关系定义的属性。

  • set_widget(etype, rtype, widget, commit=True) ,更改用于实体类型<etype>的关系<rtype>的小部件。

  • set_size_constraint(etype, rtype, size, commit=True) ,更改实体类型<etype>的关系<rtype>的大小约束。

  • update_bfss_path(old_path, new_path, commit=True) ,更改路径 old_pathnew_path 以字节为单位的文件系统存储(BFS)。

8.5. 数据迁移

以下用于数据迁移的功能在 repository 脚本:

  • rql(rql, kwargs=None, cachekey=None, ask_confirm=True) ,执行任意RQL查询,查询或更新。返回结果集对象。

  • add_entity(etype, *args, **kwargs) ,添加给定类型的新实体。属性和关系值被指定为命名的位置参数。

8.6. 工作流创建

以下用于创建工作流的功能在 repository 脚本:

  • add_workflow(label, workflowof, initial=False, commit=False, **kwargs) ,为给定类型添加新工作流,

  • get_workflow_for(etype) ,返回给定实体类型的工作流,

  • transition_by_name(self, trname) ,方法cubicweb.entities.wfobjs.Workflow实例,返回名为 trname

  • set_permissions(self, requiredgroups=(), conditions=(), reset=True) 方法cubicweb.entities.wfobjs设置或添加(如果 reset 为False)此转换的组和条件。

您可以在本章中找到有关工作流的更多详细信息 定义工作流 .

8.7. 配置迁移

以下用于配置迁移的功能在所有脚本中都可用:

  • option_renamed(oldname, newname) ,表示选项已重命名

  • option_group_change(option, oldgroup, newgroup) ,表示选项不再属于同一组。

  • option_added(option) ,表示已添加选项。

  • option_removed(option) ,表示某个选项已被删除。

这个 config 变量是一个对象,可以使用类似字典的语法访问配置值,用于读取和更新。

示例1:迁移脚本更改all-in-one.conf中的变量'sender addr'。

wrong_addr = 'cubicweb@loiglab.fr' # known wrong address
fixed_addr = 'cubicweb@logilab.fr'
configured_addr = config.get('sender-addr')
# check that the address has not been hand fixed by a sysadmin
if configured_addr == wrong_addr:
    config['sender-addr'] = fixed-addr
    config.save()

示例2:检查数据库后端驱动程序的值,这在需要在迁移脚本中发出与后端相关的原始SQL查询时非常有用。

dbdriver  = config.sources()['system']['db-driver']
if dbdriver == "sqlserver2005":
    # this is now correctly handled by CW :-)
    sql('ALTER TABLE cw_Xxxx ALTER COLUMN cw_name varchar(64) NOT NULL;')
    commit()
else: # postgresql
    sync_schema_props_perms(ertype=('Xxxx', 'name', 'String'),
    syncperms=False)

8.8. 其他迁移功能

这些功能仅用于无法以其他方式完成的低级操作,或用于在交互式会话期间修复损坏的数据库。它们在 repository 脚本:

  • sql(sql, args=None, ask_confirm=True) ,对系统源执行任意SQL查询

  • add_entity_type_table(etype, commit=True)

  • add_relation_type_table(rtype, commit=True)

  • uninline_relation(rtype, commit=True)

[FIXME] 添加有关如何使用CubicWeb CTL Shell的说明