Skip to content

Commit

Permalink
Merge pull request #1106 from lsst/tickets/DM-46631
Browse files Browse the repository at this point in the history
DM-46631: fix replace=True on dimensions (etc) with only primary key columns
  • Loading branch information
TallJimbo authored Oct 23, 2024
2 parents ddf0c64 + e75146c commit 84471a8
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 0 deletions.
1 change: 1 addition & 0 deletions doc/changes/DM-46631.bugfix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix inserts with `replace=True` on dimensions with only primary key columns.
3 changes: 3 additions & 0 deletions python/lsst/daf/butler/registry/databases/postgresql.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
3 changes: 3 additions & 0 deletions python/lsst/daf/butler/registry/databases/sqlite.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
18 changes: 18 additions & 0 deletions python/lsst/daf/butler/registry/tests/_database.py
Original file line number Diff line number Diff line change
Expand Up @@ -685,6 +685,24 @@ def testReplace(self):
[r._asdict() for r in self.query_list(db, tables.a.select())], [row1, row2a, row3]
)

def test_replace_pkey_only(self):
"""Test `Database.replace` on a table that only has primary key"""
spec = ddl.TableSpec(
[
ddl.FieldSpec("a1", dtype=sqlalchemy.BigInteger, primaryKey=True),
ddl.FieldSpec("a2", dtype=sqlalchemy.BigInteger, primaryKey=True),
]
)
db = self.makeEmptyDatabase(origin=1)
with db.declareStaticTables(create=True) as context:
table = context.addTable("a", spec)
row1 = {"a1": 1, "a2": 2}
row2 = {"a1": 1, "a2": 3}
db.replace(table, row1)
db.replace(table, row2)
db.replace(table, row1)
self.assertCountEqual([r._asdict() for r in self.query_list(db, table.select())], [row1, row2])

def testEnsure(self):
"""Tests for `Database.ensure`."""
db = self.makeEmptyDatabase(origin=1)
Expand Down

0 comments on commit 84471a8

Please sign in to comment.