Give phase 2 somewhere to record a tag's instance identity

OpenPrintTag derives an instance_uuid from the brand uuid plus the tag's
hardware UID, and phase 2 needs it stored so that rescanning a tag updates
the spool it already created instead of making a second one.

Added now, into the migration that has shipped to nobody, because the
table is the expensive half to change once it is populated on four
databases. Nothing writes the column yet, which is the same position
filament_id is already in.

Indexed for that lookup and deliberately not unique. uid already enforces
that one physical tag identifies one thing, and copying a tag's payload
onto a second sticker can legitimately put one instance identity on two
rows pointing at the same spool, which a unique constraint would reject.
This commit is contained in:
Donkie committed 2026-08-19 22:47:37 +02:00
1 parent 5b480f7db7
commit 9aea271ee5
2 files changed
+16

No files matched your search

@@ -39,6 +39,7 @@ def upgrade() -> None:
sa.Column("filament_id", sa.Integer(), nullable=True),
sa.Column("target_value", sa.String(length=64), nullable=True),
sa.Column("format", sa.String(length=32), nullable=True),
sa.Column("instance_uuid", sa.String(length=64), nullable=True),
sa.Column("added", sa.DateTime(), nullable=False),
sa.ForeignKeyConstraint(
["spool_id"],
@@ -59,10 +60,14 @@ def upgrade() -> None:
# The whole point of the table: one physical tag means exactly one thing, enforced by
# the database rather than by whichever client happened to write last.
op.create_index(op.f("ix_tag_uid"), "tag", ["uid"], unique=True)
# Not unique: see models.Tag. A payload copied onto a second sticker can carry one
# instance identity on two rows, both pointing at the same spool.
op.create_index(op.f("ix_tag_instance_uuid"), "tag", ["instance_uuid"], unique=False)
def downgrade() -> None:
"""Perform the downgrade."""
op.drop_index(op.f("ix_tag_instance_uuid"), table_name="tag")
op.drop_index(op.f("ix_tag_uid"), table_name="tag")
op.drop_index(op.f("ix_tag_filament_id"), table_name="tag")
op.drop_index(op.f("ix_tag_spool_id"), table_name="tag")
+11
View File
@@ -197,4 +197,15 @@ class Tag(Base):
# Free-ish string (openprinttag, ntag, bambu, ...) rather than an enum: informational
# in phase 1, and new tag types appear faster than migrations should.
format: Mapped[str | None] = mapped_column(String(32))
# Where phase 2 records a tag's decoded instance identity, so that rescanning a tag
# updates the spool it already created instead of making a second one. Nothing writes
# it yet -- it is here for the same reason the other unused columns are, that the
# table is the expensive half to change once it is populated on four databases, while
# the endpoint that fills it is additive and free.
#
# Indexed for that lookup and deliberately NOT unique. `uid` already enforces that one
# physical tag identifies one thing, and copying a tag's payload onto a second sticker
# (the case in the class docstring) can legitimately put one instance identity on two
# rows that point at the same spool -- which a unique constraint would reject.
instance_uuid: Mapped[str | None] = mapped_column(String(64), index=True)
added: Mapped[datetime] = mapped_column()