使用 Python 处理地理数据库
验证表名
地理数据库使用各种关系数据库管理系统 (RDBMS) 来保持构成地理数据库的许多表之间的关系。地理数据库的所有表必须有一个唯一名称,因此,在地理数据库中创建数据时,设定一个检查表名是否唯一的机制十分重要。如果脚本不能确保新输出名称的唯一性,则可能会存在意外覆盖数据的风险,而确保新表名的唯一性是消除这一风险的关键。
Exists() 函数可以查看表名在指定的工作空间中是否唯一。
脚本可以通过 ValidateTableName() 函数来确定在指定工作空间中指定名称是否有效和唯一。ValidateTableName() 函数本身不能确定在指定工作空间中指定名称是否唯一。它只会为该工作空间返回一个有效表名。
功能 |
说明 |
---|---|
ValidateTableName(name, {workspace}) |
获取表名和工作空间路径并为该工作空间返回一个有效表名 |
将工作空间指定为参数允许 ArcPy 检查所有现有表名,并确定是否存在由输出工作空间施加的命名限制。如果输出工作空间属于 RDBMS,则它可能保留了一些字,表名中不能使用这些字。还可能有一些不能用在表名或字段名中的无效字符。所有无效字符都用下划线 (_) 代替。ValidateTableName() 返回一个表示有效表名的字符串,该表名在输入名称有效的情况下可以与输入名称相同。以下示例保证由复制要素工具创建的新输出要素类在任何地理数据库中具有唯一有效名称:
# Move all shapefiles from a folder into a geodatabase # import arcpy from arcpy import env # Set the workspace. List all of the shapefiles # env.workspace = "D:/St_Johns" fcs = arcpy.ListFeatureClasses("*") # Set the workspace to SDE for ValidateTableName # env.workspace = "Database Connections/Bluestar.sde" # For each feature class name # for fc in fcs: # Validate the output name so it is valid # outfc = arcpy.ValidateTableName(fc) # Copy the features from the workspace to a geodatabase # arcpy.CopyFeatures_management(fc, outfc)
验证字段名
每个数据库都可以对表中字段名的命名进行限制。诸如要素类或关系类这样的对象在 RDBMS 中作为表存储,因此这些限制不是仅仅影响独立表而已。这些限制在各种数据库系统中可能常见也可能不常见,因此脚本应该检查所有新字段名以确保在执行过程中工具不会失败。
功能 |
说明 |
---|---|
ValidateFieldName(name, {workspace}) |
获取字符串(字段名)和工作空间路径,并基于输出地理数据库中的名称限制返回一个有效字段名。 |
无论输入名称如何,以下示例都可确保使用 ValidateFieldName 函数添加一个字段:
# Create a new numeric field containing the ratio of polygon area to # polygon perimeter. Two arguments, a feature class and field name, # are expected. # Define a pair of simple exceptions for error handling # class ShapeError(Exception): pass class FieldError(Exception): pass import arcpy import os try: # Get the input feature class and make sure it contains polygons # input = arcpy.GetParameterAsText(0) desc = arcpy.Describe(input) if desc.shapeType.lower() != "polygon": raise ShapeError # Get the new field name and validate it # fieldname = arcpy.GetParameterAsText(1) fieldname = arcpy.ValidateFieldName(fieldname, os.path.dirname(input)) # Make sure shape_length and shape_area fields exist # if len(arcpy.ListFields(input,"Shape_area")) > 0 and \ len(arcpy.ListFields(input,"Shape_length")) > 0: # Add the new field and calculate the value # arcpy.AddField_management(input, fieldname, "double") arcpy.CalculateField_management(input,fieldname, "[Shape_area] / [Shape_length]") else: raise FieldError except ShapeError: print "Input does not contain polygons" except FieldError: print "Input does not contain shape area and length fields" except: print arcpy.GetMessages(2)
无论何时脚本更新数据集(例如要素类或表),都要注意避免锁定数据集的情况。如果在 ArcCatalog 中打开了一个个人或文件地理数据库,则在取消选中该地理数据库且刷新该文件夹或者关闭 ArcCatalog 之前,脚本将不能更新地理数据库中的任何内容。这包括脚本工具。
分析表和字段名
脚本应该使用 ParseTableName() 和 ParseFieldName() 函数将数据集或表中列的全限定名称分割为各个组成部分(数据库、所有者、表和列)。需要与 RDBMS 无关的脚本不应该假定句点 (.) 是用来分开全限定数据集名称各个组成部分的分隔符。ArcGIS 应用程序总是使用全限定名称,因此如果将脚本用作脚本工具的源,则脚本在没有用户名称和数据库名称的情况下确定诸如要素类这样的名称时,必须分析所有要素类名称。在以下示例中,脚本检查输入要素类来获取特定用户名。脚本其实可以使用 Python 的分析函数来分割限定名称,但那样就会假定一种特定语法,该语法可能会因数据库类型不同而有所不同。ParseTableName() 返回一个由逗号分隔的带数据库名称、所有者名称和表名的字符串。ParseFieldName() 返回同样由逗号分隔的表名和字段名。脚本接着可以可靠分析返回的字符串,因为这些函数总是返回同样格式的字符串。Python 中的字符串具有许多自带的操作方法。在此示例中,分隔方法用于创建 Python 列表,并用逗号作为分隔符。
功能 |
说明 |
---|---|
ParseFieldName(name, {workspace}) |
将全限定字段名解析为依赖工作空间的各个组成部分(数据库、所有者名称、表名、字段名)。 |
ParseTableName(name, {workspace}) |
将表名解析为依赖工作空间的各个组成部分(数据库、所有者、表)。 |
# Append input feature class to another feature class and update field # import arcpy from arcpy import env import sys # Get the name of the input feature class and parse it. # env.workspace = os.path.dirname(arcpy.GetParameterAsText(0)) # Split ParseTableName's returned value to determine database, owner, and # featureclass # fullname = arcpy.ParseTableName(os.path.basename(arcpy.GetParameterAsText(0))) database, owner, featureclass = fullname.split(",") # Validate the name of the feature class that will be appended to and set # the workspace using the administrator's connection # env.workspace = "Database Connections/Trans_admin.sde" appendFC = arcpy.ValidateTableName("common", "roads") try: if owner == "TJohnson": arcpy.CalculateField_management(fullname, "AppendedBy", owner) arcpy.Append_management(fullname, appendFC) elif owner == "RSmith": arcpy.CalculateField_management(fullname, "AppendedBy", owner) arcpy.Append_management(fullname, appendFC) else: arcpy.AddError("Unknown user of input feature class") except: arcpy.AddError(arcpy.GetMessages(2))
Python 列表是任何类型对象(例如字符串或数字)的有序集合。列表从零开始,并且当知道列表内容的顺序时,可用于有效处理值数组。
用作脚本工具源的脚本可以对输入参数值做出一些假设。数据的路径总是通过地理处理框架完全限定。在 ArcGIS 应用程序之外运行的脚本不应做出同样的假设。