🗃️ Add max_length validation for database models and input data (#1233)

This commit is contained in:
Esteban Maya
2024-06-18 19:20:39 -05:00
committed by GitHub
parent df66c1d2ce
commit d421c90af2
4 changed files with 99 additions and 33 deletions

View File

@@ -0,0 +1,69 @@
"""Add max length for string(varchar) fields in User and Items models
Revision ID: 9c0a54914c78
Revises: e2412789c190
Create Date: 2024-06-17 14:42:44.639457
"""
from alembic import op
import sqlalchemy as sa
import sqlmodel.sql.sqltypes
# revision identifiers, used by Alembic.
revision = '9c0a54914c78'
down_revision = 'e2412789c190'
branch_labels = None
depends_on = None
def upgrade():
# Adjust the length of the email field in the User table
op.alter_column('user', 'email',
existing_type=sa.String(),
type_=sa.String(length=255),
existing_nullable=False)
# Adjust the length of the full_name field in the User table
op.alter_column('user', 'full_name',
existing_type=sa.String(),
type_=sa.String(length=255),
existing_nullable=True)
# Adjust the length of the title field in the Item table
op.alter_column('item', 'title',
existing_type=sa.String(),
type_=sa.String(length=255),
existing_nullable=False)
# Adjust the length of the description field in the Item table
op.alter_column('item', 'description',
existing_type=sa.String(),
type_=sa.String(length=255),
existing_nullable=True)
def downgrade():
# Revert the length of the email field in the User table
op.alter_column('user', 'email',
existing_type=sa.String(length=255),
type_=sa.String(),
existing_nullable=False)
# Revert the length of the full_name field in the User table
op.alter_column('user', 'full_name',
existing_type=sa.String(length=255),
type_=sa.String(),
existing_nullable=True)
# Revert the length of the title field in the Item table
op.alter_column('item', 'title',
existing_type=sa.String(length=255),
type_=sa.String(),
existing_nullable=False)
# Revert the length of the description field in the Item table
op.alter_column('item', 'description',
existing_type=sa.String(length=255),
type_=sa.String(),
existing_nullable=True)

View File

@@ -1,43 +1,40 @@
from pydantic import EmailStr
from sqlmodel import Field, Relationship, SQLModel
# Shared properties
# TODO replace email str with EmailStr when sqlmodel supports it
class UserBase(SQLModel):
email: str = Field(unique=True, index=True)
email: EmailStr = Field(unique=True, index=True, max_length=255)
is_active: bool = True
is_superuser: bool = False
full_name: str | None = None
full_name: str | None = Field(default=None, max_length=255)
# Properties to receive via API on creation
class UserCreate(UserBase):
password: str
password: str = Field(min_length=8, max_length=40)
# TODO replace email str with EmailStr when sqlmodel supports it
class UserRegister(SQLModel):
email: str
password: str
full_name: str | None = None
email: EmailStr = Field(max_length=255)
password: str = Field(min_length=8, max_length=40)
full_name: str | None = Field(default=None, max_length=255)
# Properties to receive via API on update, all are optional
# TODO replace email str with EmailStr when sqlmodel supports it
class UserUpdate(UserBase):
email: str | None = None # type: ignore
password: str | None = None
email: EmailStr | None = Field(default=None, max_length=255) # type: ignore
password: str | None = Field(default=None, min_length=8, max_length=40)
# TODO replace email str with EmailStr when sqlmodel supports it
class UserUpdateMe(SQLModel):
full_name: str | None = None
email: str | None = None
full_name: str | None = Field(default=None, max_length=255)
email: EmailStr | None = Field(default=None, max_length=255)
class UpdatePassword(SQLModel):
current_password: str
new_password: str
current_password: str = Field(min_length=8, max_length=40)
new_password: str = Field(min_length=8, max_length=40)
# Database model, database table inferred from class name
@@ -59,24 +56,24 @@ class UsersPublic(SQLModel):
# Shared properties
class ItemBase(SQLModel):
title: str
description: str | None = None
title: str = Field(min_length=1, max_length=255)
description: str | None = Field(default=None, max_length=255)
# Properties to receive on item creation
class ItemCreate(ItemBase):
title: str
title: str = Field(min_length=1, max_length=255)
# Properties to receive on item update
class ItemUpdate(ItemBase):
title: str | None = None # type: ignore
title: str | None = Field(default=None, min_length=1, max_length=255) # type: ignore
# Database model, database table inferred from class name
class Item(ItemBase, table=True):
id: int | None = Field(default=None, primary_key=True)
title: str
title: str = Field(max_length=255)
owner_id: int | None = Field(default=None, foreign_key="user.id", nullable=False)
owner: User | None = Relationship(back_populates="items")
@@ -110,4 +107,4 @@ class TokenPayload(SQLModel):
class NewPassword(SQLModel):
token: str
new_password: str
new_password: str = Field(min_length=8, max_length=40)