diff --git a/docs/advanced/decimal.md b/docs/advanced/decimal.md index 3cd916399f..036aae0003 100644 --- a/docs/advanced/decimal.md +++ b/docs/advanced/decimal.md @@ -47,14 +47,13 @@ Let's say that each hero in the database will have an amount of money. We could # More code here later 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/advanced/decimal/tutorial001.py!} ``` -
+/// Here we are saying that `money` can have at most `5` digits with `max_digits`, **this includes the integers** (to the left of the decimal dot) **and the decimals** (to the right of the decimal dot). @@ -96,14 +95,13 @@ When creating new models you can actually pass normal (`float`) numbers, Pydanti # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/advanced/decimal/tutorial001.py!} ``` -
+/// ## Select Decimal data @@ -117,14 +115,13 @@ Then, when working with Decimal types, you can confirm that they indeed avoid th # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/advanced/decimal/tutorial001.py!} ``` -
+/// ## Review the results diff --git a/docs/tutorial/automatic-id-none-refresh.md b/docs/tutorial/automatic-id-none-refresh.md index e9ac7fdf0a..fdde93a322 100644 --- a/docs/tutorial/automatic-id-none-refresh.md +++ b/docs/tutorial/automatic-id-none-refresh.md @@ -14,14 +14,13 @@ But the same `id` field actually **can be `None`** in the Python code, so we dec # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/automatic_id_none_refresh/tutorial001.py!} ``` -
+/// Next, I'll show you a bit more about the synchronization of data between the database and the Python code. @@ -39,14 +38,13 @@ When we create a new `Hero` instance, we don't set the `id`: # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/automatic_id_none_refresh/tutorial001.py!} ``` -
+/// ### How `Optional` Helps @@ -82,14 +80,13 @@ We can confirm that by printing our heroes before adding them to the database: # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/automatic_id_none_refresh/tutorial001.py!} ``` -
+/// That will output: @@ -128,14 +125,13 @@ We can verify by creating a session using a `with` block and adding the objects. # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/automatic_id_none_refresh/tutorial001.py!} ``` -
+/// This will, again, output the `id`s of the objects as `None`: @@ -168,14 +164,13 @@ Then we can `commit` the changes in the session, and print again: # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/automatic_id_none_refresh/tutorial001.py!} ``` -
+/// And now, something unexpected happens, look at the output, it seems as if the `Hero` instance objects had no data at all: @@ -241,14 +236,13 @@ To confirm and understand how this **automatic expiration and refresh** of data # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/automatic_id_none_refresh/tutorial001.py!} ``` -
+/// Now we are actually accessing the attributes, because instead of printing the whole object `hero_1`: @@ -338,14 +332,13 @@ You can do that too with `session.refresh(object)`: # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/automatic_id_none_refresh/tutorial001.py!} ``` -
+/// When Python executes this code: @@ -411,14 +404,13 @@ There are no surprises here, it still works: # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/automatic_id_none_refresh/tutorial001.py!} ``` -
+/// And the output shows again the same data: diff --git a/docs/tutorial/connect/create-connected-rows.md b/docs/tutorial/connect/create-connected-rows.md index 0803432a28..f8845ac772 100644 --- a/docs/tutorial/connect/create-connected-rows.md +++ b/docs/tutorial/connect/create-connected-rows.md @@ -45,14 +45,13 @@ We will later update **Spider-Boy** to add him to the **Preventers** team too, b We will continue with the code in the previous example and we will add more things to it. -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/connect/create_tables/tutorial001.py!} ``` -
+/// Make sure you remove the `database.db` file before running the examples to get the same results. @@ -72,14 +71,13 @@ Let's start by creating two teams: # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/connect/insert/tutorial001.py!} ``` -
+/// This would hopefully look already familiar. @@ -103,14 +101,13 @@ Let's not forget to add this function `create_heroes()` to the `main()` function # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/connect/insert/tutorial001.py!} ``` -
+/// ## Run it @@ -151,14 +148,13 @@ As the `Hero` class model now has a field (column, attribute) `team_id`, we can # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/connect/insert/tutorial001.py!} ``` -
+/// We haven't committed this hero to the database yet, but there are already a couple of things to pay **attention** to. @@ -190,14 +186,13 @@ Let's now create two more heroes: # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/connect/insert/tutorial001.py!} ``` -
+/// When creating `hero_rusty_man`, we are accessing `team_preventers.id`, so that will also trigger a refresh of its data, generating an output of: @@ -236,14 +231,13 @@ Now let's refresh and print those new heroes to see their new ID pointing to the # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/connect/insert/tutorial001.py!} ``` -
+/// If we execute that in the command line, it will output: diff --git a/docs/tutorial/connect/create-connected-tables.md b/docs/tutorial/connect/create-connected-tables.md index 5500fcc903..411ab3271e 100644 --- a/docs/tutorial/connect/create-connected-tables.md +++ b/docs/tutorial/connect/create-connected-tables.md @@ -63,14 +63,13 @@ Import the things we need from `sqlmodel` and create a new `Team` model: # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/connect/create_tables/tutorial001.py!} ``` -
+/// This is very similar to what we have been doing with the `Hero` model. @@ -95,14 +94,13 @@ This is the same model we have been using up to now, we are just adding the new # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/connect/create_tables/tutorial001.py!} ``` -
+/// Most of that should look familiar: @@ -142,14 +140,13 @@ Now we can add the same code as before to create the engine and the function to {!./docs_src/tutorial/connect/create_tables/tutorial001.py[ln:21-28]!} ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/connect/create_tables/tutorial001.py!} ``` -
+/// And as before, we'll call this function from another function `main()`, and we'll add that function `main()` to the main block of the file: @@ -159,14 +156,13 @@ And as before, we'll call this function from another function `main()`, and we'l {!./docs_src/tutorial/connect/create_tables/tutorial001.py[ln:31-36]!} ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/connect/create_tables/tutorial001.py!} ``` -
+/// ## Run the Code diff --git a/docs/tutorial/connect/read-connected-data.md b/docs/tutorial/connect/read-connected-data.md index 91bafc47f2..991d4409c8 100644 --- a/docs/tutorial/connect/read-connected-data.md +++ b/docs/tutorial/connect/read-connected-data.md @@ -35,14 +35,13 @@ And the `hero` table has this data: We will continue with the code in the previous example and we will add more things to it. -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/connect/insert/tutorial001.py!} ``` -
+/// ## `SELECT` Connected Data with SQL @@ -132,14 +131,13 @@ So, we can pass the `Hero` and `Team` model classes. And we can also use both th # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/connect/select/tutorial001.py!} ``` -
+/// Notice that in the comparison with `==` we are using the class attributes for both `Hero.team_id` and `Team.id`. @@ -157,14 +155,13 @@ And as we used `select` with two models, we will receive tuples of instances of # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/connect/select/tutorial001.py!} ``` -
+/// For each iteration in the `for` loop we get a a tuple with an instance of the class `Hero` and an instance of the class `Team`. @@ -190,14 +187,13 @@ As always, we must remember to add this new `select_heroes()` function to the `m # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/connect/select/tutorial001.py!} ``` -
+/// ## Run the Program @@ -312,14 +308,13 @@ And in SQLModel (actually SQLAlchemy), when using the `.join()`, because we alre # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/connect/select/tutorial002.py!} ``` -
+/// Also notice that we are still including `Team` in the `select(Hero, Team)`, because we still want to access that data. @@ -454,14 +449,13 @@ Now let's replicate the same query in **SQLModel**. # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/connect/select/tutorial003.py!} ``` -
+/// And if we run it, it will output: @@ -516,14 +510,13 @@ We could even add some additional `.where()` after `.join()` to filter the data # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/connect/select/tutorial004.py!} ``` -
+/// Here we are **filtering** with `.where()` to get only the heroes that belong to the **Preventers** team. @@ -562,14 +555,13 @@ By putting the `Team` in `select()` we tell **SQLModel** and the database that w # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/connect/select/tutorial005.py!} ``` -
+/// And if we run that, it will output: diff --git a/docs/tutorial/connect/remove-data-connections.md b/docs/tutorial/connect/remove-data-connections.md index 940a09f30d..b220530043 100644 --- a/docs/tutorial/connect/remove-data-connections.md +++ b/docs/tutorial/connect/remove-data-connections.md @@ -35,14 +35,13 @@ Let's see how to **remove** connections between rows in tables. We will continue with the code from the previous chapter. -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/connect/update/tutorial001.py!} ``` -
+/// ## Break a Connection @@ -64,14 +63,13 @@ We can simply set the `team_id` to `None`, and now it doesn't have a connection # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/connect/delete/tutorial001.py!} ``` -
+/// Again, we just **assign** a value to that field attribute `team_id`, now the value is `None`, which means `NULL` in the database. Then we `add()` the hero to the session, and then `commit()`. diff --git a/docs/tutorial/connect/update-data-connections.md b/docs/tutorial/connect/update-data-connections.md index ccc430dd6e..39994c3e91 100644 --- a/docs/tutorial/connect/update-data-connections.md +++ b/docs/tutorial/connect/update-data-connections.md @@ -37,14 +37,13 @@ Now we'll see how to **update** those connections between rows tables. We will continue with the code we used to create some heroes, and we'll update them. -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/connect/insert/tutorial001.py!} ``` -
+/// ## Assign a Team to a Hero @@ -64,14 +63,13 @@ Doing it is just like updating any other field: # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/connect/update/tutorial001.py!} ``` -
+/// We can simply **assign** a value to that field attribute `team_id`, then `add()` the hero to the session, and then `commit()`. diff --git a/docs/tutorial/create-db-and-table.md b/docs/tutorial/create-db-and-table.md index 48341b96e0..0d8a9a21ce 100644 --- a/docs/tutorial/create-db-and-table.md +++ b/docs/tutorial/create-db-and-table.md @@ -47,14 +47,13 @@ For that, we will import `SQLModel` (plus other things we will also use) and cre # More code here later 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/create_db_and_table/tutorial001.py!} ``` -
+/// This class `Hero` **represents the table** for our heroes. And each instance we create later will **represent a row** in the table. @@ -82,14 +81,13 @@ And the type of each of them will also be the type of table column: # More code here later 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/create_db_and_table/tutorial001.py!} ``` -
+/// Let's now see with more detail these field/column declarations. @@ -109,14 +107,13 @@ And we also set the default value of `age` to `None`. # More code here later 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/create_db_and_table/tutorial001.py!} ``` -
+/// /// tip @@ -152,14 +149,13 @@ To do that, we use the special `Field` function from `sqlmodel` and set the argu # More code here later 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/create_db_and_table/tutorial001.py!} ``` -
+/// That way, we tell **SQLModel** that this `id` field/column is the primary key of the table. @@ -208,14 +204,13 @@ Creating the **engine** is very simple, just call `create_engine()` with a URL f # More code here later 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/create_db_and_table/tutorial001.py!} ``` -
+/// You should normally have a single **engine** object for your whole application and re-use it everywhere. @@ -245,14 +240,13 @@ SQLite supports a special database that lives all *in memory*. Hence, it's very # More code here later 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/create_db_and_table/tutorial001.py!} ``` -
+/// You can read a lot more about all the databases supported by **SQLAlchemy** (and that way supported by **SQLModel**) in the SQLAlchemy documentation. @@ -270,14 +264,13 @@ It is particularly useful for **learning** and **debugging**: # More code here later 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/create_db_and_table/tutorial001.py!} ``` -
+/// But in production, you would probably want to remove `echo=True`: @@ -416,14 +409,13 @@ Let's run the program to see it all working. Put the code it in a file `app.py` if you haven't already. -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/create_db_and_table/tutorial001.py!} ``` -
+/// /// tip @@ -534,14 +526,13 @@ Let's put it in a function `create_db_and_tables()`: # More code here later 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/create_db_and_table/tutorial002.py!} ``` -
+/// If `SQLModel.metadata.create_all(engine)` was not in a function and we tried to import something from this module (from this file) in another, it would try to create the database and table **every time** we executed that other file that imported this module. diff --git a/docs/tutorial/delete.md b/docs/tutorial/delete.md index 34dd3be423..437d388b87 100644 --- a/docs/tutorial/delete.md +++ b/docs/tutorial/delete.md @@ -6,14 +6,13 @@ Now let's delete some data using **SQLModel**. As before, we'll continue from where we left off with the previous code. -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/update/tutorial003.py!} ``` -
+/// Remember to remove the `database.db` file before running the examples to get the same results. @@ -71,14 +70,13 @@ We'll start by selecting the hero `"Spider-Youngster"` that we updated in the pr # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/delete/tutorial001.py!} ``` -
+/// As this is a new function `delete_heroes()`, we'll also add it to the `main()` function so that we call it when executing the program from the command line: @@ -88,14 +86,13 @@ As this is a new function `delete_heroes()`, we'll also add it to the `main()` f {!./docs_src/tutorial/delete/tutorial001.py[ln:92-100]!} ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/delete/tutorial001.py!} ``` -
+/// That will print the same existing hero **Spider-Youngster**: @@ -131,14 +128,13 @@ Now, very similar to how we used `session.add()` to add or update new heroes, we # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/delete/tutorial001.py!} ``` -
+/// ## Commit the Session @@ -154,14 +150,13 @@ This will save all the changes stored in the **session**, like the deleted hero: # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/delete/tutorial001.py!} ``` -
+/// The same as we have seen before, `.commit()` will also save anything else that was added to the session. Including updates, or created heroes. @@ -204,14 +199,13 @@ Because of that, the object still contains its attributes with the data in it, s # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/delete/tutorial001.py!} ``` -
+/// This will output: @@ -242,14 +236,13 @@ To confirm if it was deleted, now let's query the database again, with the same # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/delete/tutorial001.py!} ``` -
+/// Here we are using `results.first()` to get the first object found (in case it found multiple) or `None`, if it didn't find anything. @@ -294,14 +287,13 @@ We'll do it by checking that the "first" item in the `results` is `None`: # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/delete/tutorial001.py!} ``` -
+/// This will output: diff --git a/docs/tutorial/fastapi/delete.md b/docs/tutorial/fastapi/delete.md index a48122304b..02fdc9fb52 100644 --- a/docs/tutorial/fastapi/delete.md +++ b/docs/tutorial/fastapi/delete.md @@ -20,14 +20,13 @@ And if we actually find a hero, we just delete it with the **session**. # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/fastapi/delete/tutorial001.py!} ``` -
+/// After deleting it successfully, we just return a response of: diff --git a/docs/tutorial/fastapi/limit-and-offset.md b/docs/tutorial/fastapi/limit-and-offset.md index 1152101eba..b9d1c8b73c 100644 --- a/docs/tutorial/fastapi/limit-and-offset.md +++ b/docs/tutorial/fastapi/limit-and-offset.md @@ -32,14 +32,13 @@ And by default, we will return a maximum of `100` heroes, so `limit` will have a # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/fastapi/limit_and_offset/tutorial001.py!} ``` -
+/// We want to allow clients to set different `offset` and `limit` values. diff --git a/docs/tutorial/fastapi/multiple-models.md b/docs/tutorial/fastapi/multiple-models.md index 3833f816a9..d57d1bd9b4 100644 --- a/docs/tutorial/fastapi/multiple-models.md +++ b/docs/tutorial/fastapi/multiple-models.md @@ -119,14 +119,13 @@ The simplest way to solve it could be to create **multiple models**, each one wi # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/fastapi/multiple_models/tutorial001.py!} ``` -
+/// Here's the important detail, and probably the most important feature of **SQLModel**: only `Hero` is declared with `table = True`. @@ -156,14 +155,13 @@ Let's first check how is the process to create a hero now: # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/fastapi/multiple_models/tutorial001.py!} ``` -
+/// Let's check that in detail. @@ -267,14 +265,13 @@ So let's create a **base** model `HeroBase` that the others can inherit from: # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/fastapi/multiple_models/tutorial002.py!} ``` -
+/// As you can see, this is *not* a **table model**, it doesn't have the `table = True` config. @@ -292,14 +289,13 @@ Let's start with the only **table model**, the `Hero`: # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/fastapi/multiple_models/tutorial002.py!} ``` -
+/// Notice that `Hero` now doesn't inherit from `SQLModel`, but from `HeroBase`. @@ -323,14 +319,13 @@ Notice that the parent model `HeroBase` is not a **table model**, but still, we # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/fastapi/multiple_models/tutorial002.py!} ``` -
+/// This won't affect this parent **data model** `HeroBase`. @@ -350,14 +345,13 @@ This is a fun one: # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/fastapi/multiple_models/tutorial002.py!} ``` -
+/// What's happening here? @@ -385,14 +379,13 @@ This one just declares that the `id` field is required when reading a hero from # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/fastapi/multiple_models/tutorial002.py!} ``` -
+/// ## Review the Updated Docs UI diff --git a/docs/tutorial/fastapi/read-one.md b/docs/tutorial/fastapi/read-one.md index b06ebc2a83..0fab696c19 100644 --- a/docs/tutorial/fastapi/read-one.md +++ b/docs/tutorial/fastapi/read-one.md @@ -22,14 +22,13 @@ If you need to refresh how *path parameters* work, including their data validati {!./docs_src/tutorial/fastapi/read_one/tutorial001.py[ln:61-67]!} ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/fastapi/read_one/tutorial001.py!} ``` -
+/// For example, to get the hero with ID `2` we would send a `GET` request to: @@ -57,14 +56,13 @@ This will let the client know that they probably made a mistake on their side an {!./docs_src/tutorial/fastapi/read_one/tutorial001.py[ln:61-67]!} ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/fastapi/read_one/tutorial001.py!} ``` -
+/// ## Return the Hero @@ -80,14 +78,13 @@ And because we are using the `response_model` with `HeroRead`, it will be valida {!./docs_src/tutorial/fastapi/read_one/tutorial001.py[ln:61-67]!} ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/fastapi/read_one/tutorial001.py!} ``` -
+/// ## Check the Docs UI diff --git a/docs/tutorial/fastapi/relationships.md b/docs/tutorial/fastapi/relationships.md index f152b231c7..81cf4286be 100644 --- a/docs/tutorial/fastapi/relationships.md +++ b/docs/tutorial/fastapi/relationships.md @@ -64,14 +64,13 @@ And the same way, we declared the `TeamRead` with only the same base fields of t # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/fastapi/teams/tutorial001.py!} ``` -
+/// Now, remember that FastAPI uses the `response_model` to validate and **filter** the response data? @@ -89,14 +88,13 @@ In this case, we used `response_model=TeamRead` and `response_model=HeroRead`, s # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/fastapi/teams/tutorial001.py!} ``` -
+/// ## Don't Include All the Data @@ -186,14 +184,13 @@ We'll add them **after** the other models so that we can easily reference the pr # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/fastapi/relationships/tutorial001.py!} ``` -
+/// These two models are very **simple in code**, but there's a lot happening here. Let's check it out. @@ -239,14 +236,13 @@ In the case of the hero, this tells FastAPI to extract the `team` too. And in th # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/fastapi/relationships/tutorial001.py!} ``` -
+/// ## Check It Out in the Docs UI diff --git a/docs/tutorial/fastapi/response-model.md b/docs/tutorial/fastapi/response-model.md index 29899beaff..f6e20b3354 100644 --- a/docs/tutorial/fastapi/response-model.md +++ b/docs/tutorial/fastapi/response-model.md @@ -40,14 +40,13 @@ For example, we can pass the same `Hero` **SQLModel** class (because it is also # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/fastapi/response_model/tutorial001.py!} ``` -
+/// ## List of Heroes in `response_model` @@ -65,14 +64,13 @@ First, we import `List` from `typing` and then we declare the `response_model` w # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/fastapi/response_model/tutorial001.py!} ``` -
+/// ## FastAPI and Response Model diff --git a/docs/tutorial/fastapi/session-with-dependency.md b/docs/tutorial/fastapi/session-with-dependency.md index d4265af9f8..ce2421fa82 100644 --- a/docs/tutorial/fastapi/session-with-dependency.md +++ b/docs/tutorial/fastapi/session-with-dependency.md @@ -14,14 +14,13 @@ Up to now, we have been creating a session in each *path operation*, in a `with` # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/fastapi/delete/tutorial001.py!} ``` -
+/// That's perfectly fine, but in many use cases we would want to use FastAPI 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*. @@ -43,14 +42,13 @@ It could use `yield` instead of `return`, and in that case **FastAPI** will make # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/fastapi/session_with_dependency/tutorial001.py!} ``` -
+/// ## Use the Dependency @@ -72,14 +70,13 @@ We import `Depends()` from `fastapi`. Then we use it in the *path operation func # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/fastapi/session_with_dependency/tutorial001.py!} ``` -
+/// /// tip @@ -121,14 +118,13 @@ This means that in the main code of the *path operation function*, it will work # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/fastapi/session_with_dependency/tutorial001.py!} ``` -
+/// In fact, you could think that all that block of code inside of the `create_hero()` function is still inside a `with` block for the **session**, because this is more or less what's happening behind the scenes. @@ -148,14 +144,13 @@ But now, the `with` block is not explicitly in the function, but in the dependen # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/fastapi/session_with_dependency/tutorial001.py!} ``` -
+/// We will see how this is very useful when testing the code later. ✅ @@ -183,14 +178,13 @@ And then we remove the previous `with` block with the old **session**. {!./docs_src/tutorial/fastapi/session_with_dependency/tutorial001.py[ln:55-106]!} ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/fastapi/session_with_dependency/tutorial001.py!} ``` -
+/// ## Recap diff --git a/docs/tutorial/fastapi/simple-hero-api.md b/docs/tutorial/fastapi/simple-hero-api.md index 8debe579af..2ef8b436d0 100644 --- a/docs/tutorial/fastapi/simple-hero-api.md +++ b/docs/tutorial/fastapi/simple-hero-api.md @@ -43,14 +43,13 @@ This is almost the same code we have seen up to now in previous examples: # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/fastapi/simple_hero_api/tutorial001.py!} ``` -
+/// There's only one change here from the code we have used before, the `check_same_thread` in the `connect_args`. @@ -88,14 +87,13 @@ And then create an `app` object that is an instance of that `FastAPI` class: # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/fastapi/simple_hero_api/tutorial001.py!} ``` -
+/// ## Create Database and Tables on `startup` @@ -111,14 +109,13 @@ This should be called only once at startup, not before every request, so we put # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/fastapi/simple_hero_api/tutorial001.py!} ``` -
+/// ## Create Heroes *Path Operation* @@ -140,14 +137,13 @@ It will be called when a user sends a request with a `POST` **operation** to the # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/fastapi/simple_hero_api/tutorial001.py!} ``` -
+/// /// info @@ -187,14 +183,13 @@ Now let's add another **path operation** to read all the heroes: {!./docs_src/tutorial/fastapi/simple_hero_api/tutorial001.py[ln:25-46]!} ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/fastapi/simple_hero_api/tutorial001.py!} ``` -
+/// This is pretty straightforward. diff --git a/docs/tutorial/fastapi/teams.md b/docs/tutorial/fastapi/teams.md index 52554cf4b6..0180b9476b 100644 --- a/docs/tutorial/fastapi/teams.md +++ b/docs/tutorial/fastapi/teams.md @@ -24,14 +24,13 @@ And we also create a `TeamUpdate` **data model**. # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/fastapi/teams/tutorial001.py!} ``` -
+/// We now also have **relationship attributes**. 🎉 @@ -47,14 +46,13 @@ Let's now update the `Hero` models too. # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/fastapi/teams/tutorial001.py!} ``` -
+/// We now have a `team_id` in the hero models. @@ -74,14 +72,13 @@ Notice that the **relationship attributes**, the ones with `Relationship()`, are # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/fastapi/teams/tutorial001.py!} ``` -
+/// ## Path Operations for Teams @@ -97,14 +94,13 @@ These are equivalent and very similar to the **path operations** for the **heroe # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/fastapi/teams/tutorial001.py!} ``` -
+/// ## Using Relationships Attributes diff --git a/docs/tutorial/fastapi/tests.md b/docs/tutorial/fastapi/tests.md index ea084335b4..33b17f87d2 100644 --- a/docs/tutorial/fastapi/tests.md +++ b/docs/tutorial/fastapi/tests.md @@ -14,14 +14,13 @@ We will use the application with the hero models, but without team models, and w Now we will see how useful it is to have this session dependency. ✨ -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/fastapi/app_testing/tutorial001/main.py!} ``` -
+/// ## File Structure @@ -171,10 +170,8 @@ But **it works great for testing**, because it can be quickly created before eac And also, because it never has to write anything to a file and it's all just in memory, it will be even faster than normally. 🏎 -
- -Other alternatives and ideas 👀 - +/// details | Other alternatives and ideas 👀 + Before arriving at the idea of using an **in-memory database** we could have explored other alternatives and ideas. The first is that we are not deleting the file after we finish the test, so the next test could have **leftover data**. So, the right thing would be to delete the file right after finishing the test. 🔥 @@ -187,7 +184,7 @@ So, if we tried to run the tests at the same time **in parallel** to try to spee Of course, we could also fix that, using some **random name** for each testing database file... but in the case of SQLite, we have an even better alternative by just using an **in-memory database**. ✨ -
+/// ## Configure the In-Memory Database @@ -315,14 +312,13 @@ Let's add some more tests: # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/fastapi/app_testing/tutorial001/test_main.py!} ``` -
+/// /// tip @@ -352,14 +348,13 @@ But for the next test function, we will require **both fixtures**, the **client* # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/fastapi/app_testing/tutorial001/test_main.py!} ``` -
+/// In this test function, we want to check that the *path operation* to **read a list of heroes** actually sends us heroes. @@ -391,14 +386,13 @@ Using the same ideas, requiring the fixtures, creating data that we need for the {!./docs_src/tutorial/fastapi/app_testing/tutorial001/test_main.py[ln:84-125]!} ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/fastapi/app_testing/tutorial001/test_main.py!} ``` -
+/// ## Run the Tests diff --git a/docs/tutorial/fastapi/update.md b/docs/tutorial/fastapi/update.md index df04600510..27c413f387 100644 --- a/docs/tutorial/fastapi/update.md +++ b/docs/tutorial/fastapi/update.md @@ -30,14 +30,13 @@ So, let's create this new `HeroUpdate` model: # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/fastapi/update/tutorial001.py!} ``` -
+/// This is almost the same as `HeroBase`, but all the fields are optional, so we can't simply inherit from `HeroBase`. @@ -55,14 +54,13 @@ We will use a `PATCH` HTTP operation. This is used to **partially update data**, # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/fastapi/update/tutorial001.py!} ``` -
+/// We also read the `hero_id` from the *path parameter* and the request body, a `HeroUpdate`. @@ -80,14 +78,13 @@ So, we need to read the hero from the database, with the **same logic** we used # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/fastapi/update/tutorial001.py!} ``` -
+/// ### Get the New Data @@ -147,14 +144,13 @@ Then we use that to get the data that was actually sent by the client: # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/fastapi/update/tutorial001.py!} ``` -
+/// ## Update the Hero in the Database @@ -168,14 +164,13 @@ Now that we have a **dictionary with the data sent by the client**, we can itera # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/fastapi/update/tutorial001.py!} ``` -
+/// If you are not familiar with that `setattr()`, it takes an object, like the `db_hero`, then an attribute name (`key`), that in our case could be `"name"`, and a value (`value`). And then it **sets the attribute with that name to the value**. diff --git a/docs/tutorial/indexes.md b/docs/tutorial/indexes.md index 9a4be7dbfb..a7c6028e88 100644 --- a/docs/tutorial/indexes.md +++ b/docs/tutorial/indexes.md @@ -20,14 +20,13 @@ Are you already a **SQL expert** and don't have time for all my explanations? Fine, in that case, you can **sneak peek** the final code to create indexes here. -
-👀 Full file preview +/// details | 👀 Full file preview ```Python hl_lines="8 10" {!./docs_src/tutorial/indexes/tutorial002.py!} ``` -
+/// ..but if you are not an expert, **continue reading**, this will probably be useful. 🤓 @@ -270,14 +269,13 @@ Here's the `Hero` model we had before: # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/where/tutorial001.py!} ``` -
+/// Let's now update it to tell **SQLModel** to create an index for the `name` field when creating the table: @@ -287,14 +285,13 @@ Let's now update it to tell **SQLModel** to create an index for the `name` field # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/indexes/tutorial001.py!} ``` -
+/// We use the same `Field()` again as we did before, and set `index=True`. That's it! 🚀 @@ -324,14 +321,13 @@ This is great because it means that indexes are very **simple to use**. But it m # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/indexes/tutorial001.py!} ``` -
+/// This is exactly the same code as we had before, but now the database will **use the index** underneath. @@ -380,14 +376,13 @@ We are going to query the `hero` table doing comparisons on the `age` field too, # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/indexes/tutorial002.py!} ``` -
+/// In this case, we want the default value of `age` to continue being `None`, so we set `default=None` when using `Field()`. diff --git a/docs/tutorial/insert.md b/docs/tutorial/insert.md index 31b387dced..9b01db339e 100644 --- a/docs/tutorial/insert.md +++ b/docs/tutorial/insert.md @@ -135,14 +135,13 @@ We'll create 3 right away, for the 3 heroes: # More code here later 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/insert/tutorial002.py!} ``` -
+/// /// tip @@ -180,14 +179,13 @@ The first step is to import the `Session` class: # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/insert/tutorial001.py!} ``` -
+/// Then we can create a new session: @@ -199,14 +197,13 @@ Then we can create a new session: # More code here later 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/insert/tutorial001.py!} ``` -
+/// The new `Session` takes an `engine` as a parameter. And it will use the **engine** underneath. @@ -227,14 +224,13 @@ Now that we have some hero model instances (some objects in memory) and a **sess # More code here later 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/insert/tutorial001.py!} ``` -
+/// By this point, our heroes are *not* stored in the database yet. @@ -265,14 +261,13 @@ Now that we have the heroes in the **session** and that we are ready to save all # More code here later 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/insert/tutorial001.py!} ``` -
+/// Once this line is executed, the **session** will use the **engine** to save all the data in the database by sending the corresponding SQL. @@ -306,14 +301,13 @@ But to keep things a bit more organized, let's instead create a new function `ma # More code here later 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/insert/tutorial002.py!} ``` -
+/// And then we can call that single `main()` function from that main block: @@ -322,14 +316,13 @@ And then we can call that single `main()` function from that main block: {!./docs_src/tutorial/insert/tutorial002.py[ln:36-42]!} ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/insert/tutorial002.py!} ``` -
+/// By having everything that should happen when called as a script in a single function, we can easily add more code later on. @@ -392,14 +385,13 @@ So once we are done with the session, we should **close** it to make it release # More code here later 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/insert/tutorial001.py!} ``` -
+/// But what happens if we forget to close the session? @@ -418,14 +410,13 @@ But there's a better way to handle the session, using a `with` block: {!./docs_src/tutorial/insert/tutorial002.py[ln:23-33]!} ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/insert/tutorial002.py!} ``` -
+/// This is the same as creating the session manually and then manually closing it. But here, using a `with` block, it will be automatically created when **starting** the `with` block and assigned to the variable `session`, and it will be automatically closed after the `with` block is **finished**. diff --git a/docs/tutorial/limit-and-offset.md b/docs/tutorial/limit-and-offset.md index bcd17b2f8f..b3fd1514a2 100644 --- a/docs/tutorial/limit-and-offset.md +++ b/docs/tutorial/limit-and-offset.md @@ -22,14 +22,13 @@ Again, we will create several heroes to have some data to select from: # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/offset_and_limit/tutorial001.py!} ``` -
+/// ## Review Select All @@ -43,14 +42,13 @@ This is the code we had to select all the heroes in the `select()` examples: # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/select/tutorial003.py!} ``` -
+/// But this would get us **all** the heroes at the same time, in a database that could have thousands, that could be problematic. @@ -66,14 +64,13 @@ We currently have 7 heroes in the database. But we could as well have thousands, # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/offset_and_limit/tutorial001.py!} ``` -
+/// The special **select** object we get from `select()` also has a method `.limit()` that we can use to limit the results to a certain number. @@ -144,14 +141,13 @@ We can use `.offset()`: # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/offset_and_limit/tutorial002.py!} ``` -
+/// The way this works is that the special **select** object we get from `select()` has methods like `.where()`, `.offset()` and `.limit()`. @@ -198,14 +194,13 @@ Then to get the next batch of 3 rows we would offset all the ones we already saw # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/offset_and_limit/tutorial003.py!} ``` -
+/// The database right now has **only 7 rows**, so this query can only get 1 row. @@ -268,14 +263,13 @@ Of course, you can also combine `.limit()` and `.offset()` with `.where()` and o # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/offset_and_limit/tutorial004.py!} ``` -
+/// ## Run the Program with Limit, Offset, and Where on the Command Line diff --git a/docs/tutorial/many-to-many/create-data.md b/docs/tutorial/many-to-many/create-data.md index 971659b9a6..3a7719c960 100644 --- a/docs/tutorial/many-to-many/create-data.md +++ b/docs/tutorial/many-to-many/create-data.md @@ -8,14 +8,13 @@ We'll create data for this same **many-to-many** relationship with a link table: We'll continue from where we left off with the previous code. -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/many_to_many/tutorial001.py!} ``` -
+/// ## Create Heroes @@ -29,14 +28,13 @@ As we have done before, we'll create a function `create_heroes()` and we'll crea # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/many_to_many/tutorial001.py!} ``` -
+/// This is very similar to what we have done before. @@ -58,14 +56,13 @@ Now let's do as we have done before, `commit` the **session**, `refresh` the dat # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/many_to_many/tutorial001.py!} ``` -
+/// ## Add to Main @@ -79,14 +76,13 @@ As before, add the `create_heroes()` function to the `main()` function to make s # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/many_to_many/tutorial001.py!} ``` -
+/// ## Run the Program diff --git a/docs/tutorial/many-to-many/create-models-with-link.md b/docs/tutorial/many-to-many/create-models-with-link.md index 63cbf3eb82..8ad06d84b6 100644 --- a/docs/tutorial/many-to-many/create-models-with-link.md +++ b/docs/tutorial/many-to-many/create-models-with-link.md @@ -18,14 +18,13 @@ We can create it just as any other **SQLModel**: # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/many_to_many/tutorial001.py!} ``` -
+/// This is a **SQLModel** class model table like any other. @@ -47,14 +46,13 @@ Let's see the `Team` model, it's almost identical as before, but with a little c # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/many_to_many/tutorial001.py!} ``` -
+/// The **relationship attribute `heroes`** is still a list of heroes, annotated as `List["Hero"]`. Again, we use `"Hero"` in quotes because we haven't declared that class yet by this point in the code (but as you know, editors and **SQLModel** understand that). @@ -76,14 +74,13 @@ Let's see the other side, here's the `Hero` model: # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/many_to_many/tutorial001.py!} ``` -
+/// We **removed** the previous `team_id` field (column) because now the relationship is done via the link table. 🔥 @@ -109,14 +106,13 @@ The same as before, we will have the rest of the code to create the **engine**, # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/many_to_many/tutorial001.py!} ``` -
+/// And as in previous examples, we will add that function to a function `main()`, and we will call that `main()` function in the main block: @@ -130,14 +126,13 @@ And as in previous examples, we will add that function to a function `main()`, a {!./docs_src/tutorial/many_to_many/tutorial001.py[ln:83-84]!} ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/many_to_many/tutorial001.py!} ``` -
+/// ## Run the Code diff --git a/docs/tutorial/many-to-many/link-with-extra-fields.md b/docs/tutorial/many-to-many/link-with-extra-fields.md index 90839c61c6..bda78d1ec3 100644 --- a/docs/tutorial/many-to-many/link-with-extra-fields.md +++ b/docs/tutorial/many-to-many/link-with-extra-fields.md @@ -40,14 +40,13 @@ And we will also add two **relationship attributes**, for the linked `team` and # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/many_to_many/tutorial003.py!} ``` -
+/// The new **relationship attributes** have their own `back_populates` pointing to new relationship attributes we will create in the `Hero` and `Team` models: @@ -76,14 +75,13 @@ We no longer have the `heroes` relationship attribute, and instead we have the n # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/many_to_many/tutorial003.py!} ``` -
+/// ## Update Hero Model @@ -99,14 +97,13 @@ We change the `teams` relationship attribute for `team_links`: # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/many_to_many/tutorial003.py!} ``` -
+/// ## Create Relationships @@ -122,14 +119,13 @@ But now we create the **explicit link models** manually, pointing to their hero # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/many_to_many/tutorial003.py!} ``` -
+/// We are just adding the link model instances to the session, because the link model instances are connected to the heroes and teams, they will be also automatically included in the session when we commit. @@ -235,14 +231,13 @@ Here we do that in the `update_heroes()` function: # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/many_to_many/tutorial003.py!} ``` -
+/// ## Run the Program with the New Relationship @@ -335,14 +330,13 @@ We can do that by iterating on the links: # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/many_to_many/tutorial003.py!} ``` -
+/// ## Run the Program with the Updated Relationships diff --git a/docs/tutorial/many-to-many/update-remove-relationships.md b/docs/tutorial/many-to-many/update-remove-relationships.md index f051c3c190..ff4f5dd096 100644 --- a/docs/tutorial/many-to-many/update-remove-relationships.md +++ b/docs/tutorial/many-to-many/update-remove-relationships.md @@ -4,14 +4,13 @@ Now we'll see how to update and remove these **many-to-many** relationships. We'll continue from where we left off with the previous code. -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/many_to_many/tutorial001.py!} ``` -
+/// ## Get Data to Update @@ -33,14 +32,13 @@ And because we are now using `select()`, we also have to import it. # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/many_to_many/tutorial002.py!} ``` -
+/// And of course, we have to add `update_heroes()` to our `main()` function: @@ -50,14 +48,13 @@ And of course, we have to add `update_heroes()` to our `main()` function: {!./docs_src/tutorial/many_to_many/tutorial002.py[ln:100-107]!} ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/many_to_many/tutorial002.py!} ``` -
+/// ## Add Many-to-Many Relationships @@ -73,14 +70,13 @@ We can use the same **relationship attributes** to include `hero_spider_boy` in # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/many_to_many/tutorial002.py!} ``` -
+/// /// tip @@ -173,14 +169,13 @@ In this case, we use the method `.remove()`, that takes an item and removes it f # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/many_to_many/tutorial002.py!} ``` -
+/// And this time, just to show again that by using `back_populates` **SQLModel** (actually SQLAlchemy) takes care of connecting the models by their relationships, even though we performed the operation from the `hero_spider_boy` object (modifying `hero_spider_boy.teams`), we are adding `team_z_force` to the **session**. And we commit that, without even add `hero_spider_boy`. diff --git a/docs/tutorial/one.md b/docs/tutorial/one.md index 6419d9cd71..75a4cc5c7b 100644 --- a/docs/tutorial/one.md +++ b/docs/tutorial/one.md @@ -14,14 +14,13 @@ Let's see the utilities to read a single row. We'll continue with the same examples we have been using in the previous chapters to create and select data and we'll keep updating them. -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/indexes/tutorial002.py!} ``` -
+/// If you already executed the previous examples and have a database with data, **remove the database file** before running each example, that way you won't have duplicate data and you will be able to get the same results. @@ -37,14 +36,13 @@ We have been iterating over the rows in a `result` object like: # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/indexes/tutorial002.py!} ``` -
+/// But let's say that we are not interested in all the rows, just the **first** one. @@ -58,14 +56,13 @@ We can call the `.first()` method on the `results` object to get the first row: # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/one/tutorial001.py!} ``` -
+/// This will return the first object in the `results` (if there was any). @@ -114,14 +111,13 @@ In that case, `.first()` will return `None`: # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/one/tutorial002.py!} ``` -
+/// In this case, as there's no hero with an age less than 25, `.first()` will return `None`. @@ -162,14 +158,13 @@ In that case, instead of `.first()` we can use `.one()`: # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/one/tutorial003.py!} ``` -
+/// Here we know that there's only one `"Deadpond"`, and there shouldn't be any more than one. @@ -233,14 +228,13 @@ Of course, even if we don't duplicate the data, we could get the same error if w # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/one/tutorial004.py!} ``` -
+/// That would find 2 rows, and would end up with the same error. @@ -256,14 +250,13 @@ And also, if we get no rows at all with `.one()`, it will also raise an error: # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/one/tutorial005.py!} ``` -
+/// In this case, as there are no heroes with an age less than 25, `.one()` will raise an error. @@ -304,14 +297,13 @@ Of course, with `.first()` and `.one()` you would also probably write all that i # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/one/tutorial006.py!} ``` -
+/// That would result in the same as some examples above. @@ -329,14 +321,13 @@ You could do it the same way we have been doing with a `.where()` and then getti # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/one/tutorial007.py!} ``` -
+/// That would work correctly, as expected. But there's a shorter version. 👇 @@ -352,14 +343,13 @@ As selecting a single row by its Id column with the **primary key** is a common # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/one/tutorial008.py!} ``` -
+/// `session.get(Hero, 1)` is an equivalent to creating a `select()`, then filtering by Id using `.where()`, and then getting the first item with `.first()`. @@ -396,14 +386,13 @@ Hero: secret_name='Dive Wilson' age=None id=1 name='Deadpond' # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/one/tutorial009.py!} ``` -
+/// Running that will output: diff --git a/docs/tutorial/relationship-attributes/back-populates.md b/docs/tutorial/relationship-attributes/back-populates.md index e56bcc2460..0c48bd790a 100644 --- a/docs/tutorial/relationship-attributes/back-populates.md +++ b/docs/tutorial/relationship-attributes/back-populates.md @@ -26,14 +26,13 @@ Let's see how that works by writing an **incomplete** version first, without `ba # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/relationship_attributes/back_populates/tutorial001.py!} ``` -
+/// ## Read Data Objects @@ -49,14 +48,13 @@ As you already know how this works, I won't separate that in a select `statement # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/relationship_attributes/back_populates/tutorial001.py!} ``` -
+/// /// tip @@ -76,14 +74,13 @@ Now, let's print the current **Spider-Boy**, the current **Preventers** team, an # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/relationship_attributes/back_populates/tutorial001.py!} ``` -
+/// Up to this point, it's all good. 😊 @@ -117,14 +114,13 @@ Now let's update **Spider-Boy**, removing him from the team by setting `hero_spi # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/relationship_attributes/back_populates/tutorial001.py!} ``` -
+/// The first important thing is, we *haven't committed* the hero yet, so accessing the list of heroes would not trigger an automatic refresh. @@ -176,14 +172,13 @@ Now, if we commit it and print again: # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/relationship_attributes/back_populates/tutorial001.py!} ``` -
+/// When we access `preventers_team.heroes` after the `commit`, that triggers a refresh, so we get the latest list, without **Spider-Boy**, so that's fine again: @@ -221,14 +216,13 @@ Let's add it back: # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/relationship_attributes/back_populates/tutorial002.py!} ``` -
+/// And we can keep the rest of the code the same: @@ -244,14 +238,13 @@ And we can keep the rest of the code the same: # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/relationship_attributes/back_populates/tutorial002.py!} ``` -
+/// /// tip @@ -290,14 +283,13 @@ It's quite simple code, it's just a string, but it might be confusing to think e # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/relationship_attributes/back_populates/tutorial002.py!} ``` -
+/// The string in `back_populates` is the name of the attribute *in the other* model, that will reference *the current* model. @@ -313,14 +305,13 @@ So, in the class `Team`, we have an attribute `heroes` and we declare it with `R # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/relationship_attributes/back_populates/tutorial002.py!} ``` -
+/// The string in `back_populates="team"` refers to the attribute `team` in the class `Hero` (the other class). @@ -336,14 +327,13 @@ So, the string `"heroes"` refers to the attribute `heroes` in the class `Team`. # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/relationship_attributes/back_populates/tutorial002.py!} ``` -
+/// /// tip @@ -376,11 +366,10 @@ So, `back_populates` would most probably be something like `"hero"` or `"heroes" # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/relationship_attributes/back_populates/tutorial003.py!} ``` -
+/// diff --git a/docs/tutorial/relationship-attributes/create-and-update-relationships.md b/docs/tutorial/relationship-attributes/create-and-update-relationships.md index dc05af6eb6..e939141193 100644 --- a/docs/tutorial/relationship-attributes/create-and-update-relationships.md +++ b/docs/tutorial/relationship-attributes/create-and-update-relationships.md @@ -14,14 +14,13 @@ Let's check the old code we used to create some heroes and teams: # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/connect/insert/tutorial001.py!} ``` -
+/// There are several things to **notice** here. @@ -49,14 +48,13 @@ Now let's do all that, but this time using the new, shiny `Relationship` attribu # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/relationship_attributes/define_relationship_attributes/tutorial001.py!} ``` -
+/// Now we can create the `Team` instances and pass them directly to the new `team` argument when creating the `Hero` instances, as `team=team_preventers` instead of `team_id=team_preventers.id`. @@ -84,14 +82,13 @@ The same way we could assign an integer with a `team.id` to a `hero.team_id`, we # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/relationship_attributes/create_and_update_relationships/tutorial001.py!} ``` -
+/// ## Create a Team with Heroes @@ -111,14 +108,13 @@ We could also create the `Hero` instances first, and then pass them in the `hero # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/relationship_attributes/create_and_update_relationships/tutorial001.py!} ``` -
+/// Here we create two heroes first, **Black Lion** and **Princess Sure-E**, and then we pass them in the `heroes` argument. @@ -146,14 +142,13 @@ Let's create some more heroes and add them to the `team_preventers.heroes` list # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/relationship_attributes/create_and_update_relationships/tutorial001.py!} ``` -
+/// The attribute `team_preventers.heroes` behaves like a list. But it's a special type of list, because when we modify it adding heroes to it, **SQLModel** (actually SQLAlchemy) **keeps track of the necessary changes** to be done in the database. diff --git a/docs/tutorial/relationship-attributes/define-relationships-attributes.md b/docs/tutorial/relationship-attributes/define-relationships-attributes.md index 0c2b4f1ef7..7585480923 100644 --- a/docs/tutorial/relationship-attributes/define-relationships-attributes.md +++ b/docs/tutorial/relationship-attributes/define-relationships-attributes.md @@ -47,14 +47,13 @@ Up to now, we have only used the `team_id` column to connect the tables when que # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/connect/insert/tutorial001.py!} ``` -
+/// This is a **plain field** like all the others, all representing a **column in the table**. @@ -68,14 +67,13 @@ First, import `Relationship` from `sqlmodel`: # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/relationship_attributes/define_relationship_attributes/tutorial001.py!} ``` -
+/// Next, use that `Relationship` to declare a new attribute in the model classes: @@ -85,14 +83,13 @@ Next, use that `Relationship` to declare a new attribute in the model classes: # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/relationship_attributes/define_relationship_attributes/tutorial001.py!} ``` -
+/// ## What Are These Relationship Attributes diff --git a/docs/tutorial/relationship-attributes/read-relationships.md b/docs/tutorial/relationship-attributes/read-relationships.md index 3a281a2038..e4a049d2bd 100644 --- a/docs/tutorial/relationship-attributes/read-relationships.md +++ b/docs/tutorial/relationship-attributes/read-relationships.md @@ -18,14 +18,13 @@ First, add a function `select_heroes()` where we get a hero to start working wit # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/relationship_attributes/read_relationships/tutorial001.py!} ``` -
+/// ## Select the Related Team - Old Way @@ -41,14 +40,13 @@ With what we have learned **up to now**, we could use a `select()` statement, th # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/relationship_attributes/read_relationships/tutorial001.py!} ``` -
+/// ## Get Relationship Team - New Way @@ -68,14 +66,13 @@ So, the highlighted block above, has the same results as the block below: # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/relationship_attributes/read_relationships/tutorial001.py!} ``` -
+/// /// tip @@ -97,14 +94,13 @@ And the same way, when we are working on the **many** side of the **one-to-many* # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/relationship_attributes/read_relationships/tutorial002.py!} ``` -
+/// That would print a list with all the heroes in the Preventers team: diff --git a/docs/tutorial/relationship-attributes/remove-relationships.md b/docs/tutorial/relationship-attributes/remove-relationships.md index ae4c6cfea2..982e316c2b 100644 --- a/docs/tutorial/relationship-attributes/remove-relationships.md +++ b/docs/tutorial/relationship-attributes/remove-relationships.md @@ -16,14 +16,13 @@ We can remove the relationship by setting it to `None`, the same as with the `te # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/relationship_attributes/read_relationships/tutorial002.py!} ``` -
+/// And of course, we should remember to add this `update_heroes()` function to `main()` so that it runs when we call this program from the command line: @@ -35,14 +34,13 @@ And of course, we should remember to add this `update_heroes()` function to `mai # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/relationship_attributes/read_relationships/tutorial002.py!} ``` -
+/// ## Recap diff --git a/docs/tutorial/relationship-attributes/type-annotation-strings.md b/docs/tutorial/relationship-attributes/type-annotation-strings.md index e51e71c106..780da6a962 100644 --- a/docs/tutorial/relationship-attributes/type-annotation-strings.md +++ b/docs/tutorial/relationship-attributes/type-annotation-strings.md @@ -8,14 +8,13 @@ In the first Relationship attribute, we declare it with `List["Hero"]`, putting # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/relationship_attributes/define_relationship_attributes/tutorial001.py!} ``` -
+/// What's that about? Can't we just write it normally as `List[Hero]`? diff --git a/docs/tutorial/select.md b/docs/tutorial/select.md index 43003231c9..5be5e8a0ba 100644 --- a/docs/tutorial/select.md +++ b/docs/tutorial/select.md @@ -23,14 +23,13 @@ Things are getting more exciting! Let's now see how to read data from the databa Let's continue from the last code we used to create some data. -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/insert/tutorial002.py!} ``` -
+/// We are creating a **SQLModel** `Hero` class model and creating some records. @@ -175,14 +174,13 @@ We will start with that in a new function `select_heroes()`: # More code here later 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/select/tutorial001.py!} ``` -
+/// ## Create a `select` Statement @@ -196,14 +194,13 @@ First we have to import `select` from `sqlmodel` at the top of the file: # More code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/select/tutorial001.py!} ``` -
+/// And then we will use it to create a `SELECT` statement in Python code: @@ -217,14 +214,13 @@ And then we will use it to create a `SELECT` statement in Python code: # More code here later 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/select/tutorial001.py!} ``` -
+/// It's a very simple line of code that conveys a lot of information: @@ -263,14 +259,13 @@ Now that we have the `select` statement, we can execute it with the **session**: # More code here later 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/select/tutorial001.py!} ``` -
+/// This will tell the **session** to go ahead and use the **engine** to execute that `SELECT` statement in the database and bring the results back. @@ -316,14 +311,13 @@ Now we can put it in a `for` loop and print each one of the heroes: # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/select/tutorial001.py!} ``` -
+/// This will print the output: @@ -345,14 +339,13 @@ Now include a call to `select_heroes()` in the `main()` function so that it is e # More code here later 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/select/tutorial001.py!} ``` -
+/// ## Review The Code @@ -406,14 +399,13 @@ The special `results` object also has a method `results.all()` that returns a li # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/select/tutorial003.py!} ``` -
+/// With this now we have all the heroes in a list in the `heroes` variable. @@ -447,14 +439,13 @@ But knowing what is each object and what it is all doing, we can simplify it a b # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/select/tutorial004.py!} ``` -
+/// Here we are putting it all on a single line, you will probably put the select statements in a single line like this more often. diff --git a/docs/tutorial/update.md b/docs/tutorial/update.md index 47ee881adc..b223d6d279 100644 --- a/docs/tutorial/update.md +++ b/docs/tutorial/update.md @@ -6,14 +6,13 @@ Now let's see how to update data using **SQLModel**. As before, we'll continue from where we left off with the previous code. -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/indexes/tutorial002.py!} ``` -
+/// Remember to remove the `database.db` file before running the examples to get the same results. @@ -102,14 +101,13 @@ We'll start by selecting the hero `"Spider-Boy"`, this is the one we will update # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/update/tutorial001.py!} ``` -
+/// Let's not forget to add that `update_heroes()` function to the `main()` function so that we call it when executing the program from the command line: @@ -119,14 +117,13 @@ Let's not forget to add that `update_heroes()` function to the `main()` function {!./docs_src/tutorial/update/tutorial001.py[ln:58-65]!} ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/update/tutorial001.py!} ``` -
+/// Up to that point, running that in the command line will output: @@ -169,14 +166,13 @@ In this case, we will set the `age` to `16`: # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/update/tutorial001.py!} ``` -
+/// ## Add the Hero to the Session @@ -192,14 +188,13 @@ This is the same we did when creating new hero instances: # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/update/tutorial001.py!} ``` -
+/// ## Commit the Session @@ -215,14 +210,13 @@ This will save the updated hero in the database: # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/update/tutorial001.py!} ``` -
+/// It will also save anything else that was added to the session. @@ -263,14 +257,13 @@ But in this example we are not accessing any attribute, we will only print the o # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/update/tutorial001.py!} ``` -
+/// This refresh will trigger the same SQL query that would be automatically triggered by accessing an attribute. So it will generate this output: @@ -304,14 +297,13 @@ Now we can just print the hero: # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/update/tutorial001.py!} ``` -
+/// Because we refreshed it right after updating it, it has fresh data, including the new `age` we just updated. @@ -364,14 +356,13 @@ This also means that you can update several fields (attributes, columns) at once {!./docs_src/tutorial/update/annotations/en/tutorial004.md!} -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/update/tutorial004.py!} ``` -
+/// /// tip diff --git a/docs/tutorial/where.md b/docs/tutorial/where.md index 541b0833bc..25c01e9290 100644 --- a/docs/tutorial/where.md +++ b/docs/tutorial/where.md @@ -31,14 +31,13 @@ We'll continue with the same examples we have been using in the previous chapter And now we will update `select_heroes()` to filter the data. -
-👀 Full file preview +/// details | 👀 Full file preview ```Python hl_lines="36-41" {!./docs_src/tutorial/select/tutorial001.py!} ``` -
+/// If you already executed the previous examples and have a database with data, **remove the database file** before running each example, that way you won't have duplicate data and you will be able to get the same results. @@ -198,14 +197,13 @@ We care specially about the **select** statement: # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/select/tutorial001.py!} ``` -
+/// ## Filter Rows Using `WHERE` with **SQLModel** @@ -219,14 +217,13 @@ Now, the same way that we add `WHERE` to a SQL statement to filter rows, we can # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/where/tutorial001.py!} ``` -
+/// It's a very small change, but it's packed of details. Let's explore them. @@ -480,14 +477,13 @@ It's actually the same as in previous chapters for selecting data: # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/where/tutorial001.py!} ``` -
+/// We take that statement, that now includes a `WHERE`, and we `exec()` it to get the results. @@ -544,14 +540,13 @@ We could get the rows where a column is **not** equal to a value using `!=`: # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/where/tutorial002.py!} ``` -
+/// That would output: @@ -572,14 +567,13 @@ Let's update the function `create_heroes()` and add some more rows to make the n # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/where/tutorial003.py!} ``` -
+/// Now that we have several heroes with different ages, it's gonna be more obvious what the next comparisons do. @@ -595,14 +589,13 @@ Now let's use `>` to get the rows where a column is **more than** a value: # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/where/tutorial003.py!} ``` -
+/// That would output: @@ -630,14 +623,13 @@ Let's do that again, but with `>=` to get the rows where a column is **more than # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/where/tutorial004.py!} ``` -
+/// Because we are using `>=`, the age `35` will be included in the output: @@ -666,14 +658,13 @@ Similarly, we can use `<` to get the rows where a column is **less than** a valu # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/where/tutorial005.py!} ``` -
+/// And we get the younger one with an age in the database: @@ -699,14 +690,13 @@ Finally, we can use `<=` to get the rows where a column is **less than or equal* # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/where/tutorial006.py!} ``` -
+/// And we get the younger ones, `35` and below: @@ -739,14 +729,13 @@ Because `.where()` returns the same special select object back, we can add more # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/where/tutorial007.py!} ``` -
+/// This will select the rows `WHERE` the `age` is **greater than or equal** to `35`, `AND` also the `age` is **less than** `40`. @@ -795,14 +784,13 @@ As an alternative to using multiple `.where()` we can also pass several expressi # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/where/tutorial008.py!} ``` -
+/// This is the same as the above, and will result in the same output with the two heroes: @@ -825,14 +813,13 @@ To do it, you can import `or_`: # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/where/tutorial009.py!} ``` -
+/// And then pass both expressions to `or_()` and put it inside `.where()`. @@ -846,14 +833,13 @@ For example, here we select the heroes that are the youngest OR the oldest: # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/where/tutorial009.py!} ``` -
+/// When we run it, this generates the output: @@ -910,14 +896,13 @@ To do that, we can import `col()` (as short for "column"): # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/where/tutorial011.py!} ``` -
+/// And then put the **class attribute** inside `col()` when using it in a `.where()`: @@ -929,14 +914,13 @@ And then put the **class attribute** inside `col()` when using it in a `.where() # Code below omitted 👇 ``` -
-👀 Full file preview +/// details | 👀 Full file preview ```Python {!./docs_src/tutorial/where/tutorial011.py!} ``` -
+/// So, now the comparison is not: