"""
A tool to merge one or more geodatabases of matching schema into a single
geodatabase. Source and target geodatabases can be local (file) geodatabases or
ArcSDE database connections. Any datasets or feature classes that do not match
the target schema will be ignored. Duplicate data will be persisted if present
(duplicate features will not be removed).
"""

import arcpy
import os
import time

START = time.time()

#### SET THESE VARIABLES BEFORE USING ####
model_path = "" # path to target geodatabase - schema should match that of input geodatabase(s)
paths_to_load = [""] # list of (str) paths to input geodatabase(s)

def list_layers(gdb):
    """
        Creates a list of feature classes in current workspace with full paths
        (including path to parent geodatabase). Returns list of layers.
    """
    print("\nGenerating layer list...")
    lyrs = []
    for ds in arcpy.ListDatasets():
        for fc in arcpy.ListFeatureClasses(feature_dataset = ds):
            fullpath = os.path.join(gdb, ds, fc)
            lyrs.append(fullpath)
    return lyrs

if __name__ == "__main__":
    for gdb in paths_to_load:
        arcpy.env.workspace = gdb

        print("***Beginning processing for {0}***".format(gdb))
        lyrs = list_layers(gdb)

        for lyr in lyrs:
            fc = os.path.basename(lyr)
            ds = os.path.basename(os.path.dirname(lyr))
                # if no dataset (i.e., fc is in root of geodatabase) then
                # ds = empty string
            target = os.path.join(model_path, ds, fc)
                # if ds = '' then join correctly ignores

            try:
            # append lyr to model_path/<ds>/<fc>
                arcpy.Append_management(lyr, target)
                print("Appended: {0}".format(target))
                with open ("appended_layers.txt", "a") as txt:
                    txt.write("{0}\n".format(lyr))
            except arcpy.ExecuteError as e:
                if "000732" in e:
                    pass
                    # target does not contain this feature class name
                    # TODO copy entire source layer to target?
                else:
                    # log failed attempts to append (e.g., non-matching schemas)
                    with open ("append_errors.txt", "a") as txt:
                        txt.write("***Failed to append {0}\n\t{1}\n".format(lyr, e))
                print(e)
                pass

    END = time.time()
    print("***Processing complete: time elapsed = {0} seconds***".format(END-START))
