mirror of
https://github.com/fastapi/sqlmodel.git
synced 2026-03-13 09:29:54 +08:00
📝 Update link syntax to minimal Markdown
This commit is contained in:
@@ -91,7 +91,7 @@ Here we import the models, the engine, and the function to create all the tables
|
||||
|
||||
### 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()`.
|
||||
|
||||
|
||||
@@ -413,7 +413,7 @@ And then why we didn't include `Hero` in the `.join()`. 🤔
|
||||
|
||||
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`.
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ Click the button <kbd>New Database</kbd>.
|
||||
|
||||
<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
|
||||
|
||||
@@ -159,9 +159,9 @@ And if you go back to the <kbd>Database Structure</kbd> tab, you will see that y
|
||||
|
||||
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**. 🤓
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
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:
|
||||
|
||||
@@ -176,7 +176,7 @@ SQLite supports a special database that lives all *in memory*. Hence, it's very
|
||||
|
||||
{* ./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
|
||||
|
||||
@@ -202,7 +202,7 @@ If you didn't know about SQLAlchemy before and are just learning **SQLModel**, y
|
||||
|
||||
///
|
||||
|
||||
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).
|
||||
|
||||
@@ -327,7 +327,7 @@ Put the code in a file `app.py` if you haven't already.
|
||||
|
||||
/// 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.
|
||||
|
||||
///
|
||||
|
||||
@@ -390,7 +390,7 @@ In the example in the previous chapter we created the table using `TEXT` for som
|
||||
|
||||
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`.
|
||||
|
||||
@@ -484,7 +484,7 @@ from app import Hero
|
||||
|
||||
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**".
|
||||
|
||||
///
|
||||
|
||||
@@ -540,7 +540,7 @@ if __name__ == "__main__":
|
||||
|
||||
/// 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).
|
||||
|
||||
///
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
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).
|
||||
|
||||
@@ -14,4 +14,4 @@ By the end we will have a **simple** but **complete** web **API** to interact wi
|
||||
|
||||
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**.
|
||||
|
||||
@@ -36,9 +36,9 @@ This way, a client can decide to take fewer heroes if they want, but not more.
|
||||
|
||||
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/)
|
||||
|
||||
///
|
||||
|
||||
|
||||
@@ -167,7 +167,7 @@ This will validate that all the data that we promised is there and will remove a
|
||||
|
||||
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/).
|
||||
|
||||
///
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ We want to get the hero based on the `id`, so we will use a **path parameter** `
|
||||
|
||||
/// 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/).
|
||||
|
||||
///
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ And the same way, we declared the `TeamPublic` with only the same base fields of
|
||||
|
||||
{* ./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**:
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ Up to now, with the code we have used, the API docs know the data the clients ha
|
||||
|
||||
<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.
|
||||
|
||||
@@ -48,7 +48,7 @@ FastAPI will do data validation and filtering of the response with this `respons
|
||||
|
||||
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
|
||||
|
||||
@@ -62,7 +62,7 @@ The clients will know what data they should expect.
|
||||
|
||||
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.
|
||||
|
||||
@@ -72,7 +72,7 @@ For example, client generators, that can automatically create the code necessary
|
||||
|
||||
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).
|
||||
|
||||
///
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ Up to now, we have been creating a session in each *path operation*, in a `with`
|
||||
|
||||
{* ./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.
|
||||
|
||||
@@ -38,7 +38,7 @@ Here we are passing the parameter `session` that has a "default value" of `Depen
|
||||
|
||||
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)
|
||||
|
||||
///
|
||||
|
||||
@@ -86,4 +86,4 @@ You just learned how to use **FastAPI dependencies** to handle the database sess
|
||||
|
||||
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/).
|
||||
|
||||
@@ -8,7 +8,7 @@ The first step is to install FastAPI.
|
||||
|
||||
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">
|
||||
|
||||
@@ -42,7 +42,7 @@ And we also need to disable it because in **FastAPI** each request could be hand
|
||||
|
||||
/// 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.
|
||||
|
||||
@@ -70,7 +70,7 @@ This should be called only once at startup, not before every request, so we put
|
||||
|
||||
/// 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/).
|
||||
|
||||
///
|
||||
|
||||
@@ -84,9 +84,9 @@ It will be called when a user sends a request with a `POST` **operation** to the
|
||||
|
||||
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/)
|
||||
|
||||
///
|
||||
|
||||
@@ -132,7 +132,7 @@ But we would **never want to *share* the same session** among different requests
|
||||
|
||||
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
|
||||
|
||||
@@ -154,7 +154,7 @@ $ fastapi dev main.py
|
||||
|
||||
/// 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.
|
||||
|
||||
///
|
||||
|
||||
@@ -180,7 +180,7 @@ $ fastapi run main.py
|
||||
|
||||
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:
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ Now we will see how useful it is to have this session dependency. ✨
|
||||
|
||||
## 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:
|
||||
|
||||
@@ -32,11 +32,11 @@ 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">
|
||||
|
||||
@@ -144,7 +144,7 @@ Here we create all the tables in the testing database with:
|
||||
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.
|
||||
|
||||
@@ -230,7 +230,7 @@ Let's use these **fixtures** to improve our code and reduce de duplicated boiler
|
||||
|
||||
## 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:
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ So, the thief won't be able to try to use that password in another system (as ma
|
||||
|
||||
/// 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. 🤡
|
||||
|
||||
|
||||
@@ -4,9 +4,9 @@ In this tutorial you will learn how to use **SQLModel**.
|
||||
|
||||
## 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.
|
||||
|
||||
|
||||
@@ -128,7 +128,7 @@ I'm using the term "link table" because it's short, doesn't collide with other t
|
||||
|
||||
## 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?
|
||||
|
||||
|
||||
@@ -129,7 +129,7 @@ The `cascade_delete` parameter is set in the `Relationship()`, on the model that
|
||||
|
||||
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).
|
||||
|
||||
///
|
||||
|
||||
@@ -442,7 +442,7 @@ To be able to test this out with SQLite, we first need to enable foreign key sup
|
||||
|
||||
/// 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).
|
||||
|
||||
///
|
||||
|
||||
|
||||
@@ -591,7 +591,7 @@ We don't have any hero called `Ratman`, so it does not match any hero.
|
||||
/// 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.
|
||||
|
||||
///
|
||||
|
||||
|
||||
Reference in New Issue
Block a user