使用 Python 脚本批量协调和提交传统版本

ArcGIS 地理数据库管理员可使用 Python 脚本自动执行通常要使用多个地理处理工具执行的多个任务。本主题将介绍管理员可能需要执行的、使安排在每晚进行的传统版本协调得以运行的过程。

注:

该工作流特定于传统版本化。分支版本化不像传统版本化那样具有添加和删除表,因此不需要本主题中描述的许多相同的管理任务。

许多管理员都想要确保运行协调时没有其他用户连接到数据库。ArcPy 函数 ListUsersDisconnectUser 可用来确保只有管理员连接到了地理数据库。

查找已连接用户

首先,使用 ListUsers 函数确定连接到地理数据库的用户。必须提供地理数据库管理员连接以运行 ListUsers 函数。

# Get a list of connected users.
userList = arcpy.ListUsers("C:\\Projects\\MyProject\\admin.sde")

分析已连接用户列表

获得已连接用户的列表后,您可以通知这些用户需要与地理数据库断开连接。可以通过获取用户列表及其相关电子邮件地址来完成通知。

为简单起见,本例假定每个连接到地理数据库的用户都有与其电子邮件地址名称相同的基本名称。可更改本例以使用其他方法确定电子邮件地址。

# Get a list of user names from the list of named tuples returned from ListUsers
userNames = [u.Name for u in userList]
# Take the userNames list and make email addresses by appending the appropriate suffix.
emailList = [name +  '@company.com' for name in userNames]

生成并发送电子邮件

使用电子邮件列表将电子邮件通过 Python 发送给用户以通知他们需要与地理数据库断开连接。本例使用了 Python 的 smtplib 模块,但是还有其他一些选项可以通过非标准模块发送电子邮件。

