Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/advanced/decimal.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Pydantic has special support for <a href="https://docs.pydantic.dev/latest/api/s

When you use `Decimal` you can specify the number of digits and decimal places to support in the `Field()` function. They will be validated by Pydantic (for example when using FastAPI) and the same information will also be used for the database columns.

/// info
/// note

For the database, **SQLModel** will use <a href="https://docs.sqlalchemy.org/en/20/core/type_basics.html#sqlalchemy.types.DECIMAL" class="external-link" target="_blank">SQLAlchemy's `DECIMAL` type</a>.

Expand Down
2 changes: 1 addition & 1 deletion docs/advanced/uuid.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ You might have seen **UUIDs**, for example in URLs. They look something like thi

UUIDs can be particularly useful as an alternative to auto-incrementing integers for **primary keys**.

/// info
/// note

Official support for UUIDs was added in SQLModel version `0.0.20`.

Expand Down
4 changes: 2 additions & 2 deletions docs/databases.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Intro to Databases

/// info
/// note

Are you a seasoned developer and already know everything about databases? 🤓

Expand Down Expand Up @@ -317,7 +317,7 @@ Next, it receives the data and puts it in Python objects that you can continue t

I'll tell you more about SQL, SQLModel, how to use them, and how they are related in the next sections.

/// info | Technical Details
/// note | Technical Details

SQLModel is built on top of SQLAlchemy. It is, in fact, just <a href="https://www.sqlalchemy.org/" class="external-link" target="_blank">SQLAlchemy</a> and <a href="https://pydantic-docs.helpmanual.io/" class="external-link" target="_blank">Pydantic</a> mixed together with some sugar on top.

Expand Down
4 changes: 2 additions & 2 deletions docs/db-to-code.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ Then your code will continue to execute and calmly tell the user that it couldn'

But we never deleted the `hero` table. 🎉

/// info
/// note

Of course, there are also other ways to do SQL data sanitization without using a tool like **SQLModel**, but it's still a nice feature you get by default.

Expand Down Expand Up @@ -296,7 +296,7 @@ There are many ORMs available apart from **SQLModel**, you can read more about s

## SQL Table Names

/// info | Technical Background
/// note | Technical Background

This is a bit of boring background for SQL purists. Feel free to skip this section. 😉

Expand Down
2 changes: 1 addition & 1 deletion docs/help.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ And if there's any other style or consistency need, I'll ask directly for that,

* Then **comment** saying that you did that, that's how I will know you really checked it.

/// info
/// note

Unfortunately, I can't simply trust PRs that just have several approvals.

Expand Down
2 changes: 1 addition & 1 deletion docs/tutorial/connect/create-connected-rows.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ Each row in the table `hero` will point to a row in the table `team`:

<img alt="table relationships" src="/img/tutorial/relationships/select/relationships2.drawio.svg">

/// info
/// note

We will later update **Spider-Boy** to add him to the **Preventers** team too, but not yet.

Expand Down
2 changes: 1 addition & 1 deletion docs/tutorial/connect/create-connected-tables.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ This is the name of the **table** in the database, so it is `"team"`, not the na

If you had a custom table name, you would use that custom table name.

/// info
/// note

You can learn about setting a custom table name for a model in the Advanced User Guide.

