Widen messages.signature to String(32) for Postgres

The column was declared String(8) but stores 16-char hex signatures (and can
hold the up-to-32-char packet_hash fallback from the LetsMesh normalizer).
SQLite never enforced the length, so the undersized definition went unnoticed
until db migrate-to-postgres rejected the data with
StringDataRightTruncation (varchar(8)). Widen the model column and add an
Alembic migration (batch_alter_table, so it applies on both SQLite and
Postgres). Verified end-to-end migrating a 1.2GB live SQLite DB into Postgres
(all 12 tables reconcile).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Louis King
2026-06-14 09:17:53 +01:00
parent ae700c45fa
commit 1c04baec7d
2 changed files with 44 additions and 2 deletions
@@ -0,0 +1,42 @@
"""widen messages.signature to 32 chars
Revision ID: d4e5f6a7b8c9
Revises: c3d4e5f6a7b8
Create Date: 2026-06-14 09:15:00.000000+00:00
The column was declared String(8) but actually stores 16-char hex signatures
(and can hold the up-to-32-char packet_hash fallback). SQLite never enforced the
length, so the undersized definition went unnoticed until a Postgres migration
rejected the data (varchar(8)). Widen it to String(32).
"""
from typing import Sequence, Union
import sqlalchemy as sa
from alembic import op
revision: str = "d4e5f6a7b8c9"
down_revision: Union[str, None] = "c3d4e5f6a7b8"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
with op.batch_alter_table("messages", schema=None) as batch_op:
batch_op.alter_column(
"signature",
existing_type=sa.String(length=8),
type_=sa.String(length=32),
existing_nullable=True,
)
def downgrade() -> None:
with op.batch_alter_table("messages", schema=None) as batch_op:
batch_op.alter_column(
"signature",
existing_type=sa.String(length=32),
type_=sa.String(length=8),
existing_nullable=True,
)
+2 -2
View File
@@ -21,7 +21,7 @@ class Message(Base, UUIDMixin, TimestampMixin):
text: Message content
path_len: Number of hops
txt_type: Message type indicator
signature: Message signature (8 hex chars)
signature: Message signature (hex), or the packet_hash fallback
snr: Signal-to-noise ratio
sender_timestamp: Sender's timestamp
received_at: When received by interface
@@ -60,7 +60,7 @@ class Message(Base, UUIDMixin, TimestampMixin):
nullable=True,
)
signature: Mapped[Optional[str]] = mapped_column(
String(8),
String(32),
nullable=True,
)
snr: Mapped[Optional[float]] = mapped_column(