@@ -362,7+362,7 @@ Here's how the output would look like:
```console
$ python app.py
-// Output above ommitted 👆
+// Output above omitted 👆
// The first refresh
INFO Engine SELECT hero.id, hero.name, hero.secret_name, hero.age
@@ -427,7+427,7 @@ And the output shows again the same data:
```console
$ python app.py
-// Output above ommitted 👆
+// Output above omitted 👆
// By finishing the with block, the Session is closed, including a rollback of any pending transaction that could have been there and was not committed
@@ -168,7+168,7 @@ Let's assume that now the file structure is:
### Circular Imports and Type Annotations
-The problem with circular imports is that Python can't resolve them at <abbr title="While it is executing the program, as oposed to the code as just text in a file stored on disk.">*runtime*</abbr>.
+The problem with circular imports is that Python can't resolve them at <abbr title="While it is executing the program, as opposed to the code as just text in a file stored on disk.">*runtime*</abbr>.
But when using Python **type annotations** it's very common to need to declare the type of some variables with classes imported from other files.
@@ -106,7+106,7 @@ This is the same model we have been using up to now, we are just adding the new
Most of that should look familiar:
-The column will be named `team_id`. It will be an integer, and it could be `NULL` in the database (or `None` in Python), becase there could be some heroes that don't belong to any team.
+The column will be named `team_id`. It will be an integer, and it could be `NULL` in the database (or `None` in Python), because there could be some heroes that don't belong to any team.
We add a default of `None` to the `Field()` so we don't have to explicitly pass `team_id=None` when creating a hero.
@@ -164,6+164,6 @@ Of course, you can also go and take a full SQL course or read a book about SQL,
We saw how to interact with SQLite databases in files using **DB Browser for SQLite** in a visual user interface.
-We also saw how to use it to write some SQL directly to the SQLite database. This will be useful to verify the data in the database is looking correclty, to debug, etc.
+We also saw how to use it to write some SQL directly to the SQLite database. This will be useful to verify the data in the database is looking correctly, to debug, etc.
In the next chapters we will start using **SQLModel** to interact with the database, and we will continue to use **DB Browser for SQLite** at the same time to look at the database underneath. 🔍
@@ -82,7+82,7 @@ But now, we need to deal with a bit of logistics and details we are not paying a
This test looks fine, but there's a problem.
-If we run it, it will use the same **production database** that we are using to store our very important **heroes**, and we will end up adding unnecesary data to it, or even worse, in future tests we could end up removing production data.
+If we run it, it will use the same **production database** that we are using to store our very important **heroes**, and we will end up adding unnecessary data to it, or even worse, in future tests we could end up removing production data.
So, we should use an independent **testing database**, just for the tests.
@@ -52,7+52,7 @@ With what we have learned **up to now**, we could use a `select()` statement, th
## Get Relationship Team - New Way
-But now that we have the **relationship attributes**, we can just access them, and **SQLModel** (actually SQLAlchemy) will go and fetch the correspoinding data from the database, and make it available in the attribute. ✨
+But now that we have the **relationship attributes**, we can just access them, and **SQLModel** (actually SQLAlchemy) will go and fetch the corresponding data from the database, and make it available in the attribute. ✨
So, the highlighted block above, has the same results as the block below:
@@ -472,7+472,7 @@ SQLAlchemy's own `Session` has a method `session.execute()`. It doesn't have a `
If you see SQLAlchemy tutorials, they will always use `session.execute()`.
-**SQLModel**'s own `Session` inherits directly from SQLAlchemy's `Session`, and adds this additonal method `session.exec()`. Underneath, it uses the same `session.execute()`.
+**SQLModel**'s own `Session` inherits directly from SQLAlchemy's `Session`, and adds this additional method `session.exec()`. Underneath, it uses the same `session.execute()`.
But `session.exec()` does several **tricks** combined with the tricks in `session()` to give you the **best editor support**, with **autocompletion** and **inline errors** everywhere, even after getting data from a select. ✨
@@ -206,7+206,7 @@ We care specially about the **select** statement:
## Filter Rows Using `WHERE` with **SQLModel**
-Now, the same way that we add `WHERE` to a SQL statement to filter rows, we can add a `.where()` to a **SQLModel** `select()` statment to filter rows, which will filter the objects returned:
+Now, the same way that we add `WHERE` to a SQL statement to filter rows, we can add a `.where()` to a **SQLModel** `select()` statement to filter rows, which will filter the objects returned: