Automating appending to web layer in python

791
5
02-03-2023 03:52 PM
Labels (2)
KitTompkins
New Contributor II

I've been trying to automate updating my organizations web-layers so i don't have to do it automatically, but I was having trouble making a model work so I decided to try moving it to python.

I have a geodatabase with all the files I want to use as sources, and the feature layers they match to all have the same name, so it should be easy to match them.

I have written this code, which runs fine until it get to the second for loop. Before I added the second for loop it actually ran with no errors but returned nothing. I have walked step by step through the code and the problem seems to be that it gets to the feature datasets, but then at ListFeatureClasses, it always returns null, even though all the datasets are full of feature classes. 

I tried to use arcpy.da.Walk and pycharm says there is no such reference in arcpy.da and I can't even find any info on why that would be.

I feel like once I can get the data in properly, doing the truncate and append with be easy, but I'd need to get there first.

 

import arcpy
import os

workspace = r'D:\Master_GIS_Files\Data\Florence\Utilities\FlorenceUtilities.gdb'


def FCIterator():
    with arcpy.EnvManager(workspace=workspace):
        fdl= arcpy.ListDatasets()
        featureclasses = arcpy.ListFeatureClasses(fdl)
    for fds in fdl:
        featureclasses.extend(arcpy.ListDatasets(fds))
        for fc in arcpy.ListFeatureClasses(fds):
            yield os.path.join(workspace, fds, fc), fc


def GetWebLayer(name):
    from arcgis.gis import GIS
    gis = GIS('https://city-of-florence.maps.arcgis.com/home', username="KitFlorence", password="Thorne!Florence27")
    ttl = f"title:*{name}"
    q = ttl + 'AND item_type="Feature Layer" AND "owner:' + gis.users.me.username + r'"'
    fLayerz = [f for f in gis.content.search(query=q)][0]
    if fLayerz:
        fLayer = fLayerz[0]
        flID = str(fLayer.id)
        return flID
    else:
        pass

for path, Fname in FCIterator():
    lID = GetWebLayer(Fname)
    print(path, Fname)
    print(lID)

 

 

0 Kudos
5 Replies
JoshuaSharp-Heward
Occasional Contributor III

I'd start by putting some print statements in there and making sure the two functions you've defined actually work independently as you're intending them to work. Also when initiating a list (line 9) you don't need the "", just do [].

Are your feature classes all within feature datasets in your geodatabase? Because if not I don't think the FCIterator would return anything.

Also out of curiosity how many layers are you wanting to update in AGOL via this script? If it's fewer than 20 it may be simpler to just create a dictionary of fc names and associated AGOL itemID's to avoid relying on the gis.content.search query return the correct item as in my experience it doesn't always return what you would expect.

0 Kudos
KitTompkins
New Contributor II

I figured out what part of the problem is at least by using to Pycharm to step through the code. It finds the feature datasets fine, but returns the list featureclasses as none even though I can see about 12 of them in each dataset. 

At this point I suppose it might be quicker to create a dictionary but also increeedibly tedious, and I want to figure out why this doesn't work, since it should.

Update: I got this part of the code to work by using arcpy. describe instead of list featureclasses, so I think ListFeatureClasses is bugged.

Now I just have to figure out why it says the content owned by me is none lol

0 Kudos
JoshuaSharp-Heward
Occasional Contributor III

Yeah getting the query right is often difficult in my experience. You might want to bring "item_type" out of the query and just add it to the gis.content.search() parameters to remove one of the potential variables that could be going wrong. I'd also try to just print out that query to make sure the string is being formatted correctly, at a glance I'm not sure the "" around the owner:username section is right as it doesn't seem to match the query examples on the API reference page. If you are still struggling you could fetch a list of your items by using user.items() instead, although that is less ideal.

0 Kudos
OrrGvili
New Contributor III

try using ListFeatureClasses example from the page 

it works for me evry time

 

0 Kudos
Janeer
by
New Contributor

I like ListFeatureClasses function. It takes a number of optional parameters, including wild_card, which allows the user to filter the list of feature classes by a specific search pattern. Additionally, the function returns a list of strings, which makes it easy to iterate over and manipulate the resulting feature class names in subsequent code.

productivity program view

0 Kudos