Select to view content in your preferred language

Issue with creating relationship class via python script

652
3
Jump to solution
09-13-2023 06:41 AM
RPGIS
by
Regular Contributor

Hi,

I encountered an issue regarding creating a relationship feature class in a test sde database. The issue that I encountered is the script will create the relationship class, but for some reason none of the data relates for some reason. At first, I thought it might be due to none of the related features having data in them as a possibility. I ran the same script with data in both of the features and it worked. I don't know why this would be an issue or if anyone else has had similar issues, but I would like to know if there is a way to make certain that this won't happen again next time the script runs.

 

 

 

# Import arcpy da modules
from arcpy.da import (
    # Import functions/classes pertaining to editing features in databases
    Editor as Editing, SearchCursor as Searching, InsertCursor as Inserting, UpdateCursor as Updating,
    # Import functions/classes pertaining to looping or creating item lists
    ListDomains, Walk, ListVersions, ListContingentValues
    )

# Import arcpy management modules
from arcpy.management import (
    # Creating features
    CreateFeatureDataset as MakeDataset, CreateFeatureclass, CreateTable ,
    # Feature field modifications
    AddField, AlterField as ModifyField , DeleteField ,
    # Creating, deleting, or modifying domains
    CreateDomain, AlterDomain, AddCodedValueToDomain as AddCode, DeleteCodedValueFromDomain as DeleteCode, SetValueForRangeDomain as SetRange, DeleteDomain, AssignDomainToField, RemoveDomainFromField ,
    # Attribute rules
    EnableAttributeRules, DisableAttributeRules, AddAttributeRule, AlterAttributeRule, DeleteAttributeRule ,
    # Creating feature relations
    CreateRelationshipClass as MakeRelation, AddRelate, RemoveRelate ,
    # Establishing roles and users
    CreateRole, ChangePrivileges, CreateDatabaseUser, ChangePrivileges, UpdatePortalDatasetOwner ,
    # Updating licensing information
    UpdateEnterpriseGeodatabaseLicense as LicenseUpdate ,
    # Enabling or disabeling editor tracking on features
    EnableEditorTracking as TrackEdits, DisableEditorTracking as StopTrackEdits ,
    # Managing versions
    CreateVersion, ChangeVersion, AlterVersion, DeleteVersion , RegisterAsVersioned , UnregisterAsVersioned ,
    # Creating contingent values
    CreateFieldGroup , AlterFieldGroup , DeleteFieldGroup , AddContingentValue , RemoveContingentValue ,
    # Add global ids
    AddGlobalIDs ,
    # Create database connections
    CreateDatabaseConnection ,
    # Manage layer symbology from existing layer
    ApplySymbologyFromLayer ,
    # Make a feature layer
    MakeFeatureLayer , SaveToLayerFile
    )

