Compare commits

..
3 Commits
3 changed files with 101 additions and 1 deletions
+3 -1
View File
@@ -10,7 +10,7 @@ working across different projects via [VisualMode](https://www.visualmode.dev/).
For a steady stream of TILs, [sign up for my newsletter](https://visualmode.kit.com/newsletter).
_1833 TILs and counting..._
_1835 TILs and counting..._
See some of the other learning resources I work on:
@@ -1076,6 +1076,7 @@ If you've learned something here, support my efforts writing daily TILs by
- [Break Debugger On First Line Of Program](python/break-debugger-on-first-line-of-program.md)
- [Check If Package Is Installed With Pip](python/check-if-package-is-installed-with-pip.md)
- [Check Precondition Before Click Arg Parsing](python/check-precondition-before-click-arg-parsing.md)
- [Commit Writes From Executed SQLite Statements](python/commit-writes-from-executed-sqlite-statements.md)
- [Control Passing Of Time In Tests](python/control-passing-of-time-in-tests.md)
- [Create A Dummy DataFrame In Pandas](python/create-a-dummy-dataframe-in-pandas.md)
- [Create A Range Of Descending Values](python/create-a-range-of-descending-values.md)
@@ -1509,6 +1510,7 @@ If you've learned something here, support my efforts writing daily TILs by
- [Install Latest Version Of Ruby With asdf](ruby/install-latest-version-of-ruby-with-asdf.md)
- [Invoking Rake Tasks Multiple Times](ruby/invoking-rake-tasks-multiple-times.md)
- [IRB Has Built-In Benchmarking With Ruby 3](ruby/irb-has-built-in-benchmarking-with-ruby-3.md)
- [IRB Prints A Helpful Welcome Prompt](ruby/irb-prints-a-helpful-welcome-prompt.md)
- [Join URI Path Parts](ruby/join-uri-path-parts.md)
- [Jump Out Of A Nested Context With Throw/Catch](ruby/jump-out-of-a-nested-context-with-throw-catch.md)
- [Last Raised Exception In The Call Stack](ruby/last-raised-exception-in-the-call-stack.md)
@@ -0,0 +1,71 @@
# Commit Writes From Executed SQLite Statements
Let's look at a method that uses a
[`sqlite3`](https://docs.python.org/3/library/sqlite3.html) connection to
execute a couple statements against a SQLite database.
```python
def write_session_with_project(self, session, *, active=False) -> None:
# Delete the current active session if there is one
self.conn.execute("""
delete from sessions where active = 1;
""")
# Upsert (find or create) the project based on `session.project_name`
cursor = self.conn.execute(
"""
insert into projects (name) values (:project_name)
on conflict (name) do update set name = excluded.name
returning id;
""",
{"project_name": session.project_name},
)
project_id = cursor.fetchone()[0]
# ...
self.conn.commit()
```
The first `conn.execute` call is going to implicitly start a database
transaction before executing the statement. Subsequent statements are going to
take place within that transaction. To apply all the changes in the transaction
I have to eventually run `conn.commit()`. If there isn't an issue committing all
the changes and nothing else raised before I committed, then those changes will
all be applied atomically.
I will need to do my own exception handling with a try/catch that handles any
rollback.
I'd rather not have to manage those extra pieces which is the kind of thing
context managers typically help with. Let's improve upon this with the
[Connection context manager](https://docs.python.org/3/library/sqlite3.html#how-to-use-the-connection-context-manager):
```python
def write_session_with_project(self, session, *, active=False) -> None:
with self.conn:
# Delete the current active session if there is one
self.conn.execute("""
delete from sessions where active = 1;
""")
# Upsert (find or create) the project based on `session.project_name`
cursor = self.conn.execute(
"""
insert into projects (name) values (:project_name)
on conflict (name) do update set name = excluded.name
returning id;
""",
{"project_name": session.project_name},
)
project_id = cursor.fetchone()[0]
# ...
```
I get the same transactional behavior as before for everything in the context
manager body. However, now the `commit` is handled and if an exception occurs
the `rollback` is handled as well.
Note: the connection context manager will still re-propagate an exception that
occurred, so I may need to handle that with a try/catch somewhere.
@@ -0,0 +1,27 @@
# IRB Prints A Helpful Welcome Prompt
I've been using `irb` for over 15 years as a REPL for executing Ruby code. It
has always been pretty plain in a lot of ways. For this reason, I often used
[`pry`](https://github.com/pry/pry) instead, especially in a Rails context.
`irb` has gotten notably better in recent years. I was delighted to recently
notice that earlier this year they landed delightful, colorful, and helpful
improvement to the welcome prompt.
It looks more or less like this:
```
irb
⢀⡴⠊⢉⡟⢿ IRB v1.18.0 - Ruby 3.4.4
⣎⣀⣴⡋⡟⣻ "ls [object] -g pattern" to filter methods and properties
⣟⣼⣱⣽⣟⣾ ~/dev/jbranchaud/pool-league-pro
irb(main):001>
```
Notice it includes a random tip on the second line. I had no idea you could
include `-g pattern` with an `ls`, so that will likely be landing as a new TIL
soon.
This improved welcome message has been available since `1.18.0` and originated
in [this PR](https://github.com/ruby/irb/pull/1183).