Expand Down
4 changes: 2 additions & 2 deletions docs/tutorial/connect/read-connected-data.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ FROM hero, team
WHERE hero.team_id = team.id
```

/// info
/// note

Because we have two columns called `name`, one for `hero` and one for `team`, we can specify them with the prefix of the table name and the dot to make it explicit what we refer to.

Expand Down Expand Up @@ -133,7 +133,7 @@ For each iteration in the `for` loop we get a tuple with an instance of the clas

And in this `for` loop we assign them to the variable `hero` and the variable `team`.

/// info
/// note

There was a lot of research, design, and work behind **SQLModel** to make this provide the best possible developer experience.

Expand Down
6 changes: 3 additions & 3 deletions docs/tutorial/create-db-and-table.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ This class `Hero` **represents the table** for our heroes. And each instance we

We use the config `table=True` to tell **SQLModel** that this is a **table model**, it represents a table.

/// info
/// note

It's also possible to have models without `table=True`, those would be only **data models**, without a table in the database, they would not be **table models**.

Expand Down Expand Up @@ -366,7 +366,7 @@ INFO Engine COMMIT

</div>

/// info
/// note

I simplified the output above a bit to make it easier to read.

Expand Down Expand Up @@ -538,7 +538,7 @@ if __name__ == "__main__":

...will **not** be executed.

/// info
/// note

For more information, check <a href="https://docs.python.org/3/library/__main__.html" class="external-link" target="_blank">the official Python docs</a>.

Expand Down
4 changes: 2 additions & 2 deletions docs/tutorial/fastapi/limit-and-offset.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ So, we probably want to limit it.

Let's use the same **offset** and **limit** we learned about in the previous tutorial chapters for the API.

/// info
/// note

In many cases, this is also called **pagination**.

Expand All @@ -32,7 +32,7 @@ So, to prevent it, we add additional validation to the `limit` query parameter,

This way, a client can decide to take fewer heroes if they want, but not more.

/// info
/// note

If you need to refresh how query parameters and their validation work, check out the docs in FastAPI:

Expand Down
2 changes: 1 addition & 1 deletion docs/tutorial/fastapi/read-one.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Let's add a new *path operation* to read one single hero.

We want to get the hero based on the `id`, so we will use a **path parameter** `hero_id`.

/// info
/// note

If you need to refresh how *path parameters* work, including their data validation, check the <a href="https://fastapi.tiangolo.com/tutorial/path-params/" class="external-link" target="_blank">FastAPI docs about Path Parameters</a>.

Expand Down
2 changes: 1 addition & 1 deletion docs/tutorial/fastapi/response-model.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ Additionally, because the schemas are defined in using a standard, there are man

For example, client generators, that can automatically create the code necessary to talk to your API in many languages.

/// info
/// note

If you are curious about the standards, FastAPI generates OpenAPI, that internally uses JSON Schema.

Expand Down
8 changes: 4 additions & 4 deletions docs/tutorial/fastapi/simple-hero-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ But here we will make sure we don't share the same **session** in more than one

And we also need to disable it because in **FastAPI** each request could be handled by multiple interacting threads.

/// info
/// note

That's enough information for now, you can read more about it in the <a href="https://fastapi.tiangolo.com/async/" class="external-link" target="_blank">FastAPI docs for `async` and `await`</a>.

Expand Down Expand Up @@ -68,7 +68,7 @@ This should be called only once at startup, not before every request, so we put

## Create Heroes *Path Operation*

/// info
/// note

If you need a refresher on what a **Path Operation** is (an endpoint with a specific HTTP Operation) and how to work with it in FastAPI, check out the <a href="https://fastapi.tiangolo.com/tutorial/first-steps/" class="external-link" target="_blank">FastAPI First Steps docs</a>.

Expand All @@ -80,7 +80,7 @@ It will be called when a user sends a request with a `POST` **operation** to the

{* ./docs_src/tutorial/fastapi/simple_hero_api/tutorial001_py310.py ln[23:37] hl[31:32] *}

/// info
/// note

If you need a refresher on some of those concepts, checkout the FastAPI documentation:

Expand Down Expand Up @@ -152,7 +152,7 @@ $ fastapi dev main.py

</div>

/// info
/// note

The `fastapi` command uses <a href="https://www.uvicorn.org/" class="external-link" target="_blank">Uvicorn</a> underneath.

Expand Down
2 changes: 1 addition & 1 deletion docs/tutorial/fastapi/tests.md
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ Do we really have to duplicate all that for **each test**? No, we can do better!

We are using **pytest** to run the tests. And pytest also has a very similar concept to the **dependencies in FastAPI**.

/// info
/// note

In fact, pytest was one of the things that inspired the design of the dependencies in FastAPI.

Expand Down
2 changes: 1 addition & 1 deletion docs/tutorial/indexes.md
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ We use the same `Field()` again as we did before, and set `index=True`. That's i

Notice that we didn't set an argument of `default=None` or anything similar. This means that **SQLModel** (thanks to Pydantic) will keep it as a **required** field.

/// info
/// note

SQLModel (actually SQLAlchemy) will **automatically generate the index name** for you.

Expand Down
2 changes: 1 addition & 1 deletion docs/tutorial/insert.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ And once we are ready, we can **commit** those changes, and then the **session**

This makes the interactions with the database more efficient (plus some extra benefits).

/// info | Technical Details
/// note | Technical Details

The session will create a new transaction and execute all the SQL code in that transaction.

Expand Down
2 changes: 1 addition & 1 deletion docs/tutorial/many-to-many/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ Specifically, the new link table `heroteamlink` would be:
</tr>
</table>

/// info
/// note

Other names used for this **link table** are:

Expand Down
2 changes: 1 addition & 1 deletion docs/tutorial/many-to-many/link-with-extra-fields.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ The new **relationship attributes** have their own `back_populates` pointing to
* `team`: has `back_populates="hero_links"`, because in the `Team` model, the attribute will contain the links to the **team's heroes**.
* `hero`: has `back_populates="team_links"`, because in the `Hero` model, the attribute will contain the links to the **hero's teams**.

/// info
/// note

In SQLAlchemy this is called an Association Object or Association Model.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Should their `team_id` instead be set to `NULL` in the database?

Let's see how to configure that with **SQLModel**.

/// info
/// note

This feature, including `cascade_delete`, `ondelete`, and `passive_deletes`, is available since SQLModel version `0.0.21`.

Expand Down Expand Up @@ -440,7 +440,7 @@ To be able to test this out with SQLite, we first need to enable foreign key sup

{* ./docs_src/tutorial/relationship_attributes/cascade_delete_relationships/tutorial003_py310.py ln[30:33] hl[33] *}

/// info
/// note

You can learn more about SQLite, foreign keys, and this SQL command on the <a href="https://docs.sqlalchemy.org/en/20/dialects/sqlite.html#foreign-key-support" class="external-link" target="_blank">SQLAlchemy docs</a>.

Expand Down
2 changes: 1 addition & 1 deletion docs/tutorial/relationship-attributes/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ And then we read the data together with `select()` and using `.where()` or `.joi