import smtplib SERVER = "mailserver.yourcompany.com"
FROM = "SDE Admin <python@yourcompany.com>"
TO = emailList SUBJECT = "Maintenance is about to be performed"
MSG = "Auto generated Message.\n\rServer maintenance will be performed in 15 minutes. Please log off."
# Prepare actual message MESSAGE = """\ From: %s To: %s Subject: %s
%s
""" % (FROM, ", ".join(TO), SUBJECT, MSG)
# Send the mail server = smtplib.SMTP(SERVER) server.sendmail(FROM, TO, MESSAGE)
server.quit()

阻止与地理数据库的连接

通过脚本使用 ArcPy 函数 AcceptConnections 阻止与地理数据库的连接。仅可通过 Python 脚本获得此函数。

这将阻止所有新用户连接到地理数据库。但现有连接仍将存在。

#Block new connections to the database.
arcpy.AcceptConnections('C:\\Projects\\MyProject\\admin.sde', False)
注:

没有必要阻止连接到数据库或断开所有用户连接来执行此维护。如果您的组织可允许断开所有连接,那么压缩过程的效率可能会更高。

暂停脚本

为了让用户有时间在连接断开之前完成工作,脚本需要暂停 15 分钟。Python 中的时间模块能够在已连接用户在断开连接之前提供 15 分钟的宽限期。

import time
time.sleep(900)#time is specified in seconds

断开用户连接

通过脚本使用 ArcPy 函数 DisconnectUser 断开用户连接。仅可通过 Python 脚本获得此函数。

在已通知用户并且脚本已暂停 15 分钟之后,用户连接就会断开。

#Disconnect all users from the database.
arcpy.DisconnectUser('C:\\Projects\\MyProject\\admin.sde', "ALL")
注:

如果仅希望指定用户断开连接,则提供这些用户连接的连接 ID 字符串或 Python 字符串列表。这些 ID 由 ListUsers 函数返回。

批量协调版本和提交更改内容

协调版本工具可用于协调和提交企业级地理数据库中的所有版本。此工具提供了可以将地理数据库中所有版本协调至目标版本 (ALL_VERSIONS),或仅协调阻止目标版本压缩的版本 (BLOCKING_VERSIONS)。此工具是实现有效压缩的方法,因为它允许多个版本以合适顺序一次性协调和提交。在本例中,以地理数据库管理员身份运行此工具。以地理数据库管理员身份进行连接能够协调和提交地理数据库中的所有版本,甚至是由其他用户拥有的私有版本或受保护版本。

# Get a list of versions to pass into the ReconcileVersions tool. versionList = arcpy.da.ListVersions('C:\\Projects\\MyProject\\admin.sde')
# Execute the ReconcileVersions tool.
arcpy.ReconcileVersions_management('C:\\Projects\\MyProject\\admin.sde', "ALL_VERSIONS", "sde.DEFAULT", versionList, "LOCK_ACQUIRED", "NO_ABORT", "BY_OBJECT", "FAVOR_TARGET_VERSION", "POST", "DELETE_VERSION", "c:/temp/reconcilelog.txt")

压缩地理数据库

在协调和提交更改内容之后,需要压缩地理数据库以移除任何冗余信息并将编辑内容移动至业务表内,这一点很重要。

# Run the compress tool. 
arcpy.Compress_management('C:\\Projects\\MyProject\\admin.sde')

允许与地理数据库的连接

完成协调和提交版本并压缩地理数据库后,您可以允许用户连接。

# Allow new connections to the database.
arcpy.AcceptConnections('C:\\Projects\\MyProject\\admin.sde', True)

重新构建索引并更新统计数据

在执行压缩操作之后,推荐重新构建索引并更新统计数据。可使用重建索引分析数据集工具来执行这些步骤。这些工具允许输入一列数据集,并可一次性在所有数据集上执行函数。以地理数据库管理员身份运行这些工具时还可以更新统计数据并为合适的系统表重新构建索引。此过程的第一部分是获取数据以及拥有这些数据的用户的列表,然后以数据所有者身份更新索引和统计数据。

一旦用户所拥有的数据列表得到确定,就会将其传递到重新构建索引分析数据集工具。

如果您有多个数据所有者,则需要为每个数据所有者生成一个数据列表,并将在以每位用户的身份进行连接时运行重新构建索引分析数据集工具。

# Set the workspace. arcpy.env.workspace = "C:\\Projects\\MyProject\\user1.sde"
# Set a variable for the workspace.
workspace = arcpy.env.workspace
# Get the user name for the workspace.
# This assumes you are using database authentication. # OS authentication connection files do not have a 'user' property. userName = arcpy.Describe(workspace).connectionProperties.user
# Get a list of all the datasets the user has access to. # First, get all the stand-alone tables, feature classes and rasters owned by the current user. dataList = arcpy.ListTables('*.' + userName + '.*') + arcpy.ListFeatureClasses('*.' + userName + '.*') + arcpy.ListRasters('*.' + userName + '.*')
# Next, for feature datasets owned by the current user,
# get all of the feature classes and add them to the master list. for dataset in arcpy.ListDatasets('*.' + userName + '.*'):
    dataList += arcpy.ListFeatureClasses(feature_dataset=dataset)
# Pass in the list of datasets owned by the connected user to the rebuild indexes 
# and update statistics on the data tables.
arcpy.RebuildIndexes_management(workspace, "NO_SYSTEM", dataList, "ALL")
arcpy.AnalyzeDatasets_management(workspace, "NO_SYSTEM", dataList, "ANALYZE_BASE", "ANALYZE_DELTA", "ANALYZE_ARCHIVE"
注:

用于限制用户拥有的数据集的通配符令牌与数据库相关。在以上示例中,('*.' + userName + '.*') 将适用于 SQL Server、PostgreSQL 或 DB2。对于 Oracle,可以使用以下通配符:(userName + '.*')

完整代码示例

以下代码示例将上述所有部分组合在一起,以便以地理数据库管理员用户的身份执行以下操作:

  • 确定已连接用户。
  • 发送电子邮件通知。
  • 阻止地理数据库接受新连接。
  • 断开用户连接。
  • 协调版本和提交更改内容。
  • 压缩地理数据库。
  • 允许地理数据库开始接受新连接。
  • 在系统表中重建索引并更新统计数据。
import arcpy, time, smtplib
# Set the workspace. arcpy.env.workspace = 'C:\\Projects\\MyProject\\admin.sde'
# Set a variable for the workspace.
adminConn = arcpy.env.workspace
# Get a list of connected users. userList = arcpy.ListUsers(adminConn)
# Get a list of user names of users currently connected and make email addresses.
emailList = [user.Name + "@yourcompany.com" for user in arcpy.ListUsers(adminConn)]
# Take the email list and use it to send an email to connected users. SERVER = "mailserver.yourcompany.com"
FROM = "SDE Admin <python@yourcompany.com>"
TO = emailList SUBJECT = "Maintenance is about to be performed"
MSG = "Auto generated Message.\n\rServer maintenance will be performed in 15 minutes. Please log off."
# Prepare actual message.
MESSAGE = """\ From: %s To: %s Subject: %s
%s
""" % (FROM, ", ".join(TO), SUBJECT, MSG)
# Send the email.
print("Sending email to connected users") server = smtplib.SMTP(SERVER) server.sendmail(FROM, TO, MESSAGE) server.quit()
# Block new connections to the database. print("The database is no longer accepting connections") arcpy.AcceptConnections(adminConn, False)
# Wait 15 minutes.
time.sleep(900)
# Disconnect all users from the database. print("Disconnecting all users") arcpy.DisconnectUser(adminConn, "ALL")
# Get a list of versions to pass into the ReconcileVersions tool. # Only reconcile versions that are children of Default.
print("Compiling a list of versions to reconcile") verList = arcpy.da.ListVersions(adminConn) versionList = [ver.name for ver in verList if ver.parentVersionName == 'sde.DEFAULT']
# Execute the ReconcileVersions tool. print("Reconciling all versions") arcpy.ReconcileVersions_management(adminConn, "ALL_VERSIONS", "sde.DEFAULT", versionList, "LOCK_ACQUIRED", "NO_ABORT", "BY_OBJECT", "FAVOR_TARGET_VERSION", "POST", "DELETE_VERSION", "c:/temp/reconcilelog.txt")
# Run the compress tool. print("Running compress")
arcpy.Compress_management(adminConn)
# Allow the database to begin accepting connections again.
print("Allow users to connect to the database again") arcpy.AcceptConnections(adminConn, True)
# Update statistics and indexes for the system tables.
# Note: To use the "SYSTEM" option, the user must be an geodatabase or database administrator. # Rebuild indexes on the system tables.
print("Rebuilding indexes on the system tables") arcpy.RebuildIndexes_management(adminConn, "SYSTEM")
# Update statistics on the system tables.
print("Updating statistics on the system tables") arcpy.AnalyzeDatasets_management(adminConn, "SYSTEM")
print("Finished.")

自动为脚本进行计划

脚本完成后,就会使用操作系统的任务计划程序为其进行计划,以使其在某个特定时间以设定间隔运行。