Skip to content

Commit

Permalink
Ограничить размер строковых колонок в бд (#165)
Browse files Browse the repository at this point in the history
Во время реализации эндпойнта регистрации (#88) были добавлены модели Account и Profile, содержащие колонки со строковым типом данных. Но при этом не были выставлены ограничения длины этих строк.

В рамках этой задачи необходимо добавить ограничения длины для колонок строкового типа согласно DDD модели данных.

---

**Особенности реализации**

В процессе работы над задачей выяснилось, что алембик не может обнаружить изменения типа, которое нам было нужно: varchar -> varchar(42), поэтому миграция была написана вручную.

Подробнее об особенности работы алембика в данном случае можно почитать в [обсуждении](sqlalchemy/alembic#1256) в репозитории самого алембика. Здесь же, на всякий случай процитирую основной ответ, закрывающий это обсуждение:

> **zzzeek** (maintainer):
>
> PG allows for unlengthed VARCHAR. the alembic type comparison rules are set so that they only report a "positive" if two parameters don't match. if the number of parameters are different, it does not attempt to guess, so in this case VARCHAR and VARCHAR(6) have a different number of parameters; it's a negative. the overarching priority is to not produce false positives, since a false negative means editing a single migration file to fix for the miss, but a false positive means editing every migration file.
  • Loading branch information
birthdaysgift committed Dec 23, 2023
1 parent c334486 commit 76a160f
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
"""add length constraints to existing string columns
Revision ID: a8b78318faef
Revises: 55f1606e7086
Create Date: 2024-01-23 14:18:20.106426+00:00
"""
from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision = "a8b78318faef"
down_revision = "55f1606e7086"
branch_labels = None
depends_on = None


def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.alter_column("account", "email", type_=sa.String(200))
op.alter_column("account", "login", type_=sa.String(50))

op.alter_column("profile", "description", type_=sa.String(1000))
op.alter_column("profile", "name", type_=sa.String(100))
# ### end Alembic commands ###


def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.alter_column("account", "email", type_=sa.String)
op.alter_column("account", "login", type_=sa.String)

op.alter_column("profile", "description", type_=sa.String)
op.alter_column("profile", "name", type_=sa.String)
# ### end Alembic commands ###
5 changes: 3 additions & 2 deletions src/account/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from sqlalchemy.orm import Mapped, mapped_column

from src.account.exceptions import DuplicateAccountException
from src.account.fields import Email, Login
from src.shared.database import Base
from src.shared.datetime import utcnow

Expand All @@ -29,8 +30,8 @@ class Account(Base): # pylint: disable=too-few-public-methods
id: Mapped[int] = mapped_column(Integer, primary_key=True) # noqa: A003

created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utcnow, nullable=False)
email: Mapped[str] = mapped_column(String, nullable=False, unique=True)
login: Mapped[str] = mapped_column(String, nullable=False, unique=True)
email: Mapped[str] = mapped_column(String(length=Email.LENGTH_MAX), nullable=False, unique=True)
login: Mapped[str] = mapped_column(String(length=Login.LENGTH_MAX), nullable=False, unique=True)
updated_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True), default=utcnow, nullable=False, onupdate=utcnow,
)
Expand Down
5 changes: 3 additions & 2 deletions src/profile/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from sqlalchemy.dialects.postgresql import UUID as PG_UUID
from sqlalchemy.orm import Mapped, mapped_column

from src.profile.fields import Description, Name
from src.shared.database import Base
from src.shared.datetime import utcnow

Expand All @@ -28,8 +29,8 @@ class Profile(Base): # pylint: disable=too-few-public-methods
account_id: Mapped[int] = mapped_column(ForeignKey("account.id"), autoincrement=False, primary_key=True)

avatar_id: Mapped[UUID | None] = mapped_column(PG_UUID(as_uuid=True), unique=True)
description: Mapped[String | None] = mapped_column(String)
name: Mapped[str] = mapped_column(String, nullable=False)
description: Mapped[str | None] = mapped_column(String(length=Description.LENGTH_MAX))
name: Mapped[str] = mapped_column(String(length=Name.LENGTH_MAX), nullable=False)
updated_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True), default=utcnow, nullable=False, onupdate=utcnow,
)
Expand Down

0 comments on commit 76a160f

Please sign in to comment.