diff --git a/docs/en/docs/tutorial/sql-databases.md b/docs/en/docs/tutorial/sql-databases.md index eac86f7fb..3f3f11943 100644 --- a/docs/en/docs/tutorial/sql-databases.md +++ b/docs/en/docs/tutorial/sql-databases.md @@ -55,7 +55,7 @@ Later we'll improve it increasing security and versatility with **multiple model Import `SQLModel` and create a database model: -{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[1:11] hl[7:11] *} +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[1:12] hl[8:12] *} The `Hero` class is very similar to a Pydantic model (in fact, underneath, it actually *is a Pydantic model*). @@ -77,7 +77,7 @@ A SQLModel `engine` (underneath it's actually a SQLAlchemy `engine`) is what **h You would have **one single `engine` object** for all your code to connect to the same database. -{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[14:18] hl[14:15,17:18] *} +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[15:19] hl[15:16,18:19] *} Using `check_same_thread=False` allows FastAPI to use the same SQLite database in different threads. This is necessary as **one single request** could use **more than one thread** (for example in dependencies). @@ -87,7 +87,7 @@ Don't worry, with the way the code is structured, we'll make sure we use **a sin We then add a function that uses `SQLModel.metadata.create_all(engine)` to **create the tables** for all the *table models*. -{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[21:22] hl[21:22] *} +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[21:23] hl[22:23] *} ### Create a Session Dependency @@ -97,18 +97,28 @@ We will create a FastAPI **dependency** with `yield` that will provide a new `Se Then we create an `Annotated` dependency `SessionDep` to simplify the rest of the code that will use this dependency. -{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[25:30] hl[25:27,30] *} +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[26:31] hl[26:28,31] *} ### Create Database Tables on Startup We will create the database tables when the application starts. -{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[32:37] hl[35:37] *} +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[34:42] hl[34:37, 42] *} Here we create the tables on an application startup event. For production you would probably use a migration script that runs before you start your app. 🤓 + +/// warning + +The `@app.on_event("startup")` and `@app.on_event("shutdown")` decorators are **deprecated** as of FastAPI v0.103.0. + +Use the `lifespan` parameter in the `FastAPI` class instead for lifecycle management. + +/// + + /// tip SQLModel will have migration utilities wrapping Alembic, but for now, you can use Alembic directly. @@ -123,7 +133,7 @@ For example, if you declare a parameter of type `Hero`, it will be read from the The same way, you can declare it as the function's **return type**, and then the shape of the data will show up in the automatic API docs UI. -{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[40:45] hl[40:45] *} +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[45:50] hl[45:50] *} Here we use the `SessionDep` dependency (a `Session`) to add the new `Hero` to the `Session` instance, commit the changes to the database, refresh the data in the `hero`, and then return it. @@ -131,19 +141,19 @@ Here we use the `SessionDep` dependency (a `Session`) to add the new `Hero` to t We can **read** `Hero`s from the database using a `select()`. We can include a `limit` and `offset` to paginate the results. -{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[48:55] hl[51:52,54] *} +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[53:60] hl[56:57,59] *} ### Read One Hero We can **read** a single `Hero`. -{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[58:63] hl[60] *} +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[63:68] hl[65] *} ### Delete a Hero We can also **delete** a `Hero`. -{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[66:73] hl[71] *} +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[71:78] hl[76] *} ### Run the App @@ -192,7 +202,7 @@ Let's start with a `HeroBase` model that has all the **fields that are shared** * `name` * `age` -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:9] hl[7:9] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[8:10] hl[8:10] *} #### `Hero` - the *table model* @@ -208,7 +218,7 @@ Because `Hero` inherits form `HeroBase`, it **also** has the **fields** declared * `age` * `secret_name` -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:14] hl[12:14] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[8:15] hl[13:15] *} #### `HeroPublic` - the public *data model* @@ -234,7 +244,7 @@ All the fields in `HeroPublic` are the same as in `HeroBase`, with `id` declared * `name` * `age` -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:18] hl[17:18] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[8:19] hl[18:19] *} #### `HeroCreate` - the *data model* to create a hero @@ -258,7 +268,7 @@ The fields of `HeroCreate` are: * `age` * `secret_name` -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:22] hl[21:22] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[8:23] hl[22:23] *} #### `HeroUpdate` - the *data model* to update a hero @@ -276,7 +286,7 @@ The fields of `HeroUpdate` are: * `age` * `secret_name` -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:28] hl[25:28] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[8:29] hl[26:29] *} ### Create with `HeroCreate` and return a `HeroPublic` @@ -288,7 +298,7 @@ This new *table model* `Hero` will have the fields sent by the client, and will Then we return the same *table model* `Hero` as is from the function. But as we declare the `response_model` with the `HeroPublic` *data model*, **FastAPI** will use `HeroPublic` to validate and serialize the data. -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[56:62] hl[56:58] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[61:67] hl[61:63] *} /// tip @@ -304,13 +314,13 @@ By declaring it in `response_model` we are telling **FastAPI** to do its thing, We can do the same as before to **read** `Hero`s, again, we use `response_model=list[HeroPublic]` to ensure that the data is validated and serialized correctly. -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[65:72] hl[65] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[70:77] hl[70] *} ### Read One Hero with `HeroPublic` We can **read** a single hero: -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[75:80] hl[77] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[80:85] hl[82] *} ### Update a Hero with `HeroUpdate` @@ -320,7 +330,7 @@ And in the code, we get a `dict` with all the data sent by the client, **only th Then we use `hero_db.sqlmodel_update(hero_data)` to update the `hero_db` with the data from `hero_data`. -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[83:93] hl[83:84,88:89] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[88:98] hl[88:89,93:94] *} ### Delete a Hero Again @@ -328,7 +338,7 @@ Then we use `hero_db.sqlmodel_update(hero_data)` to update the `hero_db` with th We won't satisfy the desire to refactor everything in this one. 😅 -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[96:103] hl[101] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[101:108] hl[106] *} ### Run the App Again diff --git a/docs/es/docs/tutorial/sql-databases.md b/docs/es/docs/tutorial/sql-databases.md index 68cc78603..bae21edc6 100644 --- a/docs/es/docs/tutorial/sql-databases.md +++ b/docs/es/docs/tutorial/sql-databases.md @@ -55,7 +55,7 @@ Más adelante la mejoraremos aumentando la seguridad y versatilidad con **múlti Importa `SQLModel` y crea un modelo de base de datos: -{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[1:11] hl[7:11] *} +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[1:12] hl[8:12] *} La clase `Hero` es muy similar a un modelo de Pydantic (de hecho, en el fondo, realmente *es un modelo de Pydantic*). @@ -77,8 +77,7 @@ Un `engine` de SQLModel (en el fondo, realmente es un `engine` de SQLAlchemy) es Tendrías **un solo objeto `engine`** para todo tu código para conectar a la misma base de datos. -{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[14:18] hl[14:15,17:18] *} - +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[15:19] hl[15:16,18:19] *} Usar `check_same_thread=False` permite a FastAPI usar la misma base de datos SQLite en diferentes hilos. Esto es necesario ya que **una sola request** podría usar **más de un hilo** (por ejemplo, en dependencias). No te preocupes, con la forma en que está estructurado el código, nos aseguraremos de usar **una sola *session* de SQLModel por request** más adelante, esto es realmente lo que intenta lograr el `check_same_thread`. @@ -87,7 +86,7 @@ No te preocupes, con la forma en que está estructurado el código, nos asegurar Luego añadimos una función que usa `SQLModel.metadata.create_all(engine)` para **crear las tablas** para todos los *modelos de tabla*. -{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[21:22] hl[21:22] *} +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[21:23] hl[22:23] *} ### Crear una Dependencia de Session @@ -97,13 +96,13 @@ Crearemos una **dependencia de FastAPI** con `yield` que proporcionará una nuev Luego creamos una dependencia `Annotated` `SessionDep` para simplificar el resto del código que usará esta dependencia. -{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[25:30] hl[25:27,30] *} +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[26:31] hl[26:28,31] *} ### Crear Tablas de Base de Datos al Arrancar Crearemos las tablas de la base de datos cuando arranque la aplicación. -{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[32:37] hl[35:37] *} +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[34:42] hl[34:37, 42] *} Aquí creamos las tablas en un evento de inicio de la aplicación. @@ -123,7 +122,7 @@ Por ejemplo, si declaras un parámetro de tipo `Hero`, será leído desde el **J De la misma manera, puedes declararlo como el **tipo de retorno** de la función, y luego la forma de los datos aparecerá en la interfaz automática de documentación de la API. -{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[40:45] hl[40:45] *} +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[45:50] hl[45:50] *} @@ -133,19 +132,19 @@ Aquí usamos la dependencia `SessionDep` (una `Session`) para añadir el nuevo ` Podemos **leer** `Hero`s de la base de datos usando un `select()`. Podemos incluir un `limit` y `offset` para paginar los resultados. -{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[48:55] hl[51:52,54] *} +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[53:60] hl[56:57,59] *} ### Leer Un Hero Podemos **leer** un único `Hero`. -{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[58:63] hl[60] *} +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[63:68] hl[65] *} ### Eliminar un Hero También podemos **eliminar** un `Hero`. -{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[66:73] hl[71] *} +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[71:78] hl[76] *} ### Ejecutar la App @@ -194,7 +193,7 @@ Comencemos con un modelo `HeroBase` que tiene todos los **campos que son compart * `name` * `age` -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:9] hl[7:9] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[8:10] hl[8:10] *} #### `Hero` - el *modelo de tabla* @@ -210,7 +209,7 @@ Debido a que `Hero` hereda de `HeroBase`, **también** tiene los **campos** decl * `age` * `secret_name` -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:14] hl[12:14] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[8:15] hl[13:15] *} #### `HeroPublic` - el *modelo de datos* público @@ -237,7 +236,7 @@ Todos los campos en `HeroPublic` son los mismos que en `HeroBase`, con `id` decl * `age` * `secret_name` -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:18] hl[17:18] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[8:19] hl[18:19] *} #### `HeroCreate` - el *modelo de datos* para crear un héroe @@ -261,7 +260,7 @@ Los campos de `HeroCreate` son: * `age` * `secret_name` -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:22] hl[21:22] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[8:23] hl[22:23] *} #### `HeroUpdate` - el *modelo de datos* para actualizar un héroe @@ -279,7 +278,7 @@ Los campos de `HeroUpdate` son: * `age` * `secret_name` -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:28] hl[25:28] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[8:29] hl[26:29] *} ### Crear con `HeroCreate` y devolver un `HeroPublic` @@ -291,7 +290,7 @@ Este nuevo *modelo de tabla* `Hero` tendrá los campos enviados por el cliente, Luego devolvemos el mismo *modelo de tabla* `Hero` tal cual desde la función. Pero como declaramos el `response_model` con el *modelo de datos* `HeroPublic`, **FastAPI** usará `HeroPublic` para validar y serializar los datos. -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[56:62] hl[56:58] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[61:67] hl[61:63] *} /// tip | Consejo @@ -307,13 +306,13 @@ Al declararlo en `response_model` le estamos diciendo a **FastAPI** que haga lo Podemos hacer lo mismo que antes para **leer** `Hero`s, nuevamente, usamos `response_model=list[HeroPublic]` para asegurar que los datos se validen y serialicen correctamente. -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[65:72] hl[65] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[70:77] hl[70] *} ### Leer Un Hero con `HeroPublic` Podemos **leer** un único héroe: -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[75:80] hl[77] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[80:85] hl[82] *} ### Actualizar un Hero con `HeroUpdate` @@ -323,7 +322,7 @@ Y en el código, obtenemos un `dict` con todos los datos enviados por el cliente Luego usamos `hero_db.sqlmodel_update(hero_data)` para actualizar el `hero_db` con los datos de `hero_data`. -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[83:93] hl[83:84,88:89] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[88:98] hl[88:89,93:94] *} ### Eliminar un Hero de Nuevo @@ -331,7 +330,7 @@ Luego usamos `hero_db.sqlmodel_update(hero_data)` para actualizar el `hero_db` c No satisfaremos el deseo de refactorizar todo en este punto. 😅 -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[96:103] hl[101] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[101:108] hl[106] *} ### Ejecutar la App de Nuevo diff --git a/docs/ko/docs/tutorial/sql-databases.md b/docs/ko/docs/tutorial/sql-databases.md index 58c7017d6..512340a5a 100644 --- a/docs/ko/docs/tutorial/sql-databases.md +++ b/docs/ko/docs/tutorial/sql-databases.md @@ -55,7 +55,7 @@ $ pip install sqlmodel `SQLModel`을 가져오고 데이터베이스 모델을 생성합니다: -{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[1:11] hl[7:11] *} +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[1:12] hl[8:12] *} `Hero` 클래스는 Pydantic 모델과 매우 유사합니다 (실제로 내부적으로 *Pydantic 모델이기도 합니다*). @@ -77,8 +77,7 @@ SQLModel의 `engine` (내부적으로는 SQLAlchemy `engine`)은 데이터베이 **하나의 단일 engine 객체**를 통해 코드 전체에서 동일한 데이터베이스에 연결할 수 있습니다. -{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[14:18] hl[14:15,17:18] *} - +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[15:19] hl[15:16,18:19] *} `check_same_thread=False`를 사용하면 FastAPI에서 여러 스레드에서 동일한 SQLite 데이터베이스를 사용할 수 있습니다. 이는 **하나의 단일 요청**이 **여러 스레드**를 사용할 수 있기 때문에 필요합니다(예: 의존성에서 사용되는 경우). 걱정하지 마세요. 코드가 구조화된 방식으로 인해, 이후에 **각 요청마다 단일 SQLModel *세션*을 사용**하도록 보장할 것입니다. 실제로 그것이 `check_same_thread`가 하려는 것입니다. @@ -87,7 +86,7 @@ SQLModel의 `engine` (내부적으로는 SQLAlchemy `engine`)은 데이터베이 그 다음 `SQLModel.metadata.create_all(engine)`을 사용하여 모든 *테이블 모델*의 **테이블을 생성**하는 함수를 추가합니다. -{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[21:22] hl[21:22] *} +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[21:23] hl[22:23] *} ### 세션 의존성 생성하기 @@ -97,13 +96,13 @@ SQLModel의 `engine` (내부적으로는 SQLAlchemy `engine`)은 데이터베이 그런 다음 이 의존성을 사용하는 코드를 간소화하기 위해 `Annotated` 의존성 `SessionDep`을 생성합니다. -{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[25:30] hl[25:27,30] *} +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[26:31] hl[26:28,31] *} ### 시작 시 데이터베이스 테이블 생성하기 애플리케이션 시작 시 데이터베이스 테이블을 생성합니다. -{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[32:37] hl[35:37] *} +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[34:42] hl[34:37, 42] *} 여기서는 애플리케이션 시작 이벤트 시 테이블을 생성합니다. @@ -123,7 +122,7 @@ SQLModel은 Alembic을 감싸는 마이그레이션 유틸리티를 제공할 마찬가지로, 함수의 **반환 타입**으로 선언하면 해당 데이터의 구조가 자동으로 생성되는 API 문서의 UI에 나타납니다. -{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[40:45] hl[40:45] *} +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[45:50] hl[45:50] *} @@ -133,19 +132,19 @@ SQLModel은 Alembic을 감싸는 마이그레이션 유틸리티를 제공할 `select()`를 사용하여 데이터베이스에서 `Hero`를 **조회**할 수 있습니다. 결과에 페이지네이션을 적용하기 위해 `limit`와 `offset`을 포함할 수 있습니다. -{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[48:55] hl[51:52,54] *} +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[53:60] hl[56:57,59] *} ### 단일 Hero 조회하기 단일 `Hero`를 **조회**할 수도 있습니다. -{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[58:63] hl[60] *} +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[63:68] hl[65] *} ### Hero 삭제하기 `Hero`를 **삭제**하는 것도 가능합니다. -{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[66:73] hl[71] *} +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[71:78] hl[76] *} ### 애플리케이션 실행하기 @@ -194,7 +193,7 @@ SQLModel을 사용하면 **상속**을 통해 모든 경우에 필드를 **중 * `name` * `age` -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:9] hl[7:9] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[8:10] hl[8:10] *} #### `Hero` - *테이블 모델* @@ -210,7 +209,7 @@ SQLModel을 사용하면 **상속**을 통해 모든 경우에 필드를 **중 * `age` * `secret_name` -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:14] hl[12:14] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[8:15] hl[13:15] *} #### `HeroPublic` - 공개 *데이터 모델* @@ -237,7 +236,7 @@ SQLModel을 사용하면 **상속**을 통해 모든 경우에 필드를 **중 * `age` * `secret_name` -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:18] hl[17:18] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[8:19] hl[18:19] *} #### `HeroCreate` - hero 생성용 *데이터 모델* @@ -261,7 +260,7 @@ SQLModel을 사용하면 **상속**을 통해 모든 경우에 필드를 **중 * `age` * `secret_name` -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:22] hl[21:22] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[8:23] hl[22:23] *} #### `HeroUpdate` - hero 수정용 *데이터 모델* @@ -279,7 +278,7 @@ SQLModel을 사용하면 **상속**을 통해 모든 경우에 필드를 **중 * `age` * `secret_name` -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:28] hl[25:28] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[8:29] hl[26:29] *} ### `HeroCreate`로 생성하고 `HeroPublic` 반환하기 @@ -291,7 +290,7 @@ SQLModel을 사용하면 **상속**을 통해 모든 경우에 필드를 **중 그런 다음 함수를 통해 동일한 *테이블 모델* `Hero`를 반환합니다. 하지만 `response_model`로 `HeroPublic` *데이터 모델*을 선언했기 때문에, **FastAPI**는 `HeroPublic`을 사용하여 데이터를 검증하고 직렬화합니다. -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[56:62] hl[56:58] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[61:67] hl[61:63] *} /// tip | 팁 @@ -307,13 +306,13 @@ SQLModel을 사용하면 **상속**을 통해 모든 경우에 필드를 **중 이전과 동일하게 `Hero`를 **조회**할 수 있습니다. 이번에도 `response_model=list[HeroPublic]`을 사용하여 데이터가 올바르게 검증되고 직렬화되도록 보장합니다. -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[65:72] hl[65] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[70:77] hl[70] *} ### `HeroPublic`으로 단일 Hero 조회하기 단일 hero을 **조회**할 수도 있습니다: -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[75:80] hl[77] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[80:85] hl[82] *} ### `HeroUpdate`로 Hero 수정하기 @@ -323,7 +322,7 @@ SQLModel을 사용하면 **상속**을 통해 모든 경우에 필드를 **중 그런 다음, `hero_db.sqlmodel_update(hero_data)`를 사용하여 `hero_data`의 데이터를 `hero_db`에 업데이트합니다. -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[83:93] hl[83:84,88:89] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[88:98] hl[88:89,93:94] *} ### Hero 다시 삭제하기 @@ -331,7 +330,7 @@ hero **삭제**는 이전과 거의 동일합니다. 이번에는 모든 것을 리팩토링하고 싶은 욕구를 만족시키지 못할 것 같습니다. 😅 -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[96:103] hl[101] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[101:108] hl[106] *} ### 애플리케이션 다시 실행하기 diff --git a/docs/pt/docs/tutorial/sql-databases.md b/docs/pt/docs/tutorial/sql-databases.md index 3d76a532c..fa1025a4a 100644 --- a/docs/pt/docs/tutorial/sql-databases.md +++ b/docs/pt/docs/tutorial/sql-databases.md @@ -55,7 +55,7 @@ Depois, vamos melhorá-lo aumentando a segurança e versatilidade com **múltipl Importe o `SQLModel` e crie um modelo de banco de dados: -{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[1:11] hl[7:11] *} +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[1:12] hl[8:12] *} A classe `Hero` é muito semelhante a um modelo Pydantic (na verdade, por baixo dos panos, ela *é um modelo Pydantic*). @@ -76,8 +76,7 @@ Um `engine` SQLModel (por baixo dos panos, ele é na verdade um `engine` do SQLA Você teria **um único objeto `engine`** para todo o seu código se conectar ao mesmo banco de dados. -{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[14:18] hl[14:15,17:18] *} - +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[15:19] hl[15:16,18:19] *} Usar `check_same_thread=False` permite que o FastAPI use o mesmo banco de dados SQLite em diferentes threads. Isso é necessário, pois **uma única requisição** pode usar **mais de uma thread** (por exemplo, em dependências). Não se preocupe, com a forma como o código está estruturado, garantiremos que usamos **uma única *sessão* SQLModel por requisição** mais tarde, isso é realmente o que o `check_same_thread` está tentando conseguir. @@ -86,7 +85,7 @@ Não se preocupe, com a forma como o código está estruturado, garantiremos que Em seguida, adicionamos uma função que usa `SQLModel.metadata.create_all(engine)` para **criar as tabelas** para todos os *modelos de tabela*. -{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[21:22] hl[21:22] *} +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[21:23] hl[22:23] *} ### Criar uma Dependência de Sessão @@ -102,7 +101,7 @@ Então, criamos uma dependência `Annotated` chamada `SessionDep` para simplific Vamos criar as tabelas do banco de dados quando o aplicativo for iniciado. -{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[32:37] hl[35:37] *} +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[34:42] hl[34:37, 42] *} Aqui, criamos as tabelas em um evento de inicialização do aplicativo. @@ -122,7 +121,7 @@ Por exemplo, se você declarar um parâmetro do tipo `Hero`, ele será lido do * Da mesma forma, você pode declará-lo como o **tipo de retorno** da função, e então o formato dos dados aparecerá na interface de documentação automática da API. -{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[40:45] hl[40:45] *} +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[45:50] hl[45:50] *} @@ -132,19 +131,19 @@ Aqui, usamos a dependência `SessionDep` (uma `Session`) para adicionar o novo ` Podemos **ler** `Hero`s do banco de dados usando um `select()`. Podemos incluir um `limit` e `offset` para paginar os resultados. -{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[48:55] hl[51:52,54] *} +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[53:60] hl[56:57,59] *} ### Ler um Único Hero Podemos **ler** um único `Hero`. -{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[58:63] hl[60] *} +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[63:68] hl[65] *} ### Deletar um Hero Também podemos **deletar** um `Hero`. -{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[66:73] hl[71] *} +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[71:78] hl[76] *} ### Executar o App @@ -193,7 +192,7 @@ Vamos começar com um modelo `HeroBase` que tem todos os **campos compartilhados * `name` * `age` -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:9] hl[7:9] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[8:10] hl[8:10] *} #### `Hero` - o *modelo de tabela* @@ -209,7 +208,7 @@ Como `Hero` herda de `HeroBase`, ele **também** tem os **campos** declarados em * `age` * `secret_name` -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:14] hl[12:14] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[8:15] hl[13:15] *} #### `HeroPublic` - o *modelo de dados* público @@ -236,7 +235,7 @@ Todos os campos em `HeroPublic` são os mesmos que em `HeroBase`, com `id` decla * `age` * `secret_name` -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:18] hl[17:18] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[8:19] hl[18:19] *} #### `HeroCreate` - o *modelo de dados* para criar um hero @@ -260,7 +259,7 @@ Os campos de `HeroCreate` são: * `age` * `secret_name` -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:22] hl[21:22] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[8:23] hl[22:23] *} #### `HeroUpdate` - o *modelo de dados* para atualizar um hero @@ -278,7 +277,7 @@ Os campos de `HeroUpdate` são: * `age` * `secret_name` -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:28] hl[25:28] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[8:29] hl[26:29] *} ### Criar com `HeroCreate` e retornar um `HeroPublic` @@ -290,7 +289,7 @@ Esse novo *modelo de tabela* `Hero` terá os campos enviados pelo cliente, e tam Em seguida, retornamos o mesmo *modelo de tabela* `Hero` como está na função. Mas como declaramos o `response_model` com o *modelo de dados* `HeroPublic`, o **FastAPI** usará `HeroPublic` para validar e serializar os dados. -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[56:62] hl[56:58] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[61:67] hl[61:63] *} /// tip | Dica @@ -306,13 +305,13 @@ Ao declará-lo no `response_model`, estamos dizendo ao **FastAPI** para fazer o Podemos fazer o mesmo que antes para **ler** `Hero`s, novamente, usamos `response_model=list[HeroPublic]` para garantir que os dados sejam validados e serializados corretamente. -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[65:72] hl[65] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[70:77] hl[70] *} ### Ler Um Hero com `HeroPublic` Podemos **ler** um único herói: -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[75:80] hl[77] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[80:85] hl[82] *} ### Atualizar um Hero com `HeroUpdate` @@ -322,7 +321,7 @@ E no código, obtemos um `dict` com todos os dados enviados pelo cliente, **apen Em seguida, usamos `hero_db.sqlmodel_update(hero_data)` para atualizar o `hero_db` com os dados de `hero_data`. -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[83:93] hl[83:84,88:89] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[88:98] hl[88:89,93:94] *} ### Deletar um Hero Novamente @@ -330,7 +329,7 @@ Em seguida, usamos `hero_db.sqlmodel_update(hero_data)` para atualizar o `hero_d Não vamos satisfazer o desejo de refatorar tudo neste aqui. 😅 -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[96:103] hl[101] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[101:108] hl[106] *} ### Executar o App Novamente diff --git a/docs/ru/docs/tutorial/sql-databases.md b/docs/ru/docs/tutorial/sql-databases.md index b127e44d5..cd2544314 100644 --- a/docs/ru/docs/tutorial/sql-databases.md +++ b/docs/ru/docs/tutorial/sql-databases.md @@ -55,7 +55,7 @@ $ pip install sqlmodel Импортируйте `SQLModel` и создайте модель базы данных: -{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[1:11] hl[7:11] *} +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[1:12] hl[8:12] *} Класс `Hero` очень напоминает модель Pydantic (фактически, под капотом, *это и есть модель Pydantic*). @@ -77,8 +77,7 @@ $ pip install sqlmodel Для обеспечения всех подключений приложения к одной базе данных нужен только один объект соединения `engine`. -{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[14:18] hl[14:15,17:18] *} - +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[15:19] hl[15:16,18:19] *} Использование настройки `check_same_thread=False` позволяет FastAPI использовать одну и ту же SQLite базу данных в различных потоках (threads). Это необходимо, когда **один запрос** использует **более одного потока** (например, в зависимостях). Не беспокойтесь, учитывая структуру кода, мы позже позаботимся о том, чтобы использовать **отдельную SQLModel-сессию на каждый отдельный запрос**, это как раз то, что пытается обеспечить `check_same_thread`. @@ -87,7 +86,7 @@ $ pip install sqlmodel Далее мы добавляем функцию, использующую `SQLModel.metadata.create_all(engine)`, для того, чтобы создать **таблицы** для каждой из **моделей таблицы**. -{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[21:22] hl[21:22] *} +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[21:23] hl[22:23] *} ### Создание зависимости Session @@ -97,13 +96,13 @@ $ pip install sqlmodel Затем мы создадим объявленную (`Annotated`) зависимость `SessionDep`. Мы сделаем это для того, чтобы упростить остальной код, который будет использовать эту зависимость. -{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[25:30] hl[25:27,30] *} +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[26:31] hl[26:28,31] *} ### Создание таблиц базы данных при запуске приложения Мы будем создавать таблицы базы данных при запуске приложения. -{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[32:37] hl[35:37] *} +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[34:42] hl[34:37, 42] *} В данном примере мы создаем таблицы при наступлении события запуска приложения. @@ -124,7 +123,7 @@ $ pip install sqlmodel Точно также, вы можете использовать её при объявлении типа значения, возвращаемого функцией, и тогда структурированные данные будут отображены через пользовательский интерфейс автоматически сгенерированной документации FastAPI. -{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[40:45] hl[40:45] *} +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[45:50] hl[45:50] *} Мы используем зависимость `SessionDep` (сессию базы данных) для того, чтобы добавить нового героя `Hero` в объект сессии (`Session`), сохранить изменения в базе данных, обновить данные героя и затем вернуть их. @@ -132,19 +131,19 @@ $ pip install sqlmodel Мы можем **читать** данные героев из базы данных с помощью `select()`. Мы можем включить `limit` и `offset` для постраничного считывания результатов. -{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[48:55] hl[51:52,54] *} +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[53:60] hl[56:57,59] *} ### Чтение данных отдельного героя Мы можем прочитать данные отдельного героя (`Hero`). -{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[58:63] hl[60] *} +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[63:68] hl[65] *} ### Удаление данных героя Мы также можем удалить героя `Hero` из базы данных. -{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[66:73] hl[71] *} +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[71:78] hl[76] *} ### Запуск приложения @@ -193,7 +192,7 @@ $ fastapi dev main.py * `name` * `age` -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:9] hl[7:9] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[8:10] hl[8:10] *} #### Модель таблицы `Hero` @@ -209,7 +208,7 @@ $ fastapi dev main.py * `age` * `secret_name` -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:14] hl[12:14] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[8:15] hl[13:15] *} #### Публичная модель данных `HeroPublic` @@ -235,7 +234,7 @@ $ fastapi dev main.py * `name` * `age` -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:18] hl[17:18] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[8:19] hl[18:19] *} #### Модель для создания героя `HeroCreate` @@ -259,7 +258,7 @@ $ fastapi dev main.py * `age` * `secret_name` -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:22] hl[21:22] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[8:23] hl[22:23] *} #### Модель для обновления данных героя `HeroUpdate` @@ -277,7 +276,7 @@ $ fastapi dev main.py * `age` * `secret_name` -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:28] hl[25:28] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[8:29] hl[26:29] *} ### Создание героя с помощью `HeroCreate` и возвращение результатов с помощью `HeroPublic` @@ -289,7 +288,7 @@ $ fastapi dev main.py Далее функция вернёт объект *модели таблицы* `Hero`. Но поскольку, мы объявили `HeroPublic` как модель ответа, то **FastAPI** будет использовать именно её для проверки и сериализации данных. -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[56:62] hl[56:58] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[61:67] hl[61:63] *} /// tip | Подсказка @@ -305,13 +304,13 @@ $ fastapi dev main.py Мы можем проделать то же самое **для чтения данных** героев. Мы применим модель ответа `response_model=list[HeroPublic]`, и тем самым обеспечим правильную проверку и сериализацию данных. -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[65:72] hl[65] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[70:77] hl[70] *} ### Чтение данных отдельного героя с помощью `HeroPublic` Мы можем **прочитать** данные отдельного героя: -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[75:80] hl[77] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[80:85] hl[82] *} ### Обновление данных героя с помощью `HeroUpdate` @@ -321,7 +320,7 @@ $ fastapi dev main.py Затем мы применим `hero_db.sqlmodel_update(hero_data)`, и обновим `hero_db`, использовав данные `hero_data`. -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[83:93] hl[83:84,88:89] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[88:98] hl[88:89,93:94] *} ### Удалим героя ещё раз @@ -329,7 +328,7 @@ $ fastapi dev main.py В данном случае желание *`отрефакторить всё`* остаётся неудовлетворенным. 😅 -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[96:103] hl[101] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[101:108] hl[106] *} ### Снова запустим приложение diff --git a/docs/zh/docs/tutorial/sql-databases.md b/docs/zh/docs/tutorial/sql-databases.md index fbdf3be6c..83ca224c8 100644 --- a/docs/zh/docs/tutorial/sql-databases.md +++ b/docs/zh/docs/tutorial/sql-databases.md @@ -55,7 +55,7 @@ $ pip install sqlmodel 导入 `SQLModel` 并创建一个数据库模型: -{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[1:11] hl[7:11] *} +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[1:12] hl[8:12] *} `Hero` 类与 Pydantic 模型非常相似(实际上,从底层来看,它确实*就是一个 Pydantic 模型*)。 @@ -77,8 +77,7 @@ SQLModel 的引擎 `engine`(实际上它是一个 SQLAlchemy `engine` )是 您只需构建**一个 `engine`**,来让您的所有代码连接到同一个数据库。 -{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[14:18] hl[14:15,17:18] *} - +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[15:19] hl[15:16,18:19] *} 使用 `check_same_thread=False` 可以让 FastAPI 在不同线程中使用同一个 SQLite 数据库。这很有必要,因为**单个请求**可能会使用**多个线程**(例如在依赖项中)。 不用担心,我们会按照代码结构确保**每个请求使用一个单独的 SQLModel *会话***,这实际上就是 `check_same_thread` 想要实现的。 @@ -87,7 +86,7 @@ SQLModel 的引擎 `engine`(实际上它是一个 SQLAlchemy `engine` )是 然后,我们来添加一个函数,使用 `SQLModel.metadata.create_all(engine)` 为所有*表模型***创建表**。 -{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[21:22] hl[21:22] *} +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[21:23] hl[22:23] *} ### 创建会话(Session)依赖项 @@ -97,13 +96,13 @@ SQLModel 的引擎 `engine`(实际上它是一个 SQLAlchemy `engine` )是 然后我们创建一个 `Annotated` 的依赖项 `SessionDep` 来简化其他也会用到此依赖的代码。 -{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[25:30] hl[25:27,30] *} +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[26:31] hl[26:28,31] *} ### 在启动时创建数据库表 我们会在应用程序启动时创建数据库表。 -{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[32:37] hl[35:37] *} +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[34:42] hl[34:37, 42] *} 此处,在应用程序启动事件中,我们创建了表。 @@ -123,7 +122,7 @@ SQLModel 将会拥有封装 Alembic 的迁移工具,但目前您可以直接 同样,您可以将其声明为函数的**返回类型**,然后数据的结构就会显示在自动生成的 API 文档界面中。 -{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[40:45] hl[40:45] *} +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[45:50] hl[45:50] *} @@ -133,19 +132,19 @@ SQLModel 将会拥有封装 Alembic 的迁移工具,但目前您可以直接 我们可以使用 `select()` 从数据库中**读取** `Hero` 类,并利用 `limit` 和 `offset` 来对结果进行分页。 -{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[48:55] hl[51:52,54] *} +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[53:60] hl[56:57,59] *} ### 读取单个 Hero 我们可以**读取**单个 `Hero` 。 -{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[58:63] hl[60] *} +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[63:68] hl[65] *} ### 删除单个 Hero 我们也可以**删除**单个 `Hero` 。 -{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[66:73] hl[71] *} +{* ../../docs_src/sql_databases/tutorial001_an_py310.py ln[71:78] hl[76] *} ### 运行应用程序 @@ -194,7 +193,7 @@ $ fastapi dev main.py * `name` * `age` -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:9] hl[7:9] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[8:10] hl[8:10] *} #### `Hero` - *表模型* @@ -210,7 +209,7 @@ $ fastapi dev main.py * `age` * `secret_name` -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:14] hl[12:14] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[8:15] hl[13:15] *} #### `HeroPublic` - 公共*数据模型* @@ -237,7 +236,7 @@ $ fastapi dev main.py * `age` * `secret_name` -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:18] hl[17:18] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[8:19] hl[18:19] *} #### `HeroCreate` - 用于创建 hero 的*数据模型* @@ -261,7 +260,7 @@ $ fastapi dev main.py * `age` * `secret_name` -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:22] hl[21:22] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[8:23] hl[22:23] *} #### `HeroUpdate` - 用于更新 hero 的*数据模型* @@ -279,7 +278,7 @@ $ fastapi dev main.py * `age` * `secret_name` -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[7:28] hl[25:28] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[8:29] hl[26:29] *} ### 使用 `HeroCreate` 创建并返回 `HeroPublic` @@ -291,7 +290,7 @@ $ fastapi dev main.py 然后我们将与函数中相同的*表模型* `Hero` 原样返回。但是由于我们使用 `HeroPublic` *数据模型*声明了 `response_model` ,**FastAPI** 会使用 `HeroPublic` 来验证和序列化数据。 -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[56:62] hl[56:58] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[61:67] hl[61:63] *} /// tip @@ -307,13 +306,13 @@ $ fastapi dev main.py 我们可以像之前一样**读取** `Hero` 。同样,使用 `response_model=list[HeroPublic]` 确保正确地验证和序列化数据。 -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[65:72] hl[65] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[70:77] hl[70] *} ### 用 `HeroPublic` 读取单个 Hero 我们可以**读取**单个 `hero` 。 -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[75:80] hl[77] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[80:85] hl[82] *} ### 用 `HeroUpdate` 更新单个 Hero @@ -323,7 +322,7 @@ $ fastapi dev main.py 然后我们会使用 `hero_db.sqlmodel_update(hero_data)` ,来利用 `hero_data` 的数据更新 `hero_db` 。 -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[83:93] hl[83:84,88:89] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[88:98] hl[88:89,93:94] *} ### (又一次)删除单个 Hero @@ -331,7 +330,7 @@ $ fastapi dev main.py 我们不会满足在这一部分中重构一切的愿望。😅 -{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[96:103] hl[101] *} +{* ../../docs_src/sql_databases/tutorial002_an_py310.py ln[101:108] hl[106] *} ### (又一次)运行应用程序 diff --git a/docs_src/sql_databases/tutorial001.py b/docs_src/sql_databases/tutorial001.py index be86ec0ee..e99fb4ce5 100644 --- a/docs_src/sql_databases/tutorial001.py +++ b/docs_src/sql_databases/tutorial001.py @@ -1,3 +1,4 @@ +from contextlib import asynccontextmanager from typing import List, Union from fastapi import Depends, FastAPI, HTTPException, Query @@ -27,12 +28,14 @@ def get_session(): yield session -app = FastAPI() +@asynccontextmanager +async def lifespan(app: FastAPI): + create_db_and_tables() # Startup + yield # Allows app to run + # Shutdown -@app.on_event("startup") -def on_startup(): - create_db_and_tables() +app = FastAPI(lifespan=lifespan) @app.post("/heroes/") diff --git a/docs_src/sql_databases/tutorial001_an.py b/docs_src/sql_databases/tutorial001_an.py index 8c000d31c..1bd04e273 100644 --- a/docs_src/sql_databases/tutorial001_an.py +++ b/docs_src/sql_databases/tutorial001_an.py @@ -1,3 +1,4 @@ +from contextlib import asynccontextmanager from typing import List, Union from fastapi import Depends, FastAPI, HTTPException, Query @@ -30,12 +31,15 @@ def get_session(): SessionDep = Annotated[Session, Depends(get_session)] -app = FastAPI() +@asynccontextmanager +async def lifespan(app: FastAPI): + create_db_and_tables() # Startup + yield # Allows app to run + # Shutdown -@app.on_event("startup") -def on_startup(): - create_db_and_tables() + +app = FastAPI(lifespan=lifespan) @app.post("/heroes/") diff --git a/docs_src/sql_databases/tutorial001_an_py310.py b/docs_src/sql_databases/tutorial001_an_py310.py index de1fb81fa..7c71b312f 100644 --- a/docs_src/sql_databases/tutorial001_an_py310.py +++ b/docs_src/sql_databases/tutorial001_an_py310.py @@ -1,3 +1,4 @@ +from contextlib import asynccontextmanager from typing import Annotated from fastapi import Depends, FastAPI, HTTPException, Query @@ -29,12 +30,16 @@ def get_session(): SessionDep = Annotated[Session, Depends(get_session)] -app = FastAPI() +@asynccontextmanager +async def lifespan(app: FastAPI): + create_db_and_tables() # Startup + yield # This Allows app to run -@app.on_event("startup") -def on_startup(): - create_db_and_tables() + # Statements below yield are ran after shutdown + + +app = FastAPI(lifespan=lifespan) @app.post("/heroes/") diff --git a/docs_src/sql_databases/tutorial001_an_py39.py b/docs_src/sql_databases/tutorial001_an_py39.py index 595892746..adac52409 100644 --- a/docs_src/sql_databases/tutorial001_an_py39.py +++ b/docs_src/sql_databases/tutorial001_an_py39.py @@ -1,3 +1,4 @@ +from contextlib import asynccontextmanager from typing import Annotated, Union from fastapi import Depends, FastAPI, HTTPException, Query @@ -29,12 +30,15 @@ def get_session(): SessionDep = Annotated[Session, Depends(get_session)] -app = FastAPI() +@asynccontextmanager +async def lifespan(app: FastAPI): + create_db_and_tables() # Startup + yield # Allows app to run + # Shutdown -@app.on_event("startup") -def on_startup(): - create_db_and_tables() + +app = FastAPI(lifespan=lifespan) @app.post("/heroes/") diff --git a/docs_src/sql_databases/tutorial001_py310.py b/docs_src/sql_databases/tutorial001_py310.py index b58462e6a..b000b4956 100644 --- a/docs_src/sql_databases/tutorial001_py310.py +++ b/docs_src/sql_databases/tutorial001_py310.py @@ -1,3 +1,5 @@ +from contextlib import asynccontextmanager + from fastapi import Depends, FastAPI, HTTPException, Query from sqlmodel import Field, Session, SQLModel, create_engine, select @@ -25,12 +27,14 @@ def get_session(): yield session -app = FastAPI() +@asynccontextmanager +async def lifespan(app: FastAPI): + create_db_and_tables() # Startup + yield # Allows app to run + # Shutdown -@app.on_event("startup") -def on_startup(): - create_db_and_tables() +app = FastAPI(lifespan=lifespan) @app.post("/heroes/") diff --git a/docs_src/sql_databases/tutorial001_py39.py b/docs_src/sql_databases/tutorial001_py39.py index 410a52d0c..12c9e0169 100644 --- a/docs_src/sql_databases/tutorial001_py39.py +++ b/docs_src/sql_databases/tutorial001_py39.py @@ -1,3 +1,4 @@ +from contextlib import asynccontextmanager from typing import Union from fastapi import Depends, FastAPI, HTTPException, Query @@ -27,12 +28,14 @@ def get_session(): yield session -app = FastAPI() +@asynccontextmanager +async def lifespan(app: FastAPI): + create_db_and_tables() # Startup + yield # Allows app to run + # Shutdown -@app.on_event("startup") -def on_startup(): - create_db_and_tables() +app = FastAPI(lifespan=lifespan) @app.post("/heroes/") diff --git a/docs_src/sql_databases/tutorial002.py b/docs_src/sql_databases/tutorial002.py index 4350d19c6..0fb007117 100644 --- a/docs_src/sql_databases/tutorial002.py +++ b/docs_src/sql_databases/tutorial002.py @@ -1,3 +1,4 @@ +from contextlib import asynccontextmanager from typing import List, Union from fastapi import Depends, FastAPI, HTTPException, Query @@ -44,12 +45,14 @@ def get_session(): yield session -app = FastAPI() +@asynccontextmanager +async def lifespan(app: FastAPI): + create_db_and_tables() # StartUp + yield # Allows app to run + # Shut down -@app.on_event("startup") -def on_startup(): - create_db_and_tables() +app = FastAPI(lifespan=lifespan) @app.post("/heroes/", response_model=HeroPublic) diff --git a/docs_src/sql_databases/tutorial002_an.py b/docs_src/sql_databases/tutorial002_an.py index 15e3d7c3a..fa1970dad 100644 --- a/docs_src/sql_databases/tutorial002_an.py +++ b/docs_src/sql_databases/tutorial002_an.py @@ -1,3 +1,4 @@ +from contextlib import asynccontextmanager from typing import List, Union from fastapi import Depends, FastAPI, HTTPException, Query @@ -46,12 +47,16 @@ def get_session(): SessionDep = Annotated[Session, Depends(get_session)] -app = FastAPI() -@app.on_event("startup") -def on_startup(): - create_db_and_tables() +@asynccontextmanager +async def lifespan(app: FastAPI): + create_db_and_tables() # Startup + yield # Allows app to run + # Shutdown + + +app = FastAPI(lifespan=lifespan) @app.post("/heroes/", response_model=HeroPublic) diff --git a/docs_src/sql_databases/tutorial002_an_py310.py b/docs_src/sql_databases/tutorial002_an_py310.py index 64c554b8a..db074cd92 100644 --- a/docs_src/sql_databases/tutorial002_an_py310.py +++ b/docs_src/sql_databases/tutorial002_an_py310.py @@ -1,3 +1,4 @@ +from contextlib import asynccontextmanager from typing import Annotated from fastapi import Depends, FastAPI, HTTPException, Query @@ -45,12 +46,16 @@ def get_session(): SessionDep = Annotated[Session, Depends(get_session)] -app = FastAPI() -@app.on_event("startup") -def on_startup(): - create_db_and_tables() +@asynccontextmanager +async def lifespan(app: FastAPI): + create_db_and_tables() # Startup + yield # Allows app to run + # Shutdown + + +app = FastAPI(lifespan=lifespan) @app.post("/heroes/", response_model=HeroPublic) diff --git a/docs_src/sql_databases/tutorial002_an_py39.py b/docs_src/sql_databases/tutorial002_an_py39.py index a8a0721ff..e87a7db12 100644 --- a/docs_src/sql_databases/tutorial002_an_py39.py +++ b/docs_src/sql_databases/tutorial002_an_py39.py @@ -1,3 +1,4 @@ +from contextlib import asynccontextmanager from typing import Annotated, Union from fastapi import Depends, FastAPI, HTTPException, Query @@ -45,12 +46,16 @@ def get_session(): SessionDep = Annotated[Session, Depends(get_session)] -app = FastAPI() -@app.on_event("startup") -def on_startup(): - create_db_and_tables() +@asynccontextmanager +async def lifespan(app: FastAPI): + create_db_and_tables() # Startup + yield # Allows app to run + # Shutdown + + +app = FastAPI(lifespan=lifespan) @app.post("/heroes/", response_model=HeroPublic) diff --git a/docs_src/sql_databases/tutorial002_py310.py b/docs_src/sql_databases/tutorial002_py310.py index ec3d68db5..07a2a2399 100644 --- a/docs_src/sql_databases/tutorial002_py310.py +++ b/docs_src/sql_databases/tutorial002_py310.py @@ -1,3 +1,5 @@ +from contextlib import asynccontextmanager + from fastapi import Depends, FastAPI, HTTPException, Query from sqlmodel import Field, Session, SQLModel, create_engine, select @@ -42,12 +44,14 @@ def get_session(): yield session -app = FastAPI() +@asynccontextmanager +async def lifespan(app: FastAPI): + create_db_and_tables() # Startup + yield # Allows app to run + # Shutdown -@app.on_event("startup") -def on_startup(): - create_db_and_tables() +app = FastAPI(lifespan=lifespan) @app.post("/heroes/", response_model=HeroPublic) diff --git a/docs_src/sql_databases/tutorial002_py39.py b/docs_src/sql_databases/tutorial002_py39.py index d8f5dd090..09c78b097 100644 --- a/docs_src/sql_databases/tutorial002_py39.py +++ b/docs_src/sql_databases/tutorial002_py39.py @@ -1,3 +1,4 @@ +from contextlib import asynccontextmanager from typing import Union from fastapi import Depends, FastAPI, HTTPException, Query @@ -44,12 +45,14 @@ def get_session(): yield session -app = FastAPI() +@asynccontextmanager +async def lifespan(app: FastAPI): + create_db_and_tables() # Startup + yield # Allows app to run + # Shutdown -@app.on_event("startup") -def on_startup(): - create_db_and_tables() +app = FastAPI(lifespan=lifespan) @app.post("/heroes/", response_model=HeroPublic)