Now we will see how to use **Relationship Attributes**, an extra feature of **SQLModel** (and SQLAlchemy), to work with the data in the database in a much more familiar way, and closer to normal Python code.

/// info
/// note

When I say "**relationship**" I mean the standard dictionary term, of data related to other data.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ And of course, **SQLModel** can also understand it in the string correctly. ✨

That is actually part of Python, it's the current official solution to handle it.

/// info
/// note

There's a lot of work going on in Python itself to make that simpler and more intuitive, and find ways to make it possible to not wrap the class in a string.

Expand Down
6 changes: 3 additions & 3 deletions docs/tutorial/select.md
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ And the second section reading data from the database could be in another functi

So, both sections could be in **different places** and would need their own sessions.

/// info
/// note

To be fair, in this example all that code could actually share the same **session**, there's actually no need to have two here.

Expand Down Expand Up @@ -319,7 +319,7 @@ After printing it, we would see something like:
]
```

/// info
/// note

It would actually look more compact, I'm formatting it a bit for you to see that it is actually a list with all the data.

Expand Down Expand Up @@ -353,7 +353,7 @@ SQLAchemy also has its own `select`, and SQLModel's `select` uses SQLAlchemy's `

But SQLModel's version does a lot of **tricks** with type annotations to make sure you get the best **editor support** possible, no matter if you use **VS Code**, **PyCharm**, or something else. ✨

/// info
/// note

There was a lot of work and research, with different versions of the internal code, to improve this as much as possible. 🤓

Expand Down
2 changes: 1 addition & 1 deletion docs/tutorial/update.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ And the second part, with the `WHERE`, defines to which rows it should apply tha

In this case, as we only have one hero with the name `"Spider-Boy"`, it will only apply the update in that row.

/// info
/// note

Notice that in the `UPDATE` the single equals sign (`=`) means **assignment**, setting a column to some value.

Expand Down
4 changes: 2 additions & 2 deletions docs/virtual-environments.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

When you work in Python projects you probably should use a **virtual environment** (or a similar mechanism) to isolate the packages you install for each project.

/// info
/// note

If you already know about virtual environments, how to create them and use them, you might want to skip this section. 🤓

Expand All @@ -18,7 +18,7 @@ A **virtual environment** is a directory with some files in it.

///

/// info
/// note

This page will teach you how to use **virtual environments** and how they work.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@

33. Print the `hero_1`.

/// info
/// note

Even if the `hero_1` wasn't fresh, this would **not** trigger a `refresh` making the **session** use the **engine** to fetch data from the database because it is not accessing an attribute.

Expand All @@ -323,7 +323,7 @@

34. Print the `hero_2`.

/// info
/// note

Even if the `hero_2` wasn't fresh, this would **not** trigger a `refresh` making the **session** use the **engine** to fetch data from the database because it is not accessing an attribute.

Expand All @@ -339,7 +339,7 @@

35. Print the `hero_3`.

/// info
/// note

Even if the `hero_3` wasn't fresh, this would **not** trigger a `refresh` making the **session** use the **engine** to fetch data from the database because it is not accessing an attribute.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
We tell it that with the `poolclass=StaticPool` parameter.
/// info
/// note
You can read more details in the <a href="https://docs.sqlalchemy.org/en/14/dialects/sqlite.html#using-a-memory-database-in-multiple-threads" class="external-link" target="_blank">SQLAlchemy documentation about Using a Memory Database in Multiple Threads</a>
Expand Down
11 changes: 0 additions & 11 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -165,17 +165,6 @@ markdown_extensions:

# pymdownx blocks
pymdownx.blocks.admonition:
types:
- note
- attention
- caution
- danger
- error
- tip
- hint
- warning
# Custom types
- info
pymdownx.blocks.details:
pymdownx.blocks.tab:
alternate_style: True
Expand Down
Loading