From 9ba902b33ca529971179e567ce2c4f4479360d64 Mon Sep 17 00:00:00 2001 From: Yurii Motov Date: Tue, 27 Jan 2026 14:19:33 +0100 Subject: [PATCH] Add "String fields and column length" sections to docs --- docs/tutorial/str-fields-and-column-length.md | 56 +++++++++++++++++++ .../str_fields_and_column_length/__init__.py | 0 .../tutorial001_py310.py | 19 +++++++ .../tutorial001_py39.py | 21 +++++++ .../tutorial002_py310.py | 19 +++++++ .../tutorial002_py39.py | 21 +++++++ .../tutorial003_py310.py | 19 +++++++ .../tutorial003_py39.py | 21 +++++++ .../tutorial004_py310.py | 19 +++++++ .../tutorial004_py39.py | 21 +++++++ mkdocs.yml | 1 + 11 files changed, 217 insertions(+) create mode 100644 docs/tutorial/str-fields-and-column-length.md create mode 100644 docs_src/tutorial/str_fields_and_column_length/__init__.py create mode 100644 docs_src/tutorial/str_fields_and_column_length/tutorial001_py310.py create mode 100644 docs_src/tutorial/str_fields_and_column_length/tutorial001_py39.py create mode 100644 docs_src/tutorial/str_fields_and_column_length/tutorial002_py310.py create mode 100644 docs_src/tutorial/str_fields_and_column_length/tutorial002_py39.py create mode 100644 docs_src/tutorial/str_fields_and_column_length/tutorial003_py310.py create mode 100644 docs_src/tutorial/str_fields_and_column_length/tutorial003_py39.py create mode 100644 docs_src/tutorial/str_fields_and_column_length/tutorial004_py310.py create mode 100644 docs_src/tutorial/str_fields_and_column_length/tutorial004_py39.py diff --git a/docs/tutorial/str-fields-and-column-length.md b/docs/tutorial/str-fields-and-column-length.md new file mode 100644 index 00000000..8d08ab4d --- /dev/null +++ b/docs/tutorial/str-fields-and-column-length.md @@ -0,0 +1,56 @@ +# String fields and column length + +Some databases have a limit on the length of string columns (e.g., `VARCHAR(255)` in *MySQL*) and fail with an error if you try to create a string column without specifying a length. + +**SQLModel** handles this automatically depending on the database dialect you are using. 😎 + +For databases that require a length for string columns, **SQLModel** will automatically set a default length (e.g., `255` for *MySQL*) if you do not specify one. + +{* ./docs_src/tutorial/str_fields_and_column_length/tutorial001_py310.py ln[4:6] hl[6] *} + +If you run this code with *MySQL*, **SQLModel** will create the `name` column as `VARCHAR(255)`: + +```sql +CREATE TABLE hero ( + id INTEGER NOT NULL AUTO_INCREMENT, + name VARCHAR(255) NOT NULL, + PRIMARY KEY (id) +) +``` + +But you can always specify a custom length if needed: + +{* ./docs_src/tutorial/str_fields_and_column_length/tutorial002_py310.py ln[4:6] hl[6] *} + +```sql +CREATE TABLE hero ( + id INTEGER NOT NULL AUTO_INCREMENT, + name VARCHAR(100) NOT NULL, + PRIMARY KEY (id) +) +``` +This works thanks to `AutoString` type that **SQLModel** uses for all string fields by default. + +But if you specify the database type of column explicitly, **SQLModel** will not be able to set the length automatically, and you will need to specify it manually: + +{* ./docs_src/tutorial/str_fields_and_column_length/tutorial003_py310.py ln[1:6] hl[1,6] *} + +The code example above will fail on databases that require a length for string columns: + +```console +sqlalchemy.exc.CompileError: (in table 'hero', column 'name'): VARCHAR requires a length on dialect mysql +``` + +To fix it, you need to specify the length explicitly as follows: + +{* ./docs_src/tutorial/str_fields_and_column_length/tutorial004_py310.py ln[1:6] hl[1,6] *} + +This will give: + +```sql +CREATE TABLE hero ( + id INTEGER NOT NULL AUTO_INCREMENT, + name VARCHAR(255) NOT NULL, + PRIMARY KEY (id) +) +``` diff --git a/docs_src/tutorial/str_fields_and_column_length/__init__.py b/docs_src/tutorial/str_fields_and_column_length/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/docs_src/tutorial/str_fields_and_column_length/tutorial001_py310.py b/docs_src/tutorial/str_fields_and_column_length/tutorial001_py310.py new file mode 100644 index 00000000..a73201e2 --- /dev/null +++ b/docs_src/tutorial/str_fields_and_column_length/tutorial001_py310.py @@ -0,0 +1,19 @@ +from sqlmodel import Field, SQLModel, create_engine + + +class Hero(SQLModel, table=True): + id: int | None = Field(default=None, primary_key=True) + name: str + + +database_url = "mysql://user:password@localhost/dbname" + +engine = create_engine(database_url, echo=True) + + +def create_db_and_tables(): + SQLModel.metadata.create_all(engine) + + +if __name__ == "__main__": + create_db_and_tables() diff --git a/docs_src/tutorial/str_fields_and_column_length/tutorial001_py39.py b/docs_src/tutorial/str_fields_and_column_length/tutorial001_py39.py new file mode 100644 index 00000000..ff334835 --- /dev/null +++ b/docs_src/tutorial/str_fields_and_column_length/tutorial001_py39.py @@ -0,0 +1,21 @@ +from typing import Optional + +from sqlmodel import Field, SQLModel, create_engine + + +class Hero(SQLModel, table=True): + id: Optional[int] = Field(default=None, primary_key=True) + name: str + + +database_url = "mysql://user:password@localhost/dbname" + +engine = create_engine(database_url, echo=True) + + +def create_db_and_tables(): + SQLModel.metadata.create_all(engine) + + +if __name__ == "__main__": + create_db_and_tables() diff --git a/docs_src/tutorial/str_fields_and_column_length/tutorial002_py310.py b/docs_src/tutorial/str_fields_and_column_length/tutorial002_py310.py new file mode 100644 index 00000000..b8a1119d --- /dev/null +++ b/docs_src/tutorial/str_fields_and_column_length/tutorial002_py310.py @@ -0,0 +1,19 @@ +from sqlmodel import Field, SQLModel, create_engine + + +class Hero(SQLModel, table=True): + id: int | None = Field(default=None, primary_key=True) + name: str = Field(max_length=100) + + +database_url = "mysql://user:password@localhost/dbname" + +engine = create_engine(database_url, echo=True) + + +def create_db_and_tables(): + SQLModel.metadata.create_all(engine) + + +if __name__ == "__main__": + create_db_and_tables() diff --git a/docs_src/tutorial/str_fields_and_column_length/tutorial002_py39.py b/docs_src/tutorial/str_fields_and_column_length/tutorial002_py39.py new file mode 100644 index 00000000..32e7052b --- /dev/null +++ b/docs_src/tutorial/str_fields_and_column_length/tutorial002_py39.py @@ -0,0 +1,21 @@ +from typing import Optional + +from sqlmodel import Field, SQLModel, create_engine + + +class Hero(SQLModel, table=True): + id: Optional[int] = Field(default=None, primary_key=True) + name: str = Field(max_length=100) + + +database_url = "mysql://user:password@localhost/dbname" + +engine = create_engine(database_url, echo=True) + + +def create_db_and_tables(): + SQLModel.metadata.create_all(engine) + + +if __name__ == "__main__": + create_db_and_tables() diff --git a/docs_src/tutorial/str_fields_and_column_length/tutorial003_py310.py b/docs_src/tutorial/str_fields_and_column_length/tutorial003_py310.py new file mode 100644 index 00000000..51e0c1bb --- /dev/null +++ b/docs_src/tutorial/str_fields_and_column_length/tutorial003_py310.py @@ -0,0 +1,19 @@ +from sqlmodel import Field, SQLModel, String, create_engine + + +class Hero(SQLModel, table=True): + id: int | None = Field(default=None, primary_key=True) + name: str = Field(sa_type=String) + + +database_url = "mysql://user:password@localhost/dbname" + +engine = create_engine(database_url, echo=True) + + +def create_db_and_tables(): + SQLModel.metadata.create_all(engine) + + +if __name__ == "__main__": + create_db_and_tables() diff --git a/docs_src/tutorial/str_fields_and_column_length/tutorial003_py39.py b/docs_src/tutorial/str_fields_and_column_length/tutorial003_py39.py new file mode 100644 index 00000000..4ca5ff0f --- /dev/null +++ b/docs_src/tutorial/str_fields_and_column_length/tutorial003_py39.py @@ -0,0 +1,21 @@ +from typing import Optional + +from sqlmodel import Field, SQLModel, String, create_engine + + +class Hero(SQLModel, table=True): + id: Optional[int] = Field(default=None, primary_key=True) + name: str = Field(sa_type=String) + + +database_url = "mysql://user:password@localhost/dbname" + +engine = create_engine(database_url, echo=True) + + +def create_db_and_tables(): + SQLModel.metadata.create_all(engine) + + +if __name__ == "__main__": + create_db_and_tables() diff --git a/docs_src/tutorial/str_fields_and_column_length/tutorial004_py310.py b/docs_src/tutorial/str_fields_and_column_length/tutorial004_py310.py new file mode 100644 index 00000000..fb67058e --- /dev/null +++ b/docs_src/tutorial/str_fields_and_column_length/tutorial004_py310.py @@ -0,0 +1,19 @@ +from sqlmodel import Field, SQLModel, String, create_engine + + +class Hero(SQLModel, table=True): + id: int | None = Field(default=None, primary_key=True) + name: str = Field(sa_type=String(length=255)) + + +database_url = "mysql://user:password@localhost/dbname" + +engine = create_engine(database_url, echo=True) + + +def create_db_and_tables(): + SQLModel.metadata.create_all(engine) + + +if __name__ == "__main__": + create_db_and_tables() diff --git a/docs_src/tutorial/str_fields_and_column_length/tutorial004_py39.py b/docs_src/tutorial/str_fields_and_column_length/tutorial004_py39.py new file mode 100644 index 00000000..c1ef56ab --- /dev/null +++ b/docs_src/tutorial/str_fields_and_column_length/tutorial004_py39.py @@ -0,0 +1,21 @@ +from typing import Optional + +from sqlmodel import Field, SQLModel, String, create_engine + + +class Hero(SQLModel, table=True): + id: Optional[int] = Field(default=None, primary_key=True) + name: str = Field(sa_type=String(length=255)) + + +database_url = "mysql://user:password@localhost/dbname" + +engine = create_engine(database_url, echo=True) + + +def create_db_and_tables(): + SQLModel.metadata.create_all(engine) + + +if __name__ == "__main__": + create_db_and_tables() diff --git a/mkdocs.yml b/mkdocs.yml index b89516e0..42d9d79b 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -81,6 +81,7 @@ nav: - tutorial/create-db-and-table.md - tutorial/insert.md - tutorial/automatic-id-none-refresh.md + - tutorial/str-fields-and-column-length.md - tutorial/select.md - tutorial/where.md - tutorial/indexes.md -- 2.47.3