摘要
通过 Editor 类可以使用编辑会话和编辑操作来管理数据库事务。
编辑内容将被暂存,直到触发时才提交到数据。 如果在一个编辑操作中或在多个编辑操作之间发生了错误,这样可以更好地进行控制。
说明
编辑会话和编辑操作具有以下优点:
- 将编辑内容细分为原子事务。 如果在完成所有编辑之前发生了错误,编辑内容可以舍弃并且事务可以回滚。
- 由地理数据库维护可选编辑操作的撤消和重做堆栈。 停止编辑操作后,系统会将其置于撤消堆栈上。 可以通过调用 undoOperation 和 redoOperation 方法来遍历撤消和重做堆栈。
- 编辑会话和编辑操作都可实现分批更新,因此在编辑企业级地理数据库时可发挥巨大的性能优势。
- 在允许多用户同时编辑的地理数据库中,编辑会话中的应用程序在会话完成前将无法识别其他应用程序所做的更改。
Editor 类可用于启动和停止地理数据库和 shapefile 不同的编辑会话和编辑操作。
startEditing 方法用于启动编辑会话,startOperation 方法用于启动编辑操作。 要提交编辑操作,请调用 stopOperation。 要取消编辑操作,请调用 abortOperation。 要完成编辑会话,请调用 stopEditing,该方法接受一个布尔型参数,用于指示提交还是放弃会话内所做的更改。
注:
偏离此模式可能会导致意外结果。 例如,正在进行编辑操作时不应该调用 stopEditing。 而应该取消编辑操作,并停止编辑会话。
编辑操作必须控制在编辑会话的上下文中,而且编辑操作不能嵌套到其他编辑操作中。
编辑会话和 with 语句
编辑会话和编辑操作还可以与 with 语句结合使用。 with 语句充当上下文管理器并负责处理相应的启动、停止和中止调用。 以下示例突出了 Editor 类与 with 语句结合使用的基本结构。
import arcpy
# Open an edit session and start an edit operation
with arcpy.da.Editor(workspace) as edit:
# <your edits>
# If an exception is raised, the operation will be aborted, and
# the edit session is closed without saving
# If no exceptions are raised, stop the operation and save
# and close the edit session
使用撤消和重做堆栈
撤消和重做堆栈在编辑会话中是否启用,具体取决于 startEditing 方法的布尔型参数。 如果编辑会话将包含多个可能依相应的条件回滚(和重做)的操作,应启用撤消和重做堆栈。 否则可以通过将参数设置为 False 来禁用撤消和重做堆栈,以提升系统性能(例如,编辑会话仅包含一个操作)。
注:
在企业级地理数据库中启动版本化的编辑会话时,将启用撤消和重做堆栈。 未版本化的编辑会话不支持撤消和重做操作。
用于控制撤消和重做堆栈的两种方法是 undoOperation 和 redoOperation。 undoOperation 将编辑会话的状态回滚到上一编辑操作,并将编辑操作移至重做堆栈。 redoOperation 方法将编辑操作从最近的重做堆栈移回撤消堆栈,并将编辑会话状态向前滚动至执行编辑操作后所处的状态。 提交编辑操作时,将清除重做堆栈,之后将无法重做任何曾位于重做堆栈中的操作。
需要编辑会话的情况
以下列出了只能在编辑会话中编辑的一些数据集类型:
- 参与拓扑的要素类
- 参与几何网络的要素类
- 参与网络数据集的要素类
- 企业级地理数据库中的版本化数据集
- 一些带有类扩展的对象和要素类
编辑会话和游标
游标应限制在单个编辑操作中。 这意味着,对于每个操作都应实例化并释放一个新的游标。 在编辑由某一游标返回的行时这一点非常重要,因为行与地理数据库的特定状态紧密相关。 应避免在多个编辑操作中使用同一游标。 这样做会导致意外情况以及数据损失。
编辑会话和版本化数据
可以对企业级地理数据库表和要素类进行版本化。 isVersioned 属性可用于确定表或要素类是否已版本化。
编辑企业级地理数据库表和要素类时,应根据正在编辑的数据类型设置编辑会话模式:
- 编辑非版本化表或要素类时,将 multiuser_mode 参数设置为 False。
- 编辑版本化表或要素类时,将 multiuser_mode 参数设置为 True。
使用 Editor 类或 Editor 类的 startEditing 方法来设置 multiuser_mode。
如果未正确设置多用户模式,可能会收到无法在编辑会话之外更新此类中对象的错误。
语法
Editor (workspace, {multiuser_mode})
参数 | 说明 | 数据类型 |
workspace | Path to the workspace to edit. The editor can edit only one workspace at a time. | String |
multiuser_mode | When edits will be performed on versioned data, set this to True; otherwise, set it to False. Only use with enterprise geodatabases. (默认值为 True) | Boolean |
属性
属性 | 说明 | 数据类型 |
isEditing (只读) | Editor 在编辑会话中时为真。 | Boolean |
方法概述
方法 | 说明 |
__enter__ () | 启动编辑会话。 |
__exit__ () | 如果成功,则停止编辑并保存编辑会话。如果发生异常,则停止编辑但不进行保存。 |
startEditing ({with_undo}, {multiuser_mode}) | 启动编辑会话。 |
stopEditing (save_changes) | 停止编辑会话。 |
startOperation () | 启动编辑操作。 |
stopOperation () | 停止编辑操作。 |
abortOperation () | 中止编辑操作。 |
undoOperation () | 撤消编辑操作(回滚修改内容)。 |
redoOperation () | 恢复编辑操作。 |
方法
__enter__ ()
__exit__ ()
startEditing ({with_undo}, {multiuser_mode})
参数 | 说明 | 数据类型 |
with_undo | Sets whether the undo and redo stacks are enabled or disabled for an edit session. If an edit session will contain multiple operations that might be conditionally rolled back (and redone), the undo and redo stacks should be enabled. If not—for example, if the edit session will only contain a single operation—the undo and redo stacks can be disabled for performance benefits by setting the argument to false. When starting a versioned edit session in enterprise geodatabase, the undo and redo stacks will always be enabled. Nonversioned edit sessions do not support undo and redo operations. (默认值为 True) | Boolean |
multiuser_mode | When False, you have full control of editing a nonversioned, or versioned dataset. If your dataset is nonversioned and you use stopEditing(False), your edit will not be committed (otherwise, if set to True, your edits will be committed). (默认值为 True) | Boolean |
stopEditing (save_changes)
参数 | 说明 | 数据类型 |
save_changes | Specifies whether to save or discard changes. (默认值为 True) | Boolean |
startOperation ()
stopOperation ()
abortOperation ()
undoOperation ()
redoOperation ()
代码示例
以下代码使用 with 语句,此语句用于开启编辑操作并在表的一组所选行中使用 CalculateField 函数。 并将处理和打印出现的任何工具错误。
由于在 with 语句中执行 CalculateField 函数,如果出现任何异常,将不会保存更改。 如果成功完成 CalculateField,将保存更新。
import arcpy
fc = 'C:/Portland/Portland.gdb/Land/Parks'
workspace = 'C:/Portland/Portland.gdb'
layer_name = 'Parks'
arcpy.MakeFeatureLayer_management(fc, layer_name)
arcpy.SelectLayerByAttribute_management(
layer_name, 'NEW_SELECTION',
"""CUSTODIAN = 'City of Portland'""")
with arcpy.da.Editor(workspace) as edit:
arcpy.CalculateField_management(layer_name, 'Usage', '"PUBLIC"', 'PYTHON')
以下为开始编辑会话和编辑操作、在表中创建行、停止编辑操作以及提交编辑会话的示例。
import arcpy
import os
fc = 'C:/projects/Portland/Portland.sde/portland.jgp.schools'
workspace = os.path.dirname(fc)
# Start an edit session. Must provide the workspace.
edit = arcpy.da.Editor(workspace)
# Edit session is started without an undo/redo stack for versioned data
# Set multiuser_mode to False if working with unversioned enterprise gdb data
edit.startEditing(with_undo=False, multiuser_mode=True)
# Start an edit operation
edit.startOperation()
# Insert a row into the table.
with arcpy.da.InsertCursor(fc, ('SHAPE@', 'Name')) as icur:
icur.insertRow([(7642471.100, 686465.725), 'New School'])
# Stop the edit operation.
edit.stopOperation()
# Stop the edit session and save the changes
edit.stopEditing(save_changes=True)
以下是将 Editor 类作为上下文管理器用于版本化数据的示例。
import arcpy
import os
new_students = 'C:/projects/Portland/Portland.sde/ptld.main.students_new2022'
students = 'C:/projects/Portland/Portland.sde/ptld.main.students'
# Start an edit session. Provide the workspace being acted on
# and with sde specify if data is edited in multiuser_mode.
with arcpy.da.Editor(os.path.dirname(students), multiuser_mode=True):
# If all 3 edit operations run successfully without error
# upon exiting this code block the edits will be applied to the data
arcpy.management.CalculateField(new_students , 'arrived', '2022')
arcpy.management.Append(new_students, students)
arcpy.management.CalculateField(students, "active", True)