# Create relationship table between certain feature classes
def RelateFeatures( InputDatabase, RelateFeaturesDictionary ):
    Tab = ' ' * 4
    print ( f'Creating relationship classes for relations in { list( RelateFeaturesDictionary ) }' )

    # Important variables
    Relationships = 'Relationships'
    Origin, Destination, ToLabel, FromLabel, Field = 'Origin', 'Destination', 'ToLabel', 'FromLabel', 'Field'
    To, From, Both, Neither = 'FORWARD', 'BACKWARD', 'BOTH', 'NONE'
    Attributed, NotAttributed = 'ATTRIBUTED', 'NONE'
    Simple, Composite = 'SIMPLE', 'COMPOSITE'
    OneCardinality, OneManyCardinality, ManyCardinality = 'ONE_TO_ONE', 'ONE_TO_MANY', 'MANY_TO_MANY'

    # Important feature classes and tables
    FeatureClasses = { filename : Combine( InputDatabase, filename ) for root, directory, filenames in Walk( InputDatabase, datatype='FeatureClass' ) for filename in filenames }
    Tables = { filename : Combine( InputDatabase, filename ) for root, directory, filenames in Walk( InputDatabase, datatype='Table' ) for filename in filenames }

    # Get all relationship feature classes
    Relationships = { filename : Combine( InputDatabase, filename ) for root, directory, filenames in Walk(InputDatabase, datatype='RelationshipClass') for filename in filenames }
    ValidateExistingRelationships = [ RelateName for RelateName in RelateFeaturesDictionary for ExistingRelation in Relationships if RelateName in ExistingRelation ]

    # Create the relationships for each named relation in the dictionary
    for Relation in RelateFeaturesDictionary:
        
        OriginName = RelateFeaturesDictionary[ Relation ][ Origin ]
        DestinationName = RelateFeaturesDictionary[ Relation ][ Destination ]
        
        RelationshipClass = Combine( InputDatabase, Relation )
        OriginFeature = None
        DestinationFeature = None
        OriginLabel = RelateFeaturesDictionary[ Relation ][ ToLabel ]
        DestinationLabel = RelateFeaturesDictionary[ Relation ][ FromLabel ]
        KeyField = RelateFeaturesDictionary[ Relation ][ Field ]

        # Get the origin feature from either feature classes or tables
        for Name in FeatureClasses:
            Fullname = None
            if '.' in Name:
                Fullname = Name.split( '.' )[ -1 ]
            if Fullname == OriginName:
                OriginFeature = FeatureClasses[ Name ]

        # Get the destination feature from either feature classes or tables
        for Name in Tables:
            Fullname = None
            if '.' in Name:
                Fullname = Name.split( '.' )[ -1 ]
            if Fullname == DestinationName:
                DestinationFeature = Tables[ Name ]

        # Create the relationship class if the relationship class does not exist
        if Relation not in ValidateExistingRelationships:
            NewRelation = MakeRelation( OriginFeature, DestinationFeature, RelationshipClass, Simple, OriginLabel, DestinationLabel, To, OneManyCardinality, NotAttributed, KeyField, KeyField )
            print ( f'{ Tab }{ NewRelation } has been created between { RootName( OriginFeature ) } as the origin and { RootName( DestinationFeature ) } as the destination' )

    print ( '\n' )
    return

# Core relationship features
Relationships = {
    'Relationship Name' : {
        Origin : FeatureA,
        Destination : TableA,
        ToLabel : 'To Message',
        FromLabel : 'From Message',
        Field : 'Selected Field Name'
        }
    }

# Create relationships
RelateFeatures( MainDatabase, Relationships )

 

 

 

0 Kudos
1 Solution

Accepted Solutions
DougBrowning
MVP Esteemed Contributor

Why all these crazy import renames and such?  All you should need is this I think.

import arcpy
arcpy.env.workspace = "C:/data/Habitat_Analysis.gdb"
arcpy.CreateRelationshipClass_management("vegtype", "vegtable", "veg_RelClass", "SIMPLE",
"Attributes from vegtable", "Attributes and Features from vegtype",
"NONE", "ONE_TO_ONE", "NONE", "HOLLAND95", "HOLLAND95")

https://pro.arcgis.com/en/pro-app/latest/tool-reference/data-management/create-relationship-class.ht...

Hope that works

View solution in original post

0 Kudos
3 Replies
RogerDunnGIS
Occasional Contributor II

Could you rephrase the question?  It seems you're saying the script works, but only when the tables contain data.  I'm sure you meant something else.

0 Kudos
DougBrowning
MVP Esteemed Contributor

Why all these crazy import renames and such?  All you should need is this I think.

import arcpy
arcpy.env.workspace = "C:/data/Habitat_Analysis.gdb"
arcpy.CreateRelationshipClass_management("vegtype", "vegtable", "veg_RelClass", "SIMPLE",
"Attributes from vegtable", "Attributes and Features from vegtype",
"NONE", "ONE_TO_ONE", "NONE", "HOLLAND95", "HOLLAND95")

https://pro.arcgis.com/en/pro-app/latest/tool-reference/data-management/create-relationship-class.ht...

Hope that works

0 Kudos
RPGIS
by
Regular Contributor

I managed to get it to work after debugging it for quite some time. I know it is typically not suitable to rename imports but I was merely doing so to simplify copying and pasting as well as reducing the length of the module name since some modules have ridiculously long names.

0 Kudos