I am trying to automate a process to take a directory given by the user which contains a file geodatabase and zip it with only the relative path being retained. Intended output is a ZIP that contains just the final folder with the FGDB inside of it.
The workflow is to take a feature class from SQL SDE and use "Feature Class to Feature Class" tool to load desired data into the FGDB. Next perform the zip below. When running this it returns this message:
Traceback (most recent call last):
File "C:\arcgisserver\ETL_Scripts\Scripts\Zipdir.py", line 19, in <module>
zipdir(directory, zip)
File "C:\arcgisserver\ETL_Scripts\Scripts\Zipdir.py", line 13, in zipdir
ziph.write(os.path.relpath(os.path.join(root, file), os.path.join(path, '..')))
File "C:\Python27\ArcGIS10.2\Lib\zipfile.py", line 1033, in write
st = os.stat(filename)
WindowsError: [Error 3] The system cannot find the path specified: u'Output\\Output.gdb\\a00000001.freelist'
This folder remains unable to be zipped until I close out of ArcCatalog which removes the .lock file from within the .gdb. This isn't an acceptable workflow to have to do in order to perform the zip as this is 1 step of about 15+ that needs to be able to be published into a service for automation. The code below is what I am using that creates this issue. Thanks for any assistance.
import os, arcpy, zipfile
directory = arcpy.GetParameterAsText(0)
outputFile = arcpy.GetParameterAsText(1)
def zipdir(path, ziph):
#ziph is zipfile handle
for root, dirs, files in os.walk(path):
for file in files:
if not file.endswith('.lock'):
ziph.write(os.path.relpath(os.path.join(root, file), os.path.join(path, '..')))
if __name__ == '__main__':
zip = zipfile.ZipFile(outputFile, 'w', zipfile.ZIP_DEFLATED)
zipdir(directory, zip)
zip.close()
Sorry I don't have time to look at your issue specifically, but a couple things to try, and two variations to zip funtions (i've decided to use the zipws for the script I'm working on....zipping shapes in my case)
Below are two different zip function I've found and modified. I've using the second zip function one because if I set keep = False it will copy all my shapes to the "root" of the .zip. Otherwise it was always putting the files in a folder within my .zip, which would not work for my purposes.
# functions only
import time
import os
import arcpy
def myMsgs(message):
arcpy.AddMessage("{0}".format(message))
print("{0}".format(message))
import sys, zipfile
def zip(src, toZip):
#zf = zipfile.ZipFile("%s.zip" % (dst), "a", zipfile.ZIP_DEFLATED)
zf = zipfile.ZipFile("{0}a.zip".format(os.path.join(path,toZip)), "a", zipfile.ZIP_DEFLATED)
abs_src = os.path.abspath(src)
for dirname, subdirs, files in os.walk(src):
for filename in files:
absname = os.path.abspath(os.path.join(dirname, filename))
arcname = absname[len(abs_src) + 1:]
#print 'zipping %s as %s' % (os.path.join(dirname, filename), arcname)
myMsgs('zipping {0} as {1}'.format(filename, arcname))
zf.write(absname, arcname)
zf.close()
keep = False # keep = True puts files in "path folder", False puts files at root of .zip
def zipws(path, toZip, fcBase):
#zf = zipfile.ZipFile("%s.zip" % (toZip), "w", zipfile.ZIP_DEFLATED)
zf = zipfile.ZipFile("{0}.zip".format(os.path.join(toZip, fcBase)), "a", zipfile.ZIP_DEFLATED)
path = os.path.normpath(path)
# os.walk visits every subdirectory, returning a 3-tuple
# of directory name, subdirectories in it, and file names
# in it.
#
for (dirpath, dirnames, filenames) in os.walk(path):
# Iterate over every file name
#
for file in filenames:
# Ignore .lock files
#
if fcBase in file and not file.endswith('.lock'):
myMsgs("Adding {0}...".format(os.path.join(path, dirpath, file)))
try:
if keep:
zf.write(os.path.join(dirpath, file),
os.path.join(os.path.basename(path), os.path.join(dirpath, file)[len(path)+len(os.sep):]))
else:
zf.write(os.path.join(dirpath, file),
os.path.join(dirpath[len(path):], file))
except Exception, e:
arcpy.AddWarning(" Error adding {0}: {1}".format(file, e))
return None
Things to try anyway. I'm still working on my scripts, but those have been working for me for the zipping part of it. hope this helps.
Since file geodatabases are folders, are you looking to have two folders, the file geodatabase and its parent folder?
Right, I finally figured it all out. Part of my issues was the code I was using to get just the relpath and not the absolute path was off. After fixing that I still had the locking issue. To get around it I used copymanagement to replicate the fgdb into a different folder. The new replicated folder doesn't have the lock so then I zip that up and added a delete at the end of process to remove the copy making the folder ready for the next run.