@@ -242,12 +242,16 @@ def _get_project_version():
242242 return mp .metadata ["version" ]
243243
244244
245- def _set_db_project_comment (conn , schema , project_name , version ):
246- """ Set postgres COMMENT on SCHEMA with mergin project name and version """
245+ def _set_db_project_comment (conn , schema , project_name , version , error = None ):
246+ """ Set postgres COMMENT on SCHEMA with mergin project name and version
247+ or eventually error message if initialisation failed
248+ """
247249 comment = {
248250 "name" : project_name ,
249- "version" : version
251+ "version" : version ,
250252 }
253+ if error :
254+ comment ["error" ] = error
251255 cur = conn .cursor ()
252256 query = sql .SQL ("COMMENT ON SCHEMA {} IS %s" ).format (sql .Identifier (schema ))
253257 cur .execute (query .as_string (conn ), (json .dumps (comment ), ))
@@ -514,6 +518,13 @@ def dbsync_init(mc, from_gpkg=True):
514518 db_proj_info = _get_db_project_comment (conn , config .db_schema_base )
515519 if not db_proj_info :
516520 raise DbSyncError ("Base schema exists but missing which project it belongs to" )
521+ if "error" in db_proj_info :
522+ changes_gpkg_base = _compare_datasets ("sqlite" , "" , gpkg_full_path , config .db_driver ,
523+ config .db_conn_info , config .db_schema_base ,
524+ summary_only = False )
525+ changes = json .dumps (changes_gpkg_base , indent = 2 )
526+ print (f"Changeset from failed init:\n { changes } " )
527+ raise DbSyncError (db_proj_info ["error" ])
517528
518529 # make sure working directory contains the same version of project
519530 if not os .path .exists (config .project_working_dir ):
@@ -539,6 +550,7 @@ def dbsync_init(mc, from_gpkg=True):
539550
540551 # make sure we have working directory now
541552 _check_has_working_dir ()
553+ local_version = _get_project_version ()
542554
543555 # check there are no pending changes on server (or locally - which should never happen)
544556 status_pull , status_push , _ = mc .project_status (config .project_working_dir )
@@ -559,7 +571,7 @@ def dbsync_init(mc, from_gpkg=True):
559571 config .db_conn_info , config .db_schema_base )
560572 if len (summary_base ):
561573 # seems someone modified base schema manually - this should never happen!
562- print (f"Local project version at { _get_project_version () } and base schema at { db_proj_info ['version' ]} " )
574+ print (f"Local project version at { local_version } and base schema at { db_proj_info ['version' ]} " )
563575 _print_changes_summary (summary_base , "Base schema changes:" )
564576 raise DbSyncError ("The db schemas already exist but 'base' schema is not synchronized with source GPKG" )
565577 elif len (summary_modified ):
@@ -576,29 +588,34 @@ def dbsync_init(mc, from_gpkg=True):
576588
577589 # initialize: we have an existing GeoPackage in our Mergin project and we want to initialize database
578590 print ("The base and modified schemas do not exist yet, going to initialize them ..." )
579- # COPY: gpkg -> modified
580- _geodiff_make_copy ("sqlite" , "" , gpkg_full_path ,
581- config .db_driver , config .db_conn_info , config .db_schema_modified )
582-
583- # COPY: modified -> base
584- _geodiff_make_copy (config .db_driver , config .db_conn_info , config .db_schema_modified ,
585- config .db_driver , config .db_conn_info , config .db_schema_base )
586-
587- # sanity check to verify that right after initialization we do not have any changes
588- # between the 'base' schema and the geopackage in Mergin project, to make sure that
589- # copying data back and forth will keep data intact
590- changes_gpkg_base = _compare_datasets ("sqlite" , "" , gpkg_full_path , config .db_driver ,
591- config .db_conn_info , config .db_schema_base ,
592- summary_only = False )
593- if len (changes_gpkg_base ):
594- changes = json .dumps (changes_gpkg_base , indent = 2 )
595- raise DbSyncError ("Initialization of db-sync failed due to a bug in geodiff: "
596- "base schema and gpkg do not match. Please report this problem "
597- "to mergin-db-sync developers. Changeset (should be empty):\n " + changes )
598-
599- # mark project version into db schema
600- version = _get_project_version ()
601- _set_db_project_comment (conn , config .db_schema_base , config .mergin_project_name , version )
591+ try :
592+ # COPY: gpkg -> modified
593+ _geodiff_make_copy ("sqlite" , "" , gpkg_full_path ,
594+ config .db_driver , config .db_conn_info , config .db_schema_modified )
595+
596+ # COPY: modified -> base
597+ _geodiff_make_copy (config .db_driver , config .db_conn_info , config .db_schema_modified ,
598+ config .db_driver , config .db_conn_info , config .db_schema_base )
599+
600+ # sanity check to verify that right after initialization we do not have any changes
601+ # between the 'base' schema and the geopackage in Mergin project, to make sure that
602+ # copying data back and forth will keep data intact
603+ changes_gpkg_base = _compare_datasets ("sqlite" , "" , gpkg_full_path , config .db_driver ,
604+ config .db_conn_info , config .db_schema_base ,
605+ summary_only = False )
606+ # mark project version into db schema
607+ if len (changes_gpkg_base ):
608+ changes = json .dumps (changes_gpkg_base , indent = 2 )
609+ print (f"Changeset after internal copy (should be empty):\n { changes } " )
610+ raise DbSyncError
611+ except DbSyncError :
612+ # add comment to base schema before throwing exception
613+ _set_db_project_comment (conn , config .db_schema_base , config .mergin_project_name , local_version ,
614+ error = 'Initialization of db-sync failed due to a bug in geodiff.\n '
615+ 'Please report this problem to mergin-db-sync developers' )
616+ raise
617+
618+ _set_db_project_comment (conn , config .db_schema_base , config .mergin_project_name , local_version )
602619 else :
603620 if not modified_schema_exists :
604621 raise DbSyncError ("The 'modified' schema does not exist: " + config .db_schema_modified )
@@ -629,25 +646,30 @@ def dbsync_init(mc, from_gpkg=True):
629646 # initialize: we have an existing schema in database with tables and we want to initialize geopackage
630647 # within our Mergin project
631648 print ("The base schema and the output GPKG do not exist yet, going to initialize them ..." )
632- # COPY: modified -> base
633- _geodiff_make_copy (config .db_driver , config .db_conn_info , config .db_schema_modified ,
634- config .db_driver , config .db_conn_info , config .db_schema_base )
635-
636- # COPY: modified -> gpkg
637- _geodiff_make_copy (config .db_driver , config .db_conn_info , config .db_schema_modified ,
638- "sqlite" , "" , gpkg_full_path )
639-
640- # sanity check to verify that right after initialization we do not have any changes
641- # between the 'base' schema and the geopackage in Mergin project, to make sure that
642- # copying data back and forth will keep data intact
643- changes_gpkg_base = _compare_datasets ("sqlite" , "" , gpkg_full_path , config .db_driver ,
644- config .db_conn_info , config .db_schema_base ,
645- summary_only = False )
646- if len (changes_gpkg_base ):
647- changes = json .dumps (changes_gpkg_base , indent = 2 )
648- raise DbSyncError ("Initialization of db-sync failed due to a bug in geodiff: "
649- "base schema and gpkg do not match. Please report this problem "
650- "to mergin-db-sync developers. Changeset (should be empty):\n " + changes )
649+ try :
650+ # COPY: modified -> base
651+ _geodiff_make_copy (config .db_driver , config .db_conn_info , config .db_schema_modified ,
652+ config .db_driver , config .db_conn_info , config .db_schema_base )
653+
654+ # COPY: modified -> gpkg
655+ _geodiff_make_copy (config .db_driver , config .db_conn_info , config .db_schema_modified ,
656+ "sqlite" , "" , gpkg_full_path )
657+
658+ # sanity check to verify that right after initialization we do not have any changes
659+ # between the 'base' schema and the geopackage in Mergin project, to make sure that
660+ # copying data back and forth will keep data intact
661+ changes_gpkg_base = _compare_datasets ("sqlite" , "" , gpkg_full_path , config .db_driver ,
662+ config .db_conn_info , config .db_schema_base ,
663+ summary_only = False )
664+ if len (changes_gpkg_base ):
665+ changes = json .dumps (changes_gpkg_base , indent = 2 )
666+ print (f"Changeset after internal copy (should be empty):\n { changes } " )
667+ raise DbSyncError
668+ except DbSyncError :
669+ _set_db_project_comment (conn , config .db_schema_base , config .mergin_project_name , local_version ,
670+ error = 'Initialization of db-sync failed due to a bug in geodiff.\n '
671+ 'Please report this problem to mergin-db-sync developers' )
672+ raise
651673
652674 # upload gpkg to mergin (client takes care of storing metadata)
653675 mc .push_project (config .project_working_dir )
0 commit comments