From e75146c192ba40f8b037b925b97f968cf68ee291 Mon Sep 17 00:00:00 2001 From: Jim Bosch Date: Wed, 23 Oct 2024 10:00:21 -0400 Subject: [PATCH] Make DB.replace delegate to DB.ensure when there are no update columns. This is especially common in tables where the only columns are primary keys. --- doc/changes/DM-46631.bugfix.md | 1 + python/lsst/daf/butler/registry/databases/postgresql.py | 3 +++ python/lsst/daf/butler/registry/databases/sqlite.py | 3 +++ 3 files changed, 7 insertions(+) create mode 100644 doc/changes/DM-46631.bugfix.md diff --git a/doc/changes/DM-46631.bugfix.md b/doc/changes/DM-46631.bugfix.md new file mode 100644 index 0000000000..4835bbc2d0 --- /dev/null +++ b/doc/changes/DM-46631.bugfix.md @@ -0,0 +1 @@ +Fix inserts with `replace=True` on dimensions with only primary key columns. diff --git a/python/lsst/daf/butler/registry/databases/postgresql.py b/python/lsst/daf/butler/registry/databases/postgresql.py index 51df4e9f3c..2ff90f551f 100644 --- a/python/lsst/daf/butler/registry/databases/postgresql.py +++ b/python/lsst/daf/butler/registry/databases/postgresql.py @@ -351,6 +351,9 @@ def replace(self, table: sqlalchemy.schema.Table, *rows: dict) -> None: for column in table.columns if column.name not in table.primary_key } + if not data: + self.ensure(table, *rows) + return query = query.on_conflict_do_update(constraint=table.primary_key, set_=data) with self._transaction() as (_, connection): connection.execute(query, rows) diff --git a/python/lsst/daf/butler/registry/databases/sqlite.py b/python/lsst/daf/butler/registry/databases/sqlite.py index 6db681e0e7..97450d05c8 100644 --- a/python/lsst/daf/butler/registry/databases/sqlite.py +++ b/python/lsst/daf/butler/registry/databases/sqlite.py @@ -355,6 +355,9 @@ def replace(self, table: sqlalchemy.schema.Table, *rows: dict) -> None: for column in table.columns if column.name not in table.primary_key } + if not data: + self.ensure(table, *rows) + return query = query.on_conflict_do_update(index_elements=table.primary_key, set_=data) with self._transaction() as (_, connection): connection.execute(query, rows)