-
Notifications
You must be signed in to change notification settings - Fork 4
/
RPLib.py
2139 lines (1900 loc) · 97.1 KB
/
RPLib.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
from __future__ import print_function
import arcpy, smtplib, string, sys, time, os, httplib, urllib, json, getpass
import subprocess
from arcpy import env
from datetime import datetime
from email.mime.text import MIMEText
# pylint: disable-msg=C0103
# pylint: disable-msg=C0303
## email method variables
email_ON = False
email_To = ()
email_From = ""
email_Subject = ""
email_Msg = ""
email_IP = ""
email_Port = ""
email_Username = ""
email_Password = ""
## Logging variables
verboseLog = False
## recPost method variables
recpost_Log = ""
## createVersions method variables
createVersions_List = []
## Global log file location
global ScriptLog
global f
def Logger(Log_Loc="",):
global ScriptLog
global f
DATE = '%Y_%m_%d'
TIME = '%H_%M%p'
Script_Log = Log_Loc
if not Script_Log == "":
if arcpy.Exists(Script_Log):
ScriptLog = ("{0}//ScriptLog"
"_{1}_{2}.txt".format(Script_Log,
datetime.now().strftime(DATE),
datetime.now().strftime(TIME)))
f = open(ScriptLog, 'w')
f.close
f = open(ScriptLog, 'r+')
sys.stdout = Tee(sys.stdout, f)
else:
print("The specified path for storing the log file does not"
" exist!\n")
else:
print("A path for the log file location must be specified!\n")
class Tee(object):
def __init__(self, *files):
self.files = files
def write(self, obj):
for f in self.files:
f.write(obj)
f.flush()
def clearworkspacecache(Workspace = None,):
"""
**Clears any ArcSDE workspaces from the ArcSDE workspace cache.**
================== ======== ======================================================================================= =========
Parameter Type Description Required
================== ======== ======================================================================================= =========
**Workspace** String Path to SDE connection file. Yes
================== ======== ======================================================================================= =========
**Returns: Boolean**
"""
try:
if verifyworkspace(Workspace,"Clear Workspace Cache","Workspace"):
if verifysde(Workspace,"Clear Workspace Cache"):
prnt("Clearing workspace cache "
"for : {0} ... ".format(Workspace))
arcpy.ClearWorkspaceCache_management(Workspace)
success()
return True
else:
return False
else:
return False
except Exception, e:
failed()
Subject = " ERROR: Clear workspace cache"
Msg = " Error clearing workspace cache for {0}\n".format(Workspace)
print(Msg+"\n"+str(e))
if email_ON: email(Subject, Msg)
return False
def pauseconnections(Workspace = None,):
"""
**Allows an administrator to disable the ability of nonadministrative users to make connections to an enterprise geodatabase.**
================== ======== ======================================================================================= =========
Parameter Type Description Required
================== ======== ======================================================================================= =========
**Workspace** String Path to SDE connection file. Yes
================== ======== ======================================================================================= =========
**Returns: Boolean**
"""
# Process: block new connections to the database
try:
if verifyworkspace(Workspace,"Pause Connections","Workspace"):
if verifysde(Workspace,"Pause Connections"):
prnt( "Blocking new connections "
"for : {0} ... ".format(Workspace))
arcpy.AcceptConnections(Workspace, False)
success()
return True
else:
return False
else:
return False
except Exception, e:
failed()
Subject = "ERROR: Pause connections"
Msg = (
" An error occurred while trying to pause connections for {0}.\n"
" Please ensure the connection file provided has the required"
" permissions to pause database connections.\n Typically the sde"
" user handles connections to the database.\n If you were not"
" using a connection file that uses the sde username and password"
" please try using a connection file which does.".format(Workspace))
print(Msg+"\n"+" "+ str(e))
if email_ON: email(Subject, Msg)
return False
def resumeconnections(Workspace = None,):
"""
**Allows an administrator to enable the ability of nonadministrative users to make connections to an enterprise geodatabase.**
================== ======== ======================================================================================= =========
Parameter Type Description Required
================== ======== ======================================================================================= =========
**Workspace** String Path to SDE connection file. Yes
================== ======== ======================================================================================= =========
**Returns: Boolean**
"""
# Process: allow new connections to the database
try:
if verifyworkspace(Workspace,"Resume Connections","Workspace"):
if verifysde(Workspace,"Resume Connections"):
prnt( "Allowing new connections "
"for : {0} ... ".format(Workspace))
arcpy.AcceptConnections(Workspace, True)
success()
return True
else:
return False
else:
return False
except Exception, e:
failed()
Subject = "ERROR: Resume connections"
Msg = (" An error occurred while trying to resume connections"
" for {0}.\n Please ensure the connection file provided"
" has the required permissions to resume database connections.\n"
" Typically the sde user handles connections to the database.\n"
" If you were not using a connection file that uses the sde"
" username and password please try using a connection file"
" which does.".format(Workspace))
print(Msg + "\n" + " " + str(e))
if email_ON: email(Subject, Msg)
return False
def killconnections(Workspace = None,):
"""
**Allows an administrator to disconnect all users who are currently connected to an Enterprise geodatabase.**
================== ======== ======================================================================================= =========
Parameter Type Description Required
================== ======== ======================================================================================= =========
**Workspace** String Path to SDE connection file Yes
================== ======== ======================================================================================= =========
**Returns: Boolean**
"""
# Process: disconnect all users from the database.
try:
if verifyworkspace(Workspace,"Kill Connections","Workspace"):
if verifysde(Workspace,"Kill Connections"):
prnt( "Killing all connections "
"for : {0} ... ".format(Workspace))
arcpy.DisconnectUser(Workspace, "ALL")
success()
return True
else:
return False
else:
return False
except Exception, e:
failed()
Subject = " ERROR: Kill connections"
Msg = (" Error trying to kill connections for {0}.\n"
" Please ensure the connection file provided has the required"
" permissions to kill database connections.\n Typically the"
" sde user handles connections to the database.\n If you were"
" not using a connection file that uses the sde username and"
" password please try using a connection file which does."
"".format(Workspace))
print(Msg + "\n" + " " + str(e))
if email_ON: email(Subject, Msg)
return False
def compressgdb(Workspace = None,):
"""
**Compresses an enterprise geodatabase by removing states not referenced by a version and redundant rows.**
================== ======== ======================================================================================= =========
Parameter Type Description Required
================== ======== ======================================================================================= =========
**Workspace** String Path to SDE connection file. Yes
================== ======== ======================================================================================= =========
**Returns: Boolean**
"""
try:
if verifyworkspace(Workspace,"Compress Database","Workspace"):
if verifysde(Workspace,"Compress Database"):
prnt("Compressing geodatabase: {0} ... ".format(Workspace))
arcpy.Compress_management(Workspace)
success()
return True
else:
return False
else:
return False
except Exception, e:
failed()
Subject = " ERROR: Compressing geodatabase"
Msg = " Error compressing geodatabase {0}\n".format(Workspace)
print(Msg + "\n" + " " + str(e))
if email_ON: email(Subject, Msg)
return False
def createversions(Workspace = None,
Versions_List = [],
PublicAccess = True,
ParentVerion = None,):
"""
**Creates a new version(s) in the specified geodatabase.**
================== ======== ======================================================================================= ==========
Parameter Type Description Required
================== ======== ======================================================================================= ==========
**Workspace** String Path to SDE connection file . Yes
**Versions_List** List The name of the version(s) to be created. Yes
**PublicAccess** Boolean The permission access level for the version. No\n
* True = Public **(Default)**\n
* False = Private\n
* "PROTECTED" = Protected
**ParentVersion** String The geodatabase, or version of a geodatabase, on which the new version will be based. No\n
* None = "sde.default"\n
* "" = "sde.default"\n
================== ======== ======================================================================================= ==========
**Returns: Boolean**
"""
if verifyworkspace(Workspace,"Create Versions","Workspace"):
if verifysde(Workspace,"Create Versions"):
env.workspace = Workspace
else:
return False
else:
return False
if len(Versions_List) == 0:
Subject = " ERROR: Create versions"
Msg = (" Invalid expression supplied for parameter"
" Versions_List !\n The parameter cannot be an empty"
" list.\n Expected: List.\n Please provide a list"
" of version name(s) to be created.")
print(Msg)
if email_ON: email(Subject, Msg)
return False
else:
version_name = Versions_List
if PublicAccess == True:
access_permission = "PUBLIC"
elif PublicAccess == False:
access_permission = "PRIVATE"
elif PublicAccess == "PROTECTED":
access_permission = "PROTECTED"
else:
Subject = " ERROR: Create versions"
Msg = ("Invalid expression supplied for parameter PublicAccess !\n"
' Expected: True, False, or "PROTECTED" .\n'
" Received: {0}".format(PublicAccess))
print(Msg)
if email_ON: email(Subject, Msg)
return False
parent_version = ""
check_parent = ""
verList = []
if ParentVerion is None or len(ParentVerion) ==0:
parent_version = "sde.default"
else:
check_parent = str(ParentVerion)
check_parent = check_parent.lower()
for ver in arcpy.da.ListVersions():
if ver.isOwner == True and ver.name.lower() == check_parent:
parent_version = ParentVerion
verList = [ver.name for ver in arcpy.da.ListVersions()
if ver.isOwner == True and
ver.name.lower() != parent_version.lower()]
# convert Lists to strings for comparison
strverList = ''.join(verList)
newversions = []
existingversions = []
for version in version_name:
if not str(version) in strverList:
newversions.append(version)
else:
existingversions.append(version)
if not len(existingversions) == 0:
Subject = " ERROR: Create versions"
Msg = (" Unable to create verion(s) {0}, already"
" exist!".format(existingversions))
print(Msg)
if email_ON: email(Subject, Msg)
if not len(newversions) == 0:
for version in newversions:
try:
prnt( "Creating version : {0} ... ".format(version))
arcpy.CreateVersion_management(Workspace,
parent_version,
version,
access_permission)
success()
except Exception, e:
failed()
Subject = " Error: Create versions"
Msg = (" An error occurred while trying to create"
" versions for {0}.\n Please ensure the correct"
" connection file is being referenced and that"
" the user has permissions to create versions.\n"
" Does the parent version being referenced"
" exist?\n Is the correct string being passed"
" for PublicAccess?\n Please review the log file"
" for more detailed"
" information.".format(Workspace))
print(Msg + "\n" + " " + str(e))
if email_ON: email(Subject, Msg)
return False
return True
else:
Subject = " ERROR: Create versions"
Msg = (" No new versions were created.\n All versions"
" specified: {0} already exist! \n".format(version_name))
print(Msg)
if email_ON: email(Subject, Msg)
return False
def rebuild_indexes_analyze(Workspace = None,
excludeList = None,
include_system = False,
delta_only = True,
only_versioned = True,
analyze_base = True,
analyze_delta = True,
analyze_archive = True,):
"""
**Updates indexes of datasets and system tables stored in an enterprise geodatabase. Rebuilds existing attribute or spatial
indexes. Updates database statistics of base tables, delta tables, and archive tables, along with the statistics on those tables
indexes.**
=================== ======== ======================================================================================= ==========
Parameter Type Description Required
=================== ======== ======================================================================================= ==========
**Workspace** String Path to SDE connection file Yes
**excludeList** List List of object names to exclude from being processed. No
**include_system** Boolean Indicates whether statistics will be gathered on the states and state lineages tables. No\n
* True = SYSTEM\n
* False = NO_SYSTEM **(Default)**\n
**delta_only** Boolean Indicates how the indexes will be rebuilt on the selected datasets. No\n
* True = ONLY_DELTAS **(Default)**\n
* False = ALL\n
**only_versioned** Boolean Indicates if indexes will only be rebuilt for objects that are versioned. No\n
* True = Include only versioned objects. **(Default)**\n
* False = Include all database objects versioned and non-versioned.\n
**analyze_base** Boolean Indicates whether the selected dataset base tables will be analyzed. No\n
* True = ANALYZE_BASE **(Default)**\n
* False = NO_ANALYZE_BASE\n
**analyze_delta** Boolean Indicates whether the selected dataset delta tables will be analyzed. No\n
* True = ANALYZE_DELTA **(Default)**\n
* False = NO_ANALYZE_DELTA\n
**analyze_archive** Boolean Indicates whether the selected dataset delta tables will be analyzed. No\n
* True = ANALYZE_ARCHIVE **(Default)**\n
* False = NO_ANALYZE_ARCHIVE\n
=================== ======== ======================================================================================= ==========
**Returns: Boolean**
"""
if verifyworkspace(Workspace,"Rebuild Indexes Analyze","Workspace"):
if verifysde(Workspace,"Rebuild Indexes Analyze"):
env.workspace = Workspace
userName = arcpy.Describe(Workspace).connectionProperties.user
else:
return False
else:
return False
if excludeList is None:
excludeList = []
elif type(excludeList) is list:
xList = excludeList
else:
Subject = " ERROR: rebuild index analyze"
Msg = (" Invalid parameter found for excludeList !\n"
" Expected: List.\n"
" Please provide a list of objects in the geodatabse"
" that you do not wish to have included in this process.")
print(Msg)
if email_ON: email(Subject, Msg)
return False
if type(include_system) is bool:
if include_system is False:
include_system = "NO_SYSTEM"
else:
include_system = "SYSTEM"
else:
Subject = " ERROR: rebuild index analyze"
Msg = ("Invalid expression supplied for parameter include_system !\n"
' Expected: True or False .\n'
" Received: {0}".format(include_system))
print(Msg)
if email_ON: email(Subject, Msg)
return False
if type(delta_only) is bool:
if delta_only is False:
delta_only = "ALL"
else:
delta_only = "ONLY_DELTAS"
else:
Subject = " ERROR: rebuild index analyze"
Msg = ("Invalid expression supplied for parameter delta_only !\n"
' Expected: True or False .\n'
" Received: {0}".format(delta_only))
print(Msg)
if email_ON: email(Subject, Msg)
return False
if type(only_versioned) is bool:
pass
else:
Subject = " ERROR: rebuild index analyze"
Msg = ("Invalid expression supplied for parameter only_versioned !\n"
' Expected: True or False .\n'
" Received: {0}".format(delta_only))
print(Msg)
if email_ON: email(Subject, Msg)
return False
if type(analyze_base) is bool:
if analyze_base is False:
analyze_base = "NO_ANALYZE_BASE"
else:
analyze_base = "ANALYZE_BASE"
else:
Subject = " ERROR: rebuild index analyze"
Msg = ("Invalid expression supplied for parameter analyze_base !\n"
' Expected: True or False .\n'
" Received: {0}".format(delta_only))
print(Msg)
if email_ON: email(Subject, Msg)
return False
if type(analyze_delta) is bool:
if analyze_delta is False:
analyze_delta = "NO_ANALYZE_DELTA"
else:
analyze_delta = "ANALYZE_DELTA"
else:
Subject = " ERROR: rebuild index analyze"
Msg = ("Invalid expression supplied for parameter analyze_delta !\n"
' Expected: True or False .\n'
" Received: {0}".format(delta_only))
print(Msg)
if email_ON: email(Subject, Msg)
return False
if type(analyze_archive) is bool:
if analyze_archive is False:
analyze_archive = "NO_ANALYZE_ARCHIVE"
else:
analyze_archive = "ANALYZE_ARCHIVE"
else:
Subject = " ERROR: rebuild index analyze"
Msg = ("Invalid expression supplied for parameter analyze_archive !\n"
' Expected: True or False .\n'
" Received: {0}".format(delta_only))
print(Msg)
if email_ON: email(Subject, Msg)
return False
try:
prnt("Gathering list of database objects...")
# Types of objects that will processed.
ftypes = ['Table','FeatureClass','FeatureDataset']
# Tuple of Table and FeatureClass objects.
gdb_objects = []
# Tuple of FeatureDataSet objects
fds_objects = []
# Tuple of versioned Table and FeatureClass objects.
idx_objects = []
# Tuple of versioned FeatureDataSet objects
fidx_objects = []
# Use arcpy's data access module to walk the current workspace
# and gather all object specified in ftypes tuple.
for dirpath, dirnames, filenames in arcpy.da.Walk(Workspace,
followlinks=True,
datatype=ftypes):
# Loop through all objects in geodatabase and append them
# to the gdb_objects tuple.
for filename in filenames:
gdb_objects.append(filename)
# Loop through all objects in geodatabase and append them
# to the fds_objects if they are of type FeatureDataSet.
for dirname in dirnames:
fds_objects.append(dirname)
# Check to see that excludeList is not empty.
if not len(excludeList) == 0:
# If objects exist in excludeList compare them to gdb_objects.
# If a match is found remove the object from gdb_objects.
gdb_objects =[objects.upper() for objects
in gdb_objects if not any(exclude.upper()
for exclude in excludeList if exclude.upper()
in objects.upper())]
# If only_version is True
if only_versioned:
# Loop through gdb_objects
for obj in gdb_objects:
# For each object check to see if the object is versioned.
if arcpy.Describe(obj).Isversioned:
# If object is versioned add it to the idx_objects tuple.
idx_objects.append(obj)
# Loop through FeatureDataSet objects
for obj in fds_objects:
# For each object check to see if the object is versioned.
if arcpy.Describe(obj).Isversioned:
# If object is versioned add it to the fidx_objects tuple.
fidx_objects.append(obj)
# If verbose logging is True show arcpy.Messages.
# If False print success on same line.
success()
except Exception, e:
failed()
Subject = " Error: rebuild index analyze"
Msg = (
" An error occurred while trying to gather objects"
" for workspace: {0}.\n Please ensure the correct connection file"
" is being referenced".format(Workspace))
print(Msg + "\n" + " " + str(e))
if email_ON: email(Subject, Msg)
return False
# If only_versioned is True.
if only_versioned:
# Set initial objects to only versioned objects
gdb_objects = idx_objects
fds_objects = fidx_objects
# Check to ensure the tuple is not empty.
if not len(gdb_objects) == 0:
prnt(" Beginning Rebuilding Indexes for FeatureClasses and"
" Tables for user: {0} ... ".format(userName))
try:
# Call Esri tool to rebuild indexes on all gdb_objects
arcpy.RebuildIndexes_management(Workspace,
include_system,
gdb_objects,
delta_only)
success()
# Check to ensure fds_objects is not empty.
if not len(fds_objects) == 0:
prnt( " Begin Analyzing FeatureDataSets"
" for user: {0} ... ".format(userName))
# Call Esri tool to analyze Featuredatasets in fds_objects.
arcpy.AnalyzeDatasets_management(Workspace,
include_system,
fds_objects,
analyze_base,
analyze_delta,
analyze_archive)
success()
except Exception, e:
failed()
# The initial tools failed because of a permissions issue.
# This will try to rerun the tools with less permissions.
if "000684" in str(e):
print(" User does not have permissions to work with"
" system tables\n")
try:
prnt(" TRYING WITHOUT SYSTEM TABLES!!! Beginning"
" Rebuilding Indexes for FeatureClasses and"
" Tables for user: {0} ... ".format(userName))
arcpy.RebuildIndexes_management(Workspace,
"NO_SYSTEM",
gdb_objects,
"ALL")
success()
if not len(fds_objects) == 0:
prnt( " TRYING WITHOUT SYSTEM TABLES!!! Begin"
" Analyzing FeatureDataSets for user:"
" {0} ... ".format(userName))
arcpy.AnalyzeDatasets_management(Workspace,
"NO_SYSTEM",
fds_objects,
analyze_base,
analyze_delta,
analyze_archive)
success()
return True
except Exception, e:
failed()
Subject = " ERROR: rebuild_indexes_analyze"
Msg = (" Rebuild Index and Analyze without system"
" table failed for: {0}\n".format(Workspace))
print(Msg + "\n" + " " + str(e))
if email_ON: email(Subject, Msg)
return False
else:
print(" No FeatueClasses or Tables were found"
" for user: {0}".format(userName))
def reconcilepost(Workspace = None,
log_folder = None,
versions = None,
parent_version = None,
delete_version = True,
all_versions = True,
acquire_locks = True,
abort_if_conflicts = True,
by_object = True,
favor_target = True,
post = True,):
"""
**Reconciles a version or multiple versions against a target version.**
====================== ======== =============================================================================================================================================================================================================================================== ==========
Parameter Type Description Required
====================== ======== =============================================================================================================================================================================================================================================== ==========
**Workspace** String Path to SDE connection file. Yes
**log_folder** String Path to folder where log file(s) will be stored. Yes
**versions** List List of version names to be reconciled and posted. No\n
**parent_version** String The geodatabase, or version of a geodatabase, which owns the version(s). No\n
* None = "sde.default" **(Default)**\n
* "" = "sde.default"\n
**delete_version** Boolean Indicates if versions will be deleted after posting to target version. No\n
* True = Delete version after posting to target version. **(Default)**\n
* False = Keep version after posting to target version.\n
**all_versions** Boolean Determines which versions will be reconciled when the tool is executed. No\n
* True = Reconciles edit versions with the target version. **(Default)**\n
* False = Reconciles versions that are blocking the target version from compressing.\n
**acquire_locks** Boolean Determines whether feature locks will be acquired. No\n
* True = Should be used when the intention is to post edits. **(Default)**\n
* False = Should be used when the edit version will not be posted to the target version.
**abort_if_conflicts** Boolean Reconcile will be aborted if conflicts are found between versions. No\n
* True = Aborts the reconcile if conflicts are found. **(Default)**\n
* False = Does not abort the reconcile if conflicts are found.
**by_object** Boolean Describes the conditions required for a conflict to occur. No\n
* True = Any changes to the same row or feature in the parent and child versions will conflict during reconcile. **(Default)**\n
* False = Only changes to the same attribute of the same row or feature in the parent and child versions will be flagged as a conflict during reconcile. Changes to different attributes will not be considered a conflict during reconcile.\n
**favor_target** Boolean Describes the behavior if a conflict is detected. No\n
* True = Resolve in favor of the target version. **(Default)**\n
* False = Resolve in favor of the edit version.\n
**post** Boolean Posts the current edit session to the reconciled target version. No\n
* True = Version will be posted to the target version after the reconcile. **(Default)**\n
* False = Version will not be posted to the target version after the reconcile.
====================== ======== =============================================================================================================================================================================================================================================== ==========
**Returns: Boolean**
"""
if verifyworkspace(Workspace,"Reconcile and Post","Workspace"):
if verifysde(Workspace,"Reconcile and Post"):
env.workspace = Workspace
else:
return False
else:
return False
# parameter check reconcilepost log_folder
if (log_folder == None
or len(log_folder) == 0
and type(log_folder) is str
):
recPost_Log = ""
print("None or empty string found")
if type(log_folder) is str and arcpy.Exists(log_folder):
recPost_Log = log_folder
# remove any trailing or leading spaces
recPost_Log = recPost_Log.strip()
else:
Subject = " ERROR: reconcile and post"
Msg = ("Invalid expression supplied for parameter log_folder !\n"
" The folder location {0} cannot be found.\n"
" Expected: String.\n"
" Please provide a valid path to a folder.".format(log_folder))
print(Msg)
if email_ON: email(Subject, Msg)
return False
# paramter check reconcilepost target_version
if parent_version is None or len(parent_version) == 0:
target_version = "sde.default"
elif type(parent_version) is str and len(parent_version) != 0:
target_version = str(parent_version)
target_version = target_version.lower()
else:
Subject = " ERROR: reconcile and post"
Msg = ("Invalid expression supplied for parameter parent_version !\n"
" Expected: String\n"
" Received: {0}\n"
" Please provide the name of the"
" parent/target version as a string.".format(parent_version))
print(Msg)
if email_ON: email(Subject, Msg)
return False
# paramter check reconcilepost target_version
# check to ensure parent version exist.
for ver in arcpy.da.ListVersions():
if ver.isOwner == True and ver.name.lower() == target_version.lower():
target_version = parent_version
#print("found target version")
# Deprecated code, does not work with other logic
## if len(target_version) == 0:
## Subject = " ERROR: reconcile and post"
## Msg = ("Invalid expression supplied for parameter parent_version !\n"
## " The parent_version specified does not exist or could not"
## " be found: {0}".format(parent_version))
## print(Msg)
## if email_ON: email(Subject, Msg)
## return False
# parameter check reconcilepost edit_versions
if (versions == None or len(versions) == 0 or versions == "" ):
edit_versions = [ver.name for ver in arcpy.da.ListVersions()
if ver.isOwner == True
and ver.name.lower() != target_version.lower()]
#print("Edit versions are: {0}".format(edit_versions))
if len(edit_versions) == 0:
Subject = " ERROR: reconcile and post"
Msg = ("Reconcile process was not performed !\n"
" The specified target version ({0}) has no edit versions"
" to reconcile with.".format(target_version))
print(Msg)
if email_ON: email(Subject, Msg)
return False
elif type(versions) is list and len(versions) != 0:
edit_versions = versions
else:
Subject = " ERROR: reconcile and post"
Msg = ("Invalid expression supplied for parameter versions !\n"
" Expected: List\n"
" Received: {0}\n"
" Please provide a valid list of"
" version names.".format(versions))
print(Msg)
if email_ON: email(Subject, Msg)
return False
# parameter check reconcilepost delete_version
if type(delete_version) is bool:
if delete_version is False:
with_delete = "KEEP_VERSION"
else:
with_delete = "DELETE_VERSION"
else:
Subject = " ERROR: reconcile and post"
Msg = ("Invalid expression supplied for parameter delete_version !\n"
' Expected: True or False .\n'
" Received: {0}".format(delete_version))
print(Msg)
if email_ON: email(Subject, Msg)
return False
# parameter check reconcilepost all_versions
if type(all_versions) is bool:
if all_versions is False:
reconcile_mode = "BLOCKING_VERSIONS"
else:
reconcile_mode = "ALL_VERSIONS"
else:
Subject = " ERROR: reconcile and post"
Msg = ("Invalid expression supplied for parameter all_versions !\n"
' Expected: True or False .\n'
" Received: {0}".format(all_versions))
print(Msg)
if email_ON: email(Subject, Msg)
return False
# parameter check reconcilepost acquire_locks
if type(acquire_locks) is bool:
if acquire_locks is False:
acquire_locks = "NO_LOCK_ACQUIRED"
else:
acquire_locks = "LOCK_ACQUIRED"
else:
Subject = " ERROR: reconcile and post"
Msg = ("Invalid expression supplied for parameter acquire_locks !\n"
' Expected: True or False .\n'
" Received: {0}".format(acquire_locks))
print(Msg)
if email_ON: email(Subject, Msg)
return False
# parameter check reconcilepost abort_if_conflicts
if type(abort_if_conflicts) is bool:
if abort_if_conflicts is False:
abort_if_conflicts = "NO_ABORT"
else:
abort_if_conflicts = "ABORT_CONFLICTS"
else:
Subject = " ERROR: reconcile and post"
Msg = ("Invalid expression supplied for parameter"
" abort_if_conflicts !\n"
" Expected: True or False .\n"
" Received: {0}".format(abort_if_conflicts))
print(Msg)
if email_ON: email(Subject, Msg)
return False
# parameter check reconcilepost by_object
if type(by_object) is bool:
if by_object is False:
conflict_definition = "BY_ATTRIBUTE"
else:
conflict_definition = "BY_OBJECT"
else:
Subject = " ERROR: reconcile and post"
Msg = ("Invalid expression supplied for parameter by_object !\n"
' Expected: True or False .\n'
" Received: {0}".format(by_object))
print(Msg)
if email_ON: email(Subject, Msg)
return False
# parameter check reconcilepost favor_target
if type(favor_target) is bool:
if favor_target is False:
conflict_resolution = "FAVOR_EDIT_VERSION"
else:
conflict_resolution = "FAVOR_TARGET_VERSION"
else:
Subject = " ERROR: reconcile and post"
Msg = ("Invalid expression supplied for parameter favor_target !\n"
' Expected: True or False .\n'
" Received: {0}".format(favor_target))
print(Msg)
if email_ON: email(Subject, Msg)
return False
# parameter check reconcilepost post
if type(post) is bool:
if post is False:
with_post = "NO_POST"
else:
with_post = "POST"
else:
Subject = " ERROR: reconcile and post"
Msg = ("Invalid expression supplied for parameter post !\n"
' Expected: True or False .\n'
" Received: {0}".format(post))
print(Msg)
if email_ON: email(Subject, Msg)
return False
DATE = '%Y_%m_%d'
TIME = '%H_%M%p'
out_log = ("{0}/RecPostProcess"
"_{1}_{2}.txt".format(recPost_Log,
datetime.now().strftime(DATE),
datetime.now().strftime(TIME)))
#print(out_log)
#print(edit_versions)
# Reconcile, Abort if conflicts are found, keep all versions, write
# output to logfile
print("Begin reconciling all versions"
" {0}\n".format(datetime.now().strftime(TIME)))
try:
prnt("Attempting to Reconcile and Post Versions...")
arcpy.ReconcileVersions_management(Workspace,
reconcile_mode,
target_version,
edit_versions,
acquire_locks,
abort_if_conflicts,
conflict_definition,
conflict_resolution,
with_post,
"KEEP_VERSION",
out_log)
# Process: Check if conflicts exist
conflicts = arcpy.GetMessages(1)
# If this error arises, there were conflicts in one or more
# of the # versions.
if "000084" in conflicts:
# Process: Read Contents of out_log so it can be added to
# email.
log_file = open(out_log, 'rb')
TEXT = MIMEText(log_file.read())
log_file.close()
detailed_string = ("\n An error occurred while Reconciling,"
" Posting all versions, The first"
" Reconcile and Post operation found"
" conflicts. Please review and fix the"
" conflicts and try again.")
Subject = " ERROR: Reconcile and Post Conflicts"
# Append contents of out_log to email message
Msg = (" {0}\n A conflict was found for: {1}\n"
" {2}".format(TEXT,Workspace,detailed_string))
print(Msg)
failed()
if email_ON: email(Subject, Msg)
return False
else:
success()
# This assumes the reconcile and post process was
# successful.
# Reconcile, Abort if conflicts are found, delete all
# versions since no conflicts were found in previous
# reconcile, do not write to log file
if delete_version:
try:
prnt("Reconciling, Posting, and Deleting All"
" Versions... ")
arcpy.ReconcileVersions_management(Workspace,
reconcile_mode,
target_version,
edit_versions,
acquire_locks,
abort_if_conflicts,
conflict_definition,
conflict_resolution,
with_post,
with_delete)
success()
log_file = open(out_log, 'rb')
TEXT = MIMEText(log_file.read())
log_file.close()
Subject = (" Success: Reconcile, Post, and"
" Delete Versions")
Msg = ("{0}\n"
" Reconciling, Posting, and Deleting all"
" versions was successful".format(TEXT))
if email_ON: email(Subject, Msg)
return True
except Exception, e:
failed()