Skip to content

Commit 9787fb4

Browse files
varmar05wonder-sk
authored andcommitted
Save error in base schema comment if init failed + small tweaks for err messages (closes #46)
1 parent 2db35e7 commit 9787fb4

File tree

1 file changed

+68
-46
lines changed

1 file changed

+68
-46
lines changed

dbsync.py

Lines changed: 68 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)