mirror of
https://github.com/simonw/sqlite-utils.git
synced 2026-08-02 23:44:12 +02:00
ForeignKey is now a frozen dataclass, restoring hashability
The namedtuple-to-dataclass change made ForeignKey unhashable, breaking set(table.foreign_keys) and dict-key usage that worked in 3.x. frozen=True restores immutability and hashability. Equality and hashing cover all compared fields including on_delete/on_update - two foreign keys differing only in their actions are different constraints. Refs https://github.com/simonw/sqlite-utils/issues/769#issuecomment-4900034150 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
8e015d024c
commit
404e935b63
4 changed files with 51 additions and 8 deletions
|
|
@ -578,3 +578,35 @@ def test_add_compound_foreign_key_guesses_pk_declaration_order(fresh_db):
|
|||
fresh_db["child"].insert({"id": 1, "x": "A", "y": "B"}, pk="id")
|
||||
fresh_db["child"].add_foreign_key(("x", "y"), "other")
|
||||
assert fresh_db["child"].foreign_keys[0].other_columns == ("a", "b")
|
||||
|
||||
|
||||
def test_foreign_keys_are_hashable(fresh_db):
|
||||
# set() over foreign_keys worked with the 3.x namedtuple and must
|
||||
# keep working with the dataclass
|
||||
fresh_db["p"].insert({"id": 1}, pk="id")
|
||||
fresh_db["c"].insert(
|
||||
{"id": 1, "pid": 1}, pk="id", foreign_keys=[("pid", "p", "id")]
|
||||
)
|
||||
fks = set(fresh_db["c"].foreign_keys)
|
||||
assert len(fks) == 1
|
||||
assert ForeignKey("c", "pid", "p", "id") in fks
|
||||
# Usable as dict keys too
|
||||
assert {fk: True for fk in fks}
|
||||
|
||||
|
||||
def test_foreign_key_is_immutable():
|
||||
import dataclasses
|
||||
|
||||
fk = ForeignKey("c", "pid", "p", "id")
|
||||
with pytest.raises(dataclasses.FrozenInstanceError):
|
||||
fk.table = "other"
|
||||
|
||||
|
||||
def test_foreign_key_equality_and_hash_include_actions():
|
||||
# Two foreign keys differing only in ON DELETE behavior are different
|
||||
# constraints - they compare unequal and hash separately
|
||||
plain = ForeignKey("c", "pid", "p", "id")
|
||||
cascade = ForeignKey("c", "pid", "p", "id", on_delete="CASCADE")
|
||||
assert plain != cascade
|
||||
assert len({plain, cascade}) == 2
|
||||
assert plain == ForeignKey("c", "pid", "p", "id")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue