<em>SQLModel, SQL databases in Python, designed for simplicity, compatibility, and robustness.</em>
</p>
<p align="center">
-<a href="https://github.com/fastapi/sqlmodel/actions?query=workflow%3ATest+event%3Apush+branch%3Amain" target="_blank">
+<a href="https://github.com/fastapi/sqlmodel/actions?query=workflow%3ATest+event%3Apush+branch%3Amain">
<img src="https://github.com/fastapi/sqlmodel/actions/workflows/test.yml/badge.svg?event=push&branch=main" alt="Test">
</a>
-<a href="https://github.com/fastapi/sqlmodel/actions?query=workflow%3APublish" target="_blank">
+<a href="https://github.com/fastapi/sqlmodel/actions?query=workflow%3APublish">
<img src="https://github.com/fastapi/sqlmodel/actions/workflows/publish.yml/badge.svg" alt="Publish">
</a>
-<a href="https://coverage-badge.samuelcolvin.workers.dev/redirect/fastapi/sqlmodel" target="_blank">
+<a href="https://coverage-badge.samuelcolvin.workers.dev/redirect/fastapi/sqlmodel">
<img src="https://coverage-badge.samuelcolvin.workers.dev/fastapi/sqlmodel.svg" alt="Coverage">
-<a href="https://pypi.org/project/sqlmodel" target="_blank">
+<a href="https://pypi.org/project/sqlmodel">
<img src="https://img.shields.io/pypi/v/sqlmodel?color=%2334D058&label=pypi%20package" alt="Package version">
</a>
</p>
---
-**Documentation**: <a href="https://sqlmodel.tiangolo.com" target="_blank">https://sqlmodel.tiangolo.com</a>
+**Documentation**: [https://sqlmodel.tiangolo.com](https://sqlmodel.tiangolo.com)
-**Source Code**: <a href="https://github.com/fastapi/sqlmodel" target="_blank">https://github.com/fastapi/sqlmodel</a>
+**Source Code**: [https://github.com/fastapi/sqlmodel](https://github.com/fastapi/sqlmodel)
---
SQLModel is a library for interacting with <abbr title='Also called "Relational databases"'>SQL databases</abbr> from Python code, with Python objects. It is designed to be intuitive, easy to use, highly compatible, and robust.
-**SQLModel** is based on Python type annotations, and powered by <a href="https://pydantic-docs.helpmanual.io/" class="external-link" target="_blank">Pydantic</a> and <a href="https://sqlalchemy.org/" class="external-link" target="_blank">SQLAlchemy</a>.
+**SQLModel** is based on Python type annotations, and powered by [Pydantic](https://pydantic-docs.helpmanual.io/) and [SQLAlchemy](https://sqlalchemy.org/).
The key features are:
## SQL Databases in FastAPI
-<a href="https://fastapi.tiangolo.com" target="_blank"><img src="https://fastapi.tiangolo.com/img/logo-margin/logo-teal.png" style="width: 20%;"></a>
+<a href="https://fastapi.tiangolo.com"><img src="https://fastapi.tiangolo.com/img/logo-margin/logo-teal.png" style="width: 20%;"></a>
-**SQLModel** is designed to simplify interacting with SQL databases in <a href="https://fastapi.tiangolo.com" class="external-link" target="_blank">FastAPI</a> applications, it was created by the same <a href="https://tiangolo.com/" class="external-link" target="_blank">author</a>. 😁
+**SQLModel** is designed to simplify interacting with SQL databases in [FastAPI](https://fastapi.tiangolo.com) applications, it was created by the same [author](https://tiangolo.com/). 😁
It combines SQLAlchemy and Pydantic and tries to simplify the code you write as much as possible, allowing you to reduce the **code duplication to a minimum**, but while getting the **best developer experience** possible.
## Requirements
-A recent and currently supported <a href="https://www.python.org/downloads/" class="external-link" target="_blank">version of Python</a>.
+A recent and currently supported [version of Python](https://www.python.org/downloads/).
As **SQLModel** is based on **Pydantic** and **SQLAlchemy**, it requires them. They will be automatically installed when you install SQLModel.
## Installation
-Make sure you create a <a href="https://sqlmodel.tiangolo.com/virtual-environments/" class="external-link" target="_blank">virtual environment</a>, activate it, and then install SQLModel, for example with:
+Make sure you create a [virtual environment](https://sqlmodel.tiangolo.com/virtual-environments/), activate it, and then install SQLModel, for example with:
<div class="termy">
## Example
-For an introduction to databases, SQL, and everything else, see the <a href="https://sqlmodel.tiangolo.com/databases/" target="_blank">SQLModel documentation</a>.
+For an introduction to databases, SQL, and everything else, see the [SQLModel documentation](https://sqlmodel.tiangolo.com/databases/).
Here's a quick example. ✨
3.3000000000000003
```
-This is because of the way numbers are stored in "ones and zeros" (binary). But Python has a module and some types to have strict decimal values. You can read more about it in the official <a href="https://docs.python.org/3/library/decimal.html" class="external-link" target="_blank">Python docs for Decimal</a>.
+This is because of the way numbers are stored in "ones and zeros" (binary). But Python has a module and some types to have strict decimal values. You can read more about it in the official [Python docs for Decimal](https://docs.python.org/3/library/decimal.html).
Because databases store data in the same ways as computers (in binary), they would have the same types of issues. And because of that, they also have a special **decimal** type.
## Decimal Types
-Pydantic has special support for <a href="https://docs.pydantic.dev/latest/api/standard_library_types/#decimaldecimal" class="external-link" target="_blank">`Decimal` types</a>.
+Pydantic has special support for [`Decimal` types](https://docs.pydantic.dev/latest/api/standard_library_types/#decimaldecimal).
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
-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>.
+For the database, **SQLModel** will use [SQLAlchemy's `DECIMAL` type](https://docs.sqlalchemy.org/en/20/core/type_basics.html#sqlalchemy.types.DECIMAL).
///
{* ./docs_src/advanced/uuid/tutorial001_py310.py ln[1:10] hl[1,7] *}
-Pydantic has support for <a href="https://docs.pydantic.dev/latest/api/standard_library_types/#uuid" class="external-link" target="_blank">`UUID` types</a>.
+Pydantic has support for [`UUID` types](https://docs.pydantic.dev/latest/api/standard_library_types/#uuid).
-For the database, **SQLModel** internally uses <a href="https://docs.sqlalchemy.org/en/20/core/type_basics.html#sqlalchemy.types.Uuid" class="external-link" target="_blank">SQLAlchemy's `Uuid` type</a>.
+For the database, **SQLModel** internally uses [SQLAlchemy's `Uuid` type](https://docs.sqlalchemy.org/en/20/core/type_basics.html#sqlalchemy.types.Uuid).
### Create a Record with a UUID
You can learn more about **UUIDs** in:
-* The official <a href="https://docs.python.org/3/library/uuid.html" class="external-link" target="_blank">Python docs for UUID</a>.
-* The <a href="https://en.wikipedia.org/wiki/Universally_unique_identifier" class="external-link" target="_blank">Wikipedia for UUID</a>.
+* The official [Python docs for UUID](https://docs.python.org/3/library/uuid.html).
+* The [Wikipedia for UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier).
# Contributing
-First, you might want to see the basic ways to [help SQLModel and get help](help.md){.internal-link target=_blank}.
+First, you might want to see the basic ways to [help SQLModel and get help](help.md).
## Developing
-If you already cloned the <a href="https://github.com/fastapi/sqlmodel" class="external-link" target="_blank">sqlmodel repository</a> and you want to deep dive in the code, here are some guidelines to set up your environment.
+If you already cloned the [sqlmodel repository](https://github.com/fastapi/sqlmodel) and you want to deep dive in the code, here are some guidelines to set up your environment.
### Install Requirements Using `uv`
The instructions here show you how to use the script at `./scripts/docs.py` with the `python` program directly.
-But you can also use <a href="https://typer.tiangolo.com/typer-cli/" class="external-link" target="_blank">Typer CLI</a>, and you will get autocompletion in your terminal for the commands after installing completion.
+But you can also use [Typer CLI](https://typer.tiangolo.com/typer-cli/), and you will get autocompletion in your terminal for the commands after installing completion.
If you install Typer CLI, you can install completion with:
### Docs Structure
-The documentation uses <a href="https://www.mkdocs.org/" class="external-link" target="_blank">MkDocs</a>.
+The documentation uses [MkDocs](https://www.mkdocs.org/).
And there are extra tools/scripts in place in `./scripts/docs.py`.
### Human Effort Denial of Service
-Using automated tools and AI to submit PRs or comments that we have to carefully review and handle would be the equivalent of a <a href="https://en.wikipedia.org/wiki/Denial-of-service_attack" class="external-link" target="_blank">Denial-of-service attack</a> on our human effort.
+Using automated tools and AI to submit PRs or comments that we have to carefully review and handle would be the equivalent of a [Denial-of-service attack](https://en.wikipedia.org/wiki/Denial-of-service_attack) on our human effort.
It would be very little effort from the person submitting the PR (an LLM prompt) that generates a large amount of effort on our side (carefully reviewing code).
/// info | 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.
+SQLModel is built on top of SQLAlchemy. It is, in fact, just [SQLAlchemy](https://www.sqlalchemy.org/) and [Pydantic](https://pydantic-docs.helpmanual.io/) mixed together with some sugar on top.
///
That is how you tell the database in SQL to delete the entire table `hero`.
-<a href="https://theuselessweb.site/nooooooooooooooo/" class="external-link" target="_blank">Nooooo!</a> We lost all the data in the `hero` table! 💥😱
+[Nooooo!](https://theuselessweb.site/nooooooooooooooo/) We lost all the data in the `hero` table! 💥😱
### SQL Sanitization
It comes by default in **SQLModel** (thanks to SQLAlchemy). And many other similar tools would also provide that functionality among many other features.
-Now you are ready for <a href="https://xkcd.com/327/" class="external-link" target="_blank">a joke from xkcd</a>:
+Now you are ready for [a joke from xkcd](https://xkcd.com/327/):

So, an **ORM** is a library that translates from SQL to code, and from code to SQL. All using classes and objects.
-There are many ORMs available apart from **SQLModel**, you can read more about some of them in [Alternatives, Inspiration and Comparisons](alternatives.md){.internal-link target=_blank}
+There are many ORMs available apart from **SQLModel**, you can read more about some of them in [Alternatives, Inspiration and Comparisons](alternatives.md)
## SQL Table Names
/// tip
-The second argument to <a href="https://docs.python.org/3.8/library/os.html#os.getenv" class="external-link" target="_blank">`os.getenv()`</a> is the default value to return.
+The second argument to [`os.getenv()`](https://docs.python.org/3.8/library/os.html#os.getenv) is the default value to return.
If not provided, it's `None` by default, here we provide `"World"` as the default value to use.
/// tip
-You can read more about it at <a href="https://12factor.net/config" class="external-link" target="_blank">The Twelve-Factor App: Config</a>.
+You can read more about it at [The Twelve-Factor App: Config](https://12factor.net/config).
///
////
-This information will be useful when learning about [Virtual Environments](virtual-environments.md){.internal-link target=_blank}.
+This information will be useful when learning about [Virtual Environments](virtual-environments.md).
## Conclusion
With this you should have a basic understanding of what **environment variables** are and how to use them in Python.
-You can also read more about them in the <a href="https://en.wikipedia.org/wiki/Environment_variable" class="external-link" target="_blank">Wikipedia for Environment Variable</a>.
+You can also read more about them in the [Wikipedia for Environment Variable](https://en.wikipedia.org/wiki/Environment_variable).
In many cases it's not very obvious how environment variables would be useful and applicable right away. But they keep showing up in many different scenarios when you are developing, so it's good to know about them.
## Designed for **FastAPI**
-**SQLModel** was created by the same <a href="https://tiangolo.com/" class="external-link" target="_blank">author</a> of FastAPI.
+**SQLModel** was created by the same [author](https://tiangolo.com/) of FastAPI.
-<a href="https://fastapi.tiangolo.com" target="_blank"><img src="https://fastapi.tiangolo.com/img/logo-margin/logo-teal.png" style="width: 20%;"></a>
+<a href="https://fastapi.tiangolo.com"><img src="https://fastapi.tiangolo.com/img/logo-margin/logo-teal.png" style="width: 20%;"></a>
It follows the same design and ideas, and it was created to be the most intuitive way to interact with SQL databases in FastAPI applications.
It's all based on standard <abbr title="Currently supported versions of Python">modern **Python**</abbr> type annotations. No new syntax to learn. Just standard modern Python.
-If you need a 2 minute refresher of how to use Python types (even if you don't use SQLModel or FastAPI), check the FastAPI tutorial section: <a href="https://fastapi.tiangolo.com/python-types/" class="external-link" target="_blank">Python types intro</a>.
+If you need a 2 minute refresher of how to use Python types (even if you don't use SQLModel or FastAPI), check the FastAPI tutorial section: [Python types intro](https://fastapi.tiangolo.com/python-types/).
-You will also see a 20 seconds refresher on the section [Tutorial - User Guide: First Steps](tutorial/index.md){.internal-link target=_blank}.
+You will also see a 20 seconds refresher on the section [Tutorial - User Guide: First Steps](tutorial/index.md).
## Editor support
Here's how your editor might help you:
-* in <a href="https://code.visualstudio.com/" class="external-link" target="_blank">Visual Studio Code</a>:
+* in [Visual Studio Code](https://code.visualstudio.com/):
<img class="shadow" src="/img/index/autocompletion02.png">
-* in <a href="https://www.jetbrains.com/pycharm/" class="external-link" target="_blank">PyCharm</a>:
+* in [PyCharm](https://www.jetbrains.com/pycharm/):
<img class="shadow" src="/img/features/autocompletion01.png">
You won't need to keep guessing the types of different attributes in your models, if they could be `None`, etc. Your editor will be able to help you with everything because **SQLModel** is based on **standard Python type annotations**.
-**SQLModel** adopts <a href="https://peps.python.org/pep-0681/" class="external-link" target="_blank">PEP 681</a> for Python type annotations to ensure the **best developer experience**, so you will get inline errors and autocompletion even while creating new model instances.
+**SQLModel** adopts [PEP 681](https://peps.python.org/pep-0681/) for Python type annotations to ensure the **best developer experience**, so you will get inline errors and autocompletion even while creating new model instances.
<img class="shadow" src="/img/index/autocompletion01.png">
There was **a lot** of research and effort dedicated to make it that way. In particular, there was a lot of effort and experimentation in making a single model be **both a SQLAlchemy model and a Pydantic** model at the same time.
-That means that you get all the power, robustness, and certainty of SQLAlchemy, the <a href="https://lp.jetbrains.com/python-developers-survey-2024/#orms" class="external-link" target="_blank">most widely used database library in Python</a>.
+That means that you get all the power, robustness, and certainty of SQLAlchemy, the [most widely used database library in Python](https://lp.jetbrains.com/python-developers-survey-2024/#orms).
**SQLModel** provides its own utilities to <abbr title="with type completion, type checks, etc.">improve the developer experience</abbr>, but underneath, it uses all of SQLAlchemy.
## Subscribe to the FastAPI and Friends newsletter
-You can subscribe to the (infrequent) <a href="https://fastapi.tiangolo.com/newsletter" class="external-link" target="_blank">**FastAPI and friends** newsletter</a> to stay updated about:
+You can subscribe to the (infrequent) [**FastAPI and friends** newsletter](https://fastapi.tiangolo.com/newsletter) to stay updated about:
* News about FastAPI and friends, including SQLModel 🚀
* Guides 📝
## Star **SQLModel** in GitHub
-You can "star" SQLModel in GitHub (clicking the star button at the top right): <a href="https://github.com/fastapi/sqlmodel" class="external-link" target="_blank">https://github.com/fastapi/sqlmodel</a>. ⭐️
+You can "star" SQLModel in GitHub (clicking the star button at the top right): [https://github.com/fastapi/sqlmodel](https://github.com/fastapi/sqlmodel). ⭐️
By adding a star, other users will be able to find it more easily and see that it has been already useful for others.
## Watch the GitHub repository for releases
-You can "watch" SQLModel in GitHub (clicking the "watch" button at the top right): <a href="https://github.com/fastapi/sqlmodel" class="external-link" target="_blank">https://github.com/fastapi/sqlmodel</a>. 👀
+You can "watch" SQLModel in GitHub (clicking the "watch" button at the top right): [https://github.com/fastapi/sqlmodel](https://github.com/fastapi/sqlmodel). 👀
There you can select "Releases only".
## Connect with the author
-You can connect with <a href="https://tiangolo.com" class="external-link" target="_blank">me (Sebastián Ramírez / `tiangolo`)</a>, the author.
+You can connect with [me (Sebastián Ramírez / `tiangolo`)](https://tiangolo.com), the author.
You can:
-* <a href="https://github.com/tiangolo" class="external-link" target="_blank">Follow me on **GitHub**</a>.
+* [Follow me on **GitHub**](https://github.com/tiangolo).
* See other Open Source projects I have created that could help you.
* Follow me to see when I create a new Open Source project.
-* <a href="https://twitter.com/tiangolo" class="external-link" target="_blank">Follow me on **Twitter**</a>.
+* [Follow me on **Twitter**](https://twitter.com/tiangolo).
* Tell me how you use SQLModel (I love to hear that).
* Hear when I make announcements or release new tools.
-* <a href="https://www.linkedin.com/in/tiangolo/" class="external-link" target="_blank">Connect with me on **Linkedin**</a>.
+* [Connect with me on **Linkedin**](https://www.linkedin.com/in/tiangolo/).
* Hear when I make announcements or release new tools (although I use Twitter more often 🤷♂).
-* Read what I write (or follow me) on <a href="https://dev.to/tiangolo" class="external-link" target="_blank">**Dev.to**</a> or <a href="https://medium.com/@tiangolo" class="external-link" target="_blank">**Medium**</a>.
+* Read what I write (or follow me) on [**Dev.to**](https://dev.to/tiangolo) or [**Medium**](https://medium.com/@tiangolo).
* Read other ideas, articles, and read about tools I have created.
* Follow me to read when I publish something new.
## Tweet about **SQLModel**
-<a href="https://twitter.com/compose/tweet?text=I'm loving SQLModel because... https://github.com/fastapi/sqlmodel cc: @tiangolo" class="external-link" target="_blank">Tweet about **SQLModel**</a> and let me and others know why you like it. 🎉
+[Tweet about **SQLModel**](https://twitter.com/compose/tweet?text=I'm loving SQLModel because... https://github.com/fastapi/sqlmodel cc: @tiangolo) and let me and others know why you like it. 🎉
I love to hear about how **SQLModel** is being used, what you have liked in it, in which project/company are you using it, etc.
You can try and help others with their questions in:
-* <a href="https://github.com/fastapi/sqlmodel/discussions/categories/questions?discussions_q=category%3AQuestions+is%3Aunanswered" class="external-link" target="_blank">GitHub Discussions</a>
-* <a href="https://github.com/fastapi/sqlmodel/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3Aquestion+-label%3Aanswered+" class="external-link" target="_blank">GitHub Issues</a>
+* [GitHub Discussions](https://github.com/fastapi/sqlmodel/discussions/categories/questions?discussions_q=category%3AQuestions+is%3Aunanswered)
+* [GitHub Issues](https://github.com/fastapi/sqlmodel/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3Aquestion+-label%3Aanswered+)
In many cases you might already know the answer for those questions. 🤓
In many cases they will only copy a fragment of the code, but that's not enough to **reproduce the problem**.
-* You can ask them to provide a <a href="https://stackoverflow.com/help/minimal-reproducible-example" class="external-link" target="_blank">minimal, reproducible, example</a>, that you can **copy-paste** and run locally to see the same error or behavior they are seeing, or to understand their use case better.
+* You can ask them to provide a [minimal, reproducible, example](https://stackoverflow.com/help/minimal-reproducible-example), that you can **copy-paste** and run locally to see the same error or behavior they are seeing, or to understand their use case better.
* If you are feeling too generous, you can try to **create an example** like that yourself, just based on the description of the problem. Just have in mind that this might take a lot of time and it might be better to ask them to clarify the problem first.
## Watch the GitHub repository
-You can "watch" SQLModel in GitHub (clicking the "watch" button at the top right): <a href="https://github.com/fastapi/sqlmodel" class="external-link" target="_blank">https://github.com/fastapi/sqlmodel</a>. 👀
+You can "watch" SQLModel in GitHub (clicking the "watch" button at the top right): [https://github.com/fastapi/sqlmodel](https://github.com/fastapi/sqlmodel). 👀
If you select "Watching" instead of "Releases only" you will receive notifications when someone creates a new issue or question. You can also specify that you only want to be notified about new issues, or discussions, or PRs, etc.
## Ask Questions
-You can <a href="https://github.com/fastapi/sqlmodel/discussions/new?category=questions" class="external-link" target="_blank">create a new question</a> in the GitHub repository, for example to:
+You can [create a new question](https://github.com/fastapi/sqlmodel/discussions/new?category=questions) in the GitHub repository, for example to:
* Ask a **question** or ask about a **problem**.
* Suggest a new **feature**.
## Create a Pull Request
-You can [contribute](contributing.md){.internal-link target=_blank} to the source code with Pull Requests, for example:
+You can [contribute](contributing.md) to the source code with Pull Requests, for example:
* To fix a typo you found on the documentation.
* To propose new documentation sections.
The main tasks that you can do right now are:
-* [Help others with questions in GitHub](#help-others-with-questions-in-github){.internal-link target=_blank} (see the section above).
-* [Review Pull Requests](#review-pull-requests){.internal-link target=_blank} (see the section above).
+* [Help others with questions in GitHub](#help-others-with-questions-in-github) (see the section above).
+* [Review Pull Requests](#review-pull-requests) (see the section above).
Those two tasks are what **consume time the most**. That's the main work of maintaining SQLModel.
## Join the chat
-Join the 👥 <a href="https://discord.gg/VQjSZaeJmf" class="external-link" target="_blank">FastAPI and Friends Discord chat server</a> 👥 and hang out with others in the community. There's a `#sqlmodel` channel.
+Join the 👥 [FastAPI and Friends Discord chat server](https://discord.gg/VQjSZaeJmf) 👥 and hang out with others in the community. There's a `#sqlmodel` channel.
/// tip
-For questions, ask them in <a href="https://github.com/fastapi/sqlmodel/discussions/new?category=questions" class="external-link" target="_blank">GitHub Discussions</a>, there's a much better chance you will receive help there.
+For questions, ask them in [GitHub Discussions](https://github.com/fastapi/sqlmodel/discussions/new?category=questions), there's a much better chance you will receive help there.
Use the chat only for other general conversations.
## Sponsor the author
-You can also financially support the author (me) through <a href="https://github.com/sponsors/tiangolo" class="external-link" target="_blank">GitHub sponsors</a>.
+You can also financially support the author (me) through [GitHub sponsors](https://github.com/sponsors/tiangolo).
There you could buy me a coffee ☕️ to say thanks. 😄
You can also sponsor:
-* <a href="https://github.com/sponsors/samuelcolvin" class="external-link" target="_blank">Samuel Colvin (Pydantic)</a>
-* <a href="https://github.com/sponsors/sqlalchemy" class="external-link" target="_blank">SQLAlchemy</a>
+* [Samuel Colvin (Pydantic)](https://github.com/sponsors/samuelcolvin)
+* [SQLAlchemy](https://github.com/sponsors/sqlalchemy)
---
<em>SQLModel, SQL databases in Python, designed for simplicity, compatibility, and robustness.</em>
</p>
<p align="center">
-<a href="https://github.com/fastapi/sqlmodel/actions?query=workflow%3ATest+event%3Apush+branch%3Amain" target="_blank">
+<a href="https://github.com/fastapi/sqlmodel/actions?query=workflow%3ATest+event%3Apush+branch%3Amain">
<img src="https://github.com/fastapi/sqlmodel/actions/workflows/test.yml/badge.svg?event=push&branch=main" alt="Test">
</a>
-<a href="https://github.com/fastapi/sqlmodel/actions?query=workflow%3APublish" target="_blank">
+<a href="https://github.com/fastapi/sqlmodel/actions?query=workflow%3APublish">
<img src="https://github.com/fastapi/sqlmodel/actions/workflows/publish.yml/badge.svg" alt="Publish">
</a>
-<a href="https://coverage-badge.samuelcolvin.workers.dev/redirect/fastapi/sqlmodel" target="_blank">
+<a href="https://coverage-badge.samuelcolvin.workers.dev/redirect/fastapi/sqlmodel">
<img src="https://coverage-badge.samuelcolvin.workers.dev/fastapi/sqlmodel.svg" alt="Coverage">
-<a href="https://pypi.org/project/sqlmodel" target="_blank">
+<a href="https://pypi.org/project/sqlmodel">
<img src="https://img.shields.io/pypi/v/sqlmodel?color=%2334D058&label=pypi%20package" alt="Package version">
</a>
</p>
---
-**Documentation**: <a href="https://sqlmodel.tiangolo.com" target="_blank">https://sqlmodel.tiangolo.com</a>
+**Documentation**: [https://sqlmodel.tiangolo.com](https://sqlmodel.tiangolo.com)
-**Source Code**: <a href="https://github.com/fastapi/sqlmodel" target="_blank">https://github.com/fastapi/sqlmodel</a>
+**Source Code**: [https://github.com/fastapi/sqlmodel](https://github.com/fastapi/sqlmodel)
---
SQLModel is a library for interacting with <abbr title='Also called "Relational databases"'>SQL databases</abbr> from Python code, with Python objects. It is designed to be intuitive, easy to use, highly compatible, and robust.
-**SQLModel** is based on Python type annotations, and powered by <a href="https://pydantic-docs.helpmanual.io/" class="external-link" target="_blank">Pydantic</a> and <a href="https://sqlalchemy.org/" class="external-link" target="_blank">SQLAlchemy</a>.
+**SQLModel** is based on Python type annotations, and powered by [Pydantic](https://pydantic-docs.helpmanual.io/) and [SQLAlchemy](https://sqlalchemy.org/).
The key features are:
{% if sponsors %}
{% for sponsor in sponsors.gold -%}
-<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
+<a href="{{ sponsor.url }}" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
{% endfor -%}
{%- for sponsor in sponsors.silver -%}
-<a href="{{ sponsor.url }}" target="_blank" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
+<a href="{{ sponsor.url }}" title="{{ sponsor.title }}"><img src="{{ sponsor.img }}" style="border-radius:15px"></a>
{% endfor %}
{% endif %}
## SQL Databases in FastAPI
-<a href="https://fastapi.tiangolo.com" target="_blank"><img src="https://fastapi.tiangolo.com/img/logo-margin/logo-teal.png" style="width: 20%;"></a>
+<a href="https://fastapi.tiangolo.com"><img src="https://fastapi.tiangolo.com/img/logo-margin/logo-teal.png" style="width: 20%;"></a>
-**SQLModel** is designed to simplify interacting with SQL databases in <a href="https://fastapi.tiangolo.com" class="external-link" target="_blank">FastAPI</a> applications, it was created by the same <a href="https://tiangolo.com/" class="external-link" target="_blank">author</a>. 😁
+**SQLModel** is designed to simplify interacting with SQL databases in [FastAPI](https://fastapi.tiangolo.com) applications, it was created by the same [author](https://tiangolo.com/). 😁
It combines SQLAlchemy and Pydantic and tries to simplify the code you write as much as possible, allowing you to reduce the **code duplication to a minimum**, but while getting the **best developer experience** possible.
## Requirements
-A recent and currently supported <a href="https://www.python.org/downloads/" class="external-link" target="_blank">version of Python</a>.
+A recent and currently supported [version of Python](https://www.python.org/downloads/).
As **SQLModel** is based on **Pydantic** and **SQLAlchemy**, it requires them. They will be automatically installed when you install SQLModel.
## Installation
-Make sure you create a <a href="https://sqlmodel.tiangolo.com/virtual-environments/" class="external-link" target="_blank">virtual environment</a>, activate it, and then install SQLModel, for example with:
+Make sure you create a [virtual environment](https://sqlmodel.tiangolo.com/virtual-environments/), activate it, and then install SQLModel, for example with:
<div class="termy">
## Example
-For an introduction to databases, SQL, and everything else, see the <a href="https://sqlmodel.tiangolo.com/databases/" target="_blank">SQLModel documentation</a>.
+For an introduction to databases, SQL, and everything else, see the [SQLModel documentation](https://sqlmodel.tiangolo.com/databases/).
Here's a quick example. ✨
# Install **SQLModel**
-Create a project directory, create a [virtual environment](virtual-environments.md){.internal-link target=_blank}, activate it, and then install **SQLModel**, for example with:
+Create a project directory, create a [virtual environment](virtual-environments.md), activate it, and then install **SQLModel**, for example with:
<div class="termy">
</div>
-As **SQLModel** is built on top of <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>, when you install `sqlmodel` they will also be automatically installed.
+As **SQLModel** is built on top of [SQLAlchemy](https://www.sqlalchemy.org/) and [Pydantic](https://pydantic-docs.helpmanual.io/), when you install `sqlmodel` they will also be automatically installed.
## Install DB Browser for SQLite
-Remember that [SQLite is a simple database in a single file](databases.md#a-single-file-database){.internal-link target=_blank}?
+Remember that [SQLite is a simple database in a single file](databases.md#a-single-file-database)?
For most of the tutorial I'll use SQLite for the examples.
-Python has integrated support for SQLite, it is a single file read and processed from Python. And it doesn't need an [External Database Server](databases.md#a-server-database){.internal-link target=_blank}, so it will be perfect for learning.
+Python has integrated support for SQLite, it is a single file read and processed from Python. And it doesn't need an [External Database Server](databases.md#a-server-database), so it will be perfect for learning.
-In fact, SQLite is perfectly capable of handling quite big applications. At some point you might want to migrate to a server-based database like <a href="https://www.postgresql.org/" class="external-link" target="_blank">PostgreSQL</a> (which is also free). But for now we'll stick to SQLite.
+In fact, SQLite is perfectly capable of handling quite big applications. At some point you might want to migrate to a server-based database like [PostgreSQL](https://www.postgresql.org/) (which is also free). But for now we'll stick to SQLite.
Through the tutorial I will show you SQL fragments, and Python examples. And I hope (and expect 🧐) you to actually run them, and verify that the database is working as expected and showing you the same data.
-To be able to explore the SQLite file yourself, independent of Python code (and probably at the same time), I recommend you use <a href="https://sqlitebrowser.org/" class="external-link" target="_blank">DB Browser for SQLite</a>.
+To be able to explore the SQLite file yourself, independent of Python code (and probably at the same time), I recommend you use [DB Browser for SQLite](https://sqlitebrowser.org/).
It's a great and simple program to interact with SQLite databases (SQLite files) in a nice user interface.
<img src="https://sqlitebrowser.org/images/screenshot.png">
-Go ahead and <a href="https://sqlitebrowser.org/" class="external-link" target="_blank">Install DB Browser for SQLite</a>, it's free.
+Go ahead and [Install DB Browser for SQLite](https://sqlitebrowser.org/), it's free.
## Next Steps
# Repository Management Tasks
-These are the tasks that can be performed to manage the SQLModel repository by [team members](./management.md#team){.internal-link target=_blank}.
+These are the tasks that can be performed to manage the SQLModel repository by [team members](./management.md#team).
/// tip
///
-...so, you are a [team member of SQLModel](./management.md#team){.internal-link target=_blank}? Wow, you are so cool! 😎
+...so, you are a [team member of SQLModel](./management.md#team)? Wow, you are so cool! 😎
-You can help with everything on [Help SQLModel - Get Help](./help.md){.internal-link target=_blank} the same ways as external contributors. But additionally, there are some tasks that only you (as part of the team) can perform.
+You can help with everything on [Help SQLModel - Get Help](./help.md) the same ways as external contributors. But additionally, there are some tasks that only you (as part of the team) can perform.
Here are the general instructions for the tasks you can perform.
## Edit PR Titles
-* Edit the PR title to start with an emoji from <a href="https://gitmoji.dev/" class="external-link" target="_blank">gitmoji</a>.
+* Edit the PR title to start with an emoji from [gitmoji](https://gitmoji.dev/).
* Use the emoji character, not the GitHub code. So, use `🐛` instead of `:bug:`. This is so that it shows up correctly outside of GitHub, for example in the release notes.
* Start the title with a verb. For example `Add`, `Refactor`, `Fix`, etc. This way the title will say the action that the PR does. Like `Add support for teleporting`, instead of `Teleporting wasn't working, so this PR fixes it`.
* Edit the text of the PR title to start in "imperative", like giving an order. So, instead of `Adding support for teleporting` use `Add support for teleporting`.
* Try to make the title descriptive about what it achieves. If it's a feature, try to describe it, for example `Add support for teleporting` instead of `Create TeleportAdapter class`.
* Do not finish the title with a period (`.`).
-Once the PR is merged, a GitHub Action (<a href="https://github.com/tiangolo/latest-changes" class="external-link" target="_blank">latest-changes</a>) will use the PR title to update the latest changes automatically.
+Once the PR is merged, a GitHub Action ([latest-changes](https://github.com/tiangolo/latest-changes)) will use the PR title to update the latest changes automatically.
So, having a nice PR title will not only look nice in GitHub, but also in the release notes. 📝
## Add Labels to PRs
-The same GitHub Action <a href="https://github.com/tiangolo/latest-changes" class="external-link" target="_blank">latest-changes</a> uses one label in the PR to decide the section in the release notes to put this PR in.
+The same GitHub Action [latest-changes](https://github.com/tiangolo/latest-changes) uses one label in the PR to decide the section in the release notes to put this PR in.
-Make sure you use a supported label from the <a href="https://github.com/tiangolo/latest-changes#using-labels" class="external-link" target="_blank">latest-changes list of labels</a>:
+Make sure you use a supported label from the [latest-changes list of labels](https://github.com/tiangolo/latest-changes#using-labels):
* `breaking`: Breaking Changes
* Existing code will break if they update the version without changing their code. This rarely happens, so this label is not frequently used.
When a question in GitHub Discussions has been answered, mark the answer by clicking "Mark as answer".
-You can filter discussions by <a href="https://github.com/fastapi/sqlmodel/discussions/categories/questions?discussions_q=category:Questions+is:open+is:unanswered" class="external-link" target="_blank">`Questions` that are `Unanswered`</a>.
+You can filter discussions by [`Questions` that are `Unanswered`](https://github.com/fastapi/sqlmodel/discussions/categories/questions?discussions_q=category:Questions+is:open+is:unanswered).
## Owner
-I, <a href="https://github.com/tiangolo" target="_blank">@tiangolo</a>, am the creator and owner of the SQLModel repository. 🤓
+I, [@tiangolo](https://github.com/tiangolo), am the creator and owner of the SQLModel repository. 🤓
-I normally give the final review to each PR before merging them. I make the final decisions on the project, I'm the <a href="https://en.wikipedia.org/wiki/Benevolent_dictator_for_life" class="external-link" target="_blank"><abbr title="Benevolent Dictator For Life">BDFL</abbr></a>. 😅
+I normally give the final review to each PR before merging them. I make the final decisions on the project, I'm the [<abbr title="Benevolent Dictator For Life">BDFL</abbr>](https://en.wikipedia.org/wiki/Benevolent_dictator_for_life). 😅
## Team
There's a team of people that help manage and maintain the project. 😎
-They have different levels of permissions and [specific instructions](./management-tasks.md){.internal-link target=_blank}.
+They have different levels of permissions and [specific instructions](./management-tasks.md).
Some of the tasks they can perform include:
<div class="user-list user-list-center">
{% for user in members["members"] %}
-<div class="user"><a href="https://github.com/{{ user.login }}" target="_blank"><div class="avatar-wrapper"><img src="https://github.com/{{ user.login }}.png"/></div><div class="title">@{{ user.login }}</div></a></div>
+<div class="user"><a href="https://github.com/{{ user.login }}"><div class="avatar-wrapper"><img src="https://github.com/{{ user.login }}.png"/></div><div class="title">@{{ user.login }}</div></a></div>
{% endfor %}
</div>
External contributions are very welcome and appreciated, including answering questions, submitting PRs, etc. 🙇♂️
-There are many ways to [help maintain SQLModel](./help.md){.internal-link target=_blank}.
+There are many ways to [help maintain SQLModel](./help.md).
### Order Matters
-Remember that [Order Matters](create-db-and-table.md#sqlmodel-metadata-order-matters){.internal-link target=_blank} when calling `SQLModel.metadata.create_all()`?
+Remember that [Order Matters](create-db-and-table.md#sqlmodel-metadata-order-matters) when calling `SQLModel.metadata.create_all()`?
The point of that section in the docs is that you have to import the module that has the models **before** calling `SQLModel.metadata.create_all()`.
In SQLModel (actually in SQLAlchemy), all these functions and tools try to **replicate** how it would be to work with the **SQL** language.
-Remember that [`SELECT` defines the columns to get and `WHERE` how to filter them?](../where.md#select-and-where){.internal-link target=_blank}.
+Remember that [`SELECT` defines the columns to get and `WHERE` how to filter them?](../where.md#select-and-where).
This also applies here, but with `JOIN` and `ON`.
<img class="shadow" src="/img/create-db-and-table-with-db-browser/image001.png">
-A dialog should show up. Go to the [project directory you created](../virtual-environments.md#create-a-project){.internal-link target=_blank} and save the file with a name of `database.db`.
+A dialog should show up. Go to the [project directory you created](../virtual-environments.md#create-a-project) and save the file with a name of `database.db`.
/// tip
I will keep showing you small bits of SQL through this tutorial. And you don't have to be a SQL expert to use **SQLModel**.
-But if you are curious and want to get a quick overview of SQL, I recommend the visual documentation from SQLite, on <a href="https://www.sqlite.org/lang.html" class="external-link" target="_blank">SQL As Understood By SQLite</a>.
+But if you are curious and want to get a quick overview of SQL, I recommend the visual documentation from SQLite, on [SQL As Understood By SQLite](https://www.sqlite.org/lang.html).
-You can start with <a href="https://www.sqlite.org/lang_createtable.html" class="external-link" target="_blank">`CREATE TABLE`</a>.
+You can start with [`CREATE TABLE`](https://www.sqlite.org/lang_createtable.html).
Of course, you can also go and take a full SQL course or read a book about SQL, but you don't need more than what I'll explain here on the tutorial to start being productive with **SQLModel**. 🤓
Now let's get to the code. 👩💻
-Make sure you are inside of your project directory and with your virtual environment activated as explained in [Virtual Environments](../virtual-environments.md#create-a-project){.internal-link target=_blank}.
+Make sure you are inside of your project directory and with your virtual environment activated as explained in [Virtual Environments](../virtual-environments.md#create-a-project).
We will:
{* ./docs_src/tutorial/create_db_and_table/tutorial001_py310.py ln[1:16] hl[11:12,14] *}
-You can read a lot more about all the databases supported by **SQLAlchemy** (and that way supported by **SQLModel**) in the <a href="https://docs.sqlalchemy.org/en/14/core/engines.html" class="external-link" target="_blank">SQLAlchemy documentation</a>.
+You can read a lot more about all the databases supported by **SQLAlchemy** (and that way supported by **SQLModel**) in the [SQLAlchemy documentation](https://docs.sqlalchemy.org/en/14/core/engines.html).
### Engine Echo
///
-You can read a lot more about the engine in the <a href="https://docs.sqlalchemy.org/en/14/tutorial/engine.html" class="external-link" target="_blank">SQLAlchemy documentation</a>.
+You can read a lot more about the engine in the [SQLAlchemy documentation](https://docs.sqlalchemy.org/en/14/tutorial/engine.html).
**SQLModel** defines its own `create_engine()` function. It is the same as SQLAlchemy's `create_engine()`, but with the difference that it defaults to use `future=True` (which means that it uses the style of the latest SQLAlchemy, 1.4, and the future 2.0).
/// tip
-Remember to [activate the virtual environment](../virtual-environments.md#create-a-virtual-environment){.internal-link target=_blank} before running it.
+Remember to [activate the virtual environment](../virtual-environments.md#create-a-virtual-environment) before running it.
///
But in this output SQLAlchemy is using `VARCHAR` instead. Let's see what's going on.
-Remember that [each SQL Database has some different variations in what they support?](../databases.md#sql-the-language){.internal-link target=_blank}
+Remember that [each SQL Database has some different variations in what they support?](../databases.md#sql-the-language)
This is one of the differences. Each database supports some particular **data types**, like `INTEGER` and `TEXT`.
That `if` block using `if __name__ == "__main__":` is sometimes called the "**main block**".
-The official name (in the <a href="https://docs.python.org/3/library/__main__.html" class="external-link" target="_blank">Python docs</a>) is "**Top-level script environment**".
+The official name (in the [Python docs](https://docs.python.org/3/library/__main__.html)) is "**Top-level script environment**".
///
/// info
-For more information, check <a href="https://docs.python.org/3/library/__main__.html" class="external-link" target="_blank">the official Python docs</a>.
+For more information, check [the official Python docs](https://docs.python.org/3/library/__main__.html).
///
One of the use cases where **SQLModel** shines the most, and the main one why it was built, was to be combined with **FastAPI**. ✨
-<a href="https://fastapi.tiangolo.com/" class="external-link" target="_blank">FastAPI</a> is a Python web framework for building web APIs created by the same <a href="https://twitter.com/tiangolo" class="external-link" target="_blank">author</a> of SQLModel. FastAPI is also built on top of **Pydantic**.
+[FastAPI](https://fastapi.tiangolo.com/) is a Python web framework for building web APIs created by the same [author](https://twitter.com/tiangolo) of SQLModel. FastAPI is also built on top of **Pydantic**.
In this group of chapters we will see how to combine SQLModel **table models** representing tables in the SQL database as all the ones we have seen up to now, with **data models** that only represent data (which are actually just Pydantic models behind the scenes).
If you have never used FastAPI, maybe a good idea would be to go and study it a bit before continuing.
-Just reading and trying the examples on the <a href="https://fastapi.tiangolo.com/" class="external-link" target="_blank">FastAPI main page</a> should be enough, and it shouldn't take you more than **10 minutes**.
+Just reading and trying the examples on the [FastAPI main page](https://fastapi.tiangolo.com/) should be enough, and it shouldn't take you more than **10 minutes**.
If you need to refresh how query parameters and their validation work, check out the docs in FastAPI:
-* <a href="https://fastapi.tiangolo.com/tutorial/query-params/" class="external-link" target="_blank">Query Parameters</a>
-* <a href="https://fastapi.tiangolo.com/tutorial/query-params-str-validations/" class="external-link" target="_blank">Query Parameters and String Validations</a>
-* <a href="https://fastapi.tiangolo.com/tutorial/path-params-numeric-validations/" class="external-link" target="_blank">Path Parameters and Numeric Validations</a>
+* [Query Parameters](https://fastapi.tiangolo.com/tutorial/query-params/)
+* [Query Parameters and String Validations](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/)
+* [Path Parameters and Numeric Validations](https://fastapi.tiangolo.com/tutorial/path-params-numeric-validations/)
///
This filtering could be very important and could be a very good security feature, for example, to make sure you filter private data, hashed passwords, etc.
-You can read more about it in the <a href="https://fastapi.tiangolo.com/tutorial/response-model/" class="external-link" target="_blank">FastAPI docs about Response Model</a>.
+You can read more about it in the [FastAPI docs about Response Model](https://fastapi.tiangolo.com/tutorial/response-model/).
///
/// info
-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>.
+If you need to refresh how *path parameters* work, including their data validation, check the [FastAPI docs about Path Parameters](https://fastapi.tiangolo.com/tutorial/path-params/).
///
{* ./docs_src/tutorial/fastapi/teams/tutorial001_py310.py ln[5:7,20:21,29:34,43:44] hl[5:7,20:21,29:34,43:44] *}
-Now, remember that <a href="https://fastapi.tiangolo.com/tutorial/response-model/" class="external-link" target="_blank">FastAPI uses the `response_model` to validate and **filter** the response data</a>?
+Now, remember that [FastAPI uses the `response_model` to validate and **filter** the response data](https://fastapi.tiangolo.com/tutorial/response-model/)?
In this case, we used `response_model=TeamPublic` and `response_model=HeroPublic`, so FastAPI will use them to filter the response data, even if we return a **table model** that includes **relationship attributes**:
<img class="shadow" alt="Interactive API docs UI" src="/img/tutorial/fastapi/simple-hero-api/image01.png">
-This interactive docs UI is powered by <a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a>, and what Swagger UI does is to read a big JSON content that defines the API with all the data schemas (data shapes) using the standard <a href="https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md" class="external-link" target="_blank">OpenAPI</a>, and showing it in that nice <abbr title="User Interface">UI</abbr>.
+This interactive docs UI is powered by [Swagger UI](https://github.com/swagger-api/swagger-ui), and what Swagger UI does is to read a big JSON content that defines the API with all the data schemas (data shapes) using the standard [OpenAPI](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md), and showing it in that nice <abbr title="User Interface">UI</abbr>.
FastAPI automatically **generates that OpenAPI** for Swagger UI to read it.
So this works like a contract between our application and the client.
-You can read more about it in the <a href="https://fastapi.tiangolo.com/tutorial/response-model/" class="external-link" target="_blank">FastAPI docs about `response_model`</a>.
+You can read more about it in the [FastAPI docs about `response_model`](https://fastapi.tiangolo.com/tutorial/response-model/).
## New API Docs UI
The most visible advantage of using the `response_model` is that it shows up in the API docs UI.
-But there are other advantages, like that FastAPI will do automatic <a href="https://fastapi.tiangolo.com/tutorial/response-model/" class="external-link" target="_blank">data validation and filtering</a> of the response data using this model.
+But there are other advantages, like that FastAPI will do automatic [data validation and filtering](https://fastapi.tiangolo.com/tutorial/response-model/) of the response data using this model.
Additionally, because the schemas are defined in using a standard, there are many tools that can take advantage of this.
If you are curious about the standards, FastAPI generates OpenAPI, that internally uses JSON Schema.
-You can read about all that in the <a href="https://fastapi.tiangolo.com/tutorial/first-steps/#openapi" class="external-link" target="_blank">FastAPI docs - First Steps</a>.
+You can read about all that in the [FastAPI docs - First Steps](https://fastapi.tiangolo.com/tutorial/first-steps/#openapi).
///
{* ./docs_src/tutorial/fastapi/delete/tutorial001_py310.py ln[48:55] hl[50] *}
-That's perfectly fine, but in many use cases we would want to use <a href="https://fastapi.tiangolo.com/tutorial/dependencies/" class="external-link" target="_blank">FastAPI Dependencies</a>, for example to **verify** that the client is **logged in** and get the **current user** before executing any other code in the *path operation*.
+That's perfectly fine, but in many use cases we would want to use [FastAPI Dependencies](https://fastapi.tiangolo.com/tutorial/dependencies/), for example to **verify** that the client is **logged in** and get the **current user** before executing any other code in the *path operation*.
These dependencies are also very useful during **testing**, because we can **easily replace them**, and then, for example, use a new database for our tests, or put some data before the tests, etc.
Python would normally complain about that, but we can use the initial "parameter" `*,` to mark all the rest of the parameters as "keyword only", which solves the problem.
-You can read more about it in the FastAPI documentation <a href="https://fastapi.tiangolo.com/tutorial/path-params-numeric-validations/#order-the-parameters-as-you-need-tricks" class="external-link" target="_blank">Path Parameters and Numeric Validations - Order the parameters as you need, tricks</a>
+You can read more about it in the FastAPI documentation [Path Parameters and Numeric Validations - Order the parameters as you need, tricks](https://fastapi.tiangolo.com/tutorial/path-params-numeric-validations/#order-the-parameters-as-you-need-tricks)
///
And you will see how much these dependencies can help the more you work with FastAPI, to handle **permissions**, **authentication**, resources like database **sessions**, etc. 🚀
-If you want to learn more about dependencies, checkout the <a href="https://fastapi.tiangolo.com/tutorial/dependencies/" class="external-link" target="_blank">FastAPI docs about Dependencies</a>.
+If you want to learn more about dependencies, checkout the [FastAPI docs about Dependencies](https://fastapi.tiangolo.com/tutorial/dependencies/).
FastAPI is the framework to create the **web API**.
-Make sure you create a [virtual environment](../../virtual-environments.md){.internal-link target=_blank}, activate it, and then install them, for example with:
+Make sure you create a [virtual environment](../../virtual-environments.md), activate it, and then install them, for example with:
<div class="termy">
/// info
-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>.
+That's enough information for now, you can read more about it in the [FastAPI docs for `async` and `await`](https://fastapi.tiangolo.com/async/).
The main point is, by ensuring you **don't share** the same **session** with more than one request, the code is already safe.
/// info
-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>.
+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 [FastAPI First Steps docs](https://fastapi.tiangolo.com/tutorial/first-steps/).
///
If you need a refresher on some of those concepts, checkout the FastAPI documentation:
-* <a href="https://fastapi.tiangolo.com/tutorial/first-steps/" class="external-link" target="_blank">First Steps</a>
-* <a href="https://fastapi.tiangolo.com/tutorial/path-params/" class="external-link" target="_blank">Path Parameters - Data Validation and Data Conversion</a>
-* <a href="https://fastapi.tiangolo.com/tutorial/body/" class="external-link" target="_blank">Request Body</a>
+* [First Steps](https://fastapi.tiangolo.com/tutorial/first-steps/)
+* [Path Parameters - Data Validation and Data Conversion](https://fastapi.tiangolo.com/tutorial/path-params/)
+* [Request Body](https://fastapi.tiangolo.com/tutorial/body/)
///
In this simple example, we just create the new sessions manually in the **path operation functions**.
-In future examples later we will use a <a href="https://fastapi.tiangolo.com/tutorial/dependencies/" class="external-link" target="_blank">FastAPI Dependency</a> to get the **session**, being able to share it with other dependencies and being able to replace it during testing. 🤓
+In future examples later we will use a [FastAPI Dependency](https://fastapi.tiangolo.com/tutorial/dependencies/) to get the **session**, being able to share it with other dependencies and being able to replace it during testing. 🤓
## Run the **FastAPI** Server in Development Mode
/// info
-The `fastapi` command uses <a href="https://www.uvicorn.org/" class="external-link" target="_blank">Uvicorn</a> underneath.
+The `fastapi` command uses [Uvicorn](https://www.uvicorn.org/) underneath.
///
Now you can go to that URL in your browser `http://127.0.0.1:8000`. We didn't create a *path operation* for the root path `/`, so that URL alone will only show a "Not Found" error... that "Not Found" error is produced by your FastAPI application.
-But you can go to the **automatically generated interactive API documentation** at the path `/docs`: <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>. ✨
+But you can go to the **automatically generated interactive API documentation** at the path `/docs`: [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs). ✨
You will see that this **automatic API docs <abbr title="user interface">UI</abbr>** has the *paths* that we defined above with their *operations*, and that it already knows the shape of the data that the **path operations** will receive:
## File Structure
-Now we will have a Python project with multiple files, one file `main.py` with all the application, and one file `test_main.py` with the tests, with the same ideas from [Code Structure and Multiple Files](../code-structure.md){.internal-link target=_blank}.
+Now we will have a Python project with multiple files, one file `main.py` with all the application, and one file `test_main.py` with the tests, with the same ideas from [Code Structure and Multiple Files](../code-structure.md).
The file structure is:
## Testing FastAPI Applications
-If you haven't done testing in FastAPI applications, first check the <a href="https://fastapi.tiangolo.com/tutorial/testing/" class="external-link" target="_blank">FastAPI docs about Testing</a>.
+If you haven't done testing in FastAPI applications, first check the [FastAPI docs about Testing](https://fastapi.tiangolo.com/tutorial/testing/).
Then, we can continue here, the first step is to install the dependencies, `requests` and `pytest`.
-Make sure you create a [virtual environment](../../virtual-environments.md){.internal-link target=_blank}, activate it, and then install them, for example with:
+Make sure you create a [virtual environment](../../virtual-environments.md), activate it, and then install them, for example with:
<div class="termy">
SQLModel.metadata.create_all(engine)
```
-But remember that [Order Matters](../create-db-and-table.md#sqlmodel-metadata-order-matters){.internal-link target=_blank} and we need to make sure all the **SQLModel** models are already defined and **imported** before calling `.create_all()`.
+But remember that [Order Matters](../create-db-and-table.md#sqlmodel-metadata-order-matters) and we need to make sure all the **SQLModel** models are already defined and **imported** before calling `.create_all()`.
In this case, it all works for a little subtlety that deserves some attention.
## Pytest Fixtures
-You can read more about them in the <a href="https://docs.pytest.org/en/6.2.x/fixture.html" class="external-link" target="_blank">pytest docs for fixtures</a>, but I'll give you a short example for what we need here.
+You can read more about them in the [pytest docs for fixtures](https://docs.pytest.org/en/6.2.x/fixture.html), but I'll give you a short example for what we need here.
Let's see the first code example with a fixture:
/// tip
-You could use <a href="https://passlib.readthedocs.io/en/stable/" class="external-link" target="_blank">passlib</a> to hash passwords.
+You could use [passlib](https://passlib.readthedocs.io/en/stable/) to hash passwords.
In this example we will use a fake hashing function to focus on the data changes. 🤡
## Type hints
-If you need a refresher about how to use Python type hints (type annotations), check <a href="https://fastapi.tiangolo.com/python-types/" class="external-link" target="_blank">FastAPI's Python types intro</a>.
+If you need a refresher about how to use Python type hints (type annotations), check [FastAPI's Python types intro](https://fastapi.tiangolo.com/python-types/).
-You can also check the <a href="https://mypy.readthedocs.io/en/latest/cheat_sheet_py3.html" class="external-link" target="_blank">mypy cheat sheet</a>.
+You can also check the [mypy cheat sheet](https://mypy.readthedocs.io/en/latest/cheat_sheet_py3.html).
**SQLModel** uses type annotations for everything, this way you can use a familiar Python syntax and get all the editor support possible, with autocompletion and in-editor error checking.
## Link Primary Key
-Cool, we have a link table with **just two columns**. But remember that SQL databases [require each row to have a **primary key**](../../databases.md#identifications-primary-key){.internal-link target=_blank} that **uniquely identifies** the row in that table?
+Cool, we have a link table with **just two columns**. But remember that SQL databases [require each row to have a **primary key**](../../databases.md#identifications-primary-key) that **uniquely identifies** the row in that table?
Now, what is the **primary key** in this table?
Setting `cascade_delete=True` in the `Relationship()` will configure SQLAlchemy to use `cascade="all, delete-orphan"`, which is the most common and useful configuration when wanting to cascade deletes.
-You can read more about it in the <a href="https://docs.sqlalchemy.org/en/20/orm/cascades.html" class="external-link" target="_blank">SQLAlchemy docs</a>.
+You can read more about it in the [SQLAlchemy docs](https://docs.sqlalchemy.org/en/20/orm/cascades.html).
///
/// info
-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>.
+You can learn more about SQLite, foreign keys, and this SQL command on the [SQLAlchemy docs](https://docs.sqlalchemy.org/en/20/dialects/sqlite.html#foreign-key-support).
///
/// tip
You need to wrap your attribute with `col()` to use `in_`.
-You can read more about it in the [Type annotations and errors](#type-annotations-and-errors){.internal-link target=_blank} section.
+You can read more about it in the [Type annotations and errors](#type-annotations-and-errors) section.
///
This page will teach you how to use **virtual environments** and how they work.
-If you are ready to adopt a **tool that manages everything** for you (including installing Python), try <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">uv</a>.
+If you are ready to adopt a **tool that manages everything** for you (including installing Python), try [uv](https://github.com/astral-sh/uv).
///
//// tab | `uv`
-If you have <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">`uv`</a> installed, you can use it to create a virtual environment.
+If you have [`uv`](https://github.com/astral-sh/uv) installed, you can use it to create a virtual environment.
<div class="termy">
//// tab | Windows Bash
-Or if you use Bash for Windows (e.g. <a href="https://gitforwindows.org/" class="external-link" target="_blank">Git Bash</a>):
+Or if you use Bash for Windows (e.g. [Git Bash](https://gitforwindows.org/)):
<div class="termy">
/// tip
-If you use <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">`uv`</a> you would use it to install things instead of `pip`, so you don't need to upgrade `pip`. 😎
+If you use [`uv`](https://github.com/astral-sh/uv) you would use it to install things instead of `pip`, so you don't need to upgrade `pip`. 😎
///
/// tip
-If you used <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">`uv`</a> to create the virtual environment, it already did this for you, you can skip this step. 😎
+If you used [`uv`](https://github.com/astral-sh/uv) to create the virtual environment, it already did this for you, you can skip this step. 😎
///
//// tab | `uv`
-If you have <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">`uv`</a>:
+If you have [`uv`](https://github.com/astral-sh/uv):
<div class="termy">
//// tab | `uv`
-If you have <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">`uv`</a>:
+If you have [`uv`](https://github.com/astral-sh/uv):
<div class="termy">
For example:
-* <a href="https://code.visualstudio.com/docs/python/environments#_select-and-activate-an-environment" class="external-link" target="_blank">VS Code</a>
-* <a href="https://www.jetbrains.com/help/pycharm/creating-virtual-environment.html" class="external-link" target="_blank">PyCharm</a>
+* [VS Code](https://code.visualstudio.com/docs/python/environments#_select-and-activate-an-environment)
+* [PyCharm](https://www.jetbrains.com/help/pycharm/creating-virtual-environment.html)
/// tip
## Why Virtual Environments
-To work with SQLModel you need to install <a href="https://www.python.org/" class="external-link" target="_blank">Python</a>.
+To work with SQLModel you need to install [Python](https://www.python.org/).
After that, you would need to **install** SQLModel and any other **packages** you want to use.
</div>
-That will download a compressed file with the SQLModel code, normally from <a href="https://pypi.org/project/sqlmodel/" class="external-link" target="_blank">PyPI</a>.
+That will download a compressed file with the SQLModel code, normally from [PyPI](https://pypi.org/project/sqlmodel/).
It will also **download** files for other packages that SQLModel depends on.
//// tab | Windows Bash
-Or if you use Bash for Windows (e.g. <a href="https://gitforwindows.org/" class="external-link" target="_blank">Git Bash</a>):
+Or if you use Bash for Windows (e.g. [Git Bash](https://gitforwindows.org/)):
<div class="termy">
////
-That command will create or modify some [environment variables](environment-variables.md){.internal-link target=_blank} that will be available for the next commands.
+That command will create or modify some [environment variables](environment-variables.md) that will be available for the next commands.
One of those variables is the `PATH` variable.
/// tip
-You can learn more about the `PATH` environment variable in the [Environment Variables](environment-variables.md#path-environment-variable){.internal-link target=_blank} section.
+You can learn more about the `PATH` environment variable in the [Environment Variables](environment-variables.md#path-environment-variable) section.
///
There are many **alternatives** to managing virtual environments, package dependencies (requirements), projects.
-Once you are ready and want to use a tool to **manage the entire project**, packages dependencies, virtual environments, etc. I would suggest you try <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">uv</a>.
+Once you are ready and want to use a tool to **manage the entire project**, packages dependencies, virtual environments, etc. I would suggest you try [uv](https://github.com/astral-sh/uv).
`uv` can do a lot of things, it can: