Skip to content

Commit ab74559

Browse files
committed
update sqlalchemy doc
1 parent 80aa389 commit ab74559

1 file changed

Lines changed: 93 additions & 44 deletions

File tree

docs/posts/2025/2025-12-30-sqlalchemy-cheetsheet.md

Lines changed: 93 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -10,30 +10,110 @@ date:
1010
published: false
1111
---
1212

13-
# SQLAlchemy cheatsheet
13+
# SQLAlchemy cheat-sheet
1414

1515
## Architecture
1616

1717
https://aosabook.org/en/v2/sqlalchemy.html
1818

19+
## Online tutorials
20+
21+
* https://leapcell.medium.com/leapcell-the-next-gen-serverless-platform-for-python-app-hosting-0722d1b32047
22+
1923
## Engine, Connection, and Session
2024

2125
https://stackoverflow.com/questions/34322471/sqlalchemy-engine-connection-and-session-difference
2226

23-
## Renew connection/session credentials
27+
### Session-level vs. Engine level transaction control
28+
29+
Just copied from the [official documentation](https://docs.sqlalchemy.org/en/20/orm/session_transaction.html#session-level-vs-engine-level-transaction-control):
30+
31+
| ORM | Core |
32+
| ------------------------------------------ | ------------------------------------------ |
33+
| sessionmaker | Engine |
34+
| Session | Connection |
35+
| sessionmaker.begin() | Engine.begin() |
36+
| some_session.commit() | some_connection.commit() |
37+
| with some_sessionmaker() as session: | with some_engine.connect() as conn: |
38+
| with some_sessionmaker.begin() as session: | with some_engine.begin() as conn: |
39+
| with some_session.begin_nested() as sp: | with some_connection.begin_nested() as sp: |
40+
41+
### with Session() as session vs with Session.begin() as session
42+
43+
ref: https://docs.sqlalchemy.org/en/20/orm/session_api.html#session-and-sessionmaker
44+
45+
```python hl_lines="11"
46+
from sqlalchemy import create_engine
47+
from sqlalchemy.orm import sessionmaker
48+
49+
# an Engine, which the Session will use for connection resources
50+
engine = create_engine("postgresql+psycopg2://scott:tiger@localhost/")
51+
52+
Session = sessionmaker(engine)
53+
with Session() as session:
54+
session.add(some_object)
55+
session.add(some_other_object)
56+
# need manual commit
57+
session.commit()
58+
```
59+
60+
```python
61+
with Session.begin() as session:
62+
# auto commits on context exit
63+
session.add(some_object)
64+
session.add(some_other_object)
65+
```
66+
67+
| Aspect | with Session() as session | with Session.begin() as session |
68+
| ----------------------------- | ---------------------------------------- | ------------------------------------- |
69+
| Transaction Start immediately | same | same |
70+
| Session is closed on complete | same | same |
71+
| Rollback on Exception | same | same |
72+
| (different) Commit Behavior | Requires explicit commit to save changes | Automatically commits on context exit |
73+
74+
### Using event lister to refresh volatile authentication credentials
75+
76+
* https://github.com/sqlalchemy/sqlalchemy/discussions/7148
77+
* https://github.com/sqlalchemy/sqlalchemy/discussions/12133
78+
* https://github.com/sqlalchemy/sqlalchemy/discussions/8349
79+
* https://github.com/sqlalchemy/sqlalchemy/discussions/11806
80+
* https://docs.sqlalchemy.org/en/20/dialects/mssql.html#mssql-pyodbc-access-tokens
81+
* https://community.snowflake.com/s/article/Snowflake-OAuth-Support-Guide
82+
* https://community.snowflake.com/s/article/Create-External-OAuth-Token-Using-Azure-AD-For-The-OAuth-Client-Itself
83+
84+
Use the [event lister to refresh volatile authentication credentials](https://docs.sqlalchemy.org/en/20/core/engines.html#generating-dynamic-authentication-tokens).
85+
86+
Event Hooks:
87+
88+
* `checkout` Event: Triggered when a connection is checked out from the pool. Useful for tasks like setting session-level parameters. each `engine.connect()` will trigger this event.
89+
* `checkin` Event: Triggered when a connection is returned to the pool (reverse operation of `checkout`). Can be used for cleanup tasks.
90+
* `connect` Event:
91+
Type: Notification Event
92+
Purpose: Triggered after a new DBAPI connection has been established.
93+
Usage: Primarily used for performing actions post-connection, such as setting session-level parameters, initializing database schemas, or logging connection details. First `engine.connect()` (not the subsequent) will trigger this event.
94+
* `do_connect` Event:
95+
Type: Customization Hook
96+
Purpose: Allows developers to override or customize the actual process of establishing a new DBAPI connection.
97+
Usage: Useful when you need to implement custom connection logic, integrate with non-standard DBAPI drivers, or modify connection parameters dynamically. First `engine.connect()` (not the subsequent) will trigger this event.
98+
`do_connect` event is triggered before the `connect` event.
99+
100+
```python
101+
from sqlalchemy import event
102+
103+
engine = create_engine("postgresql://user@hostname/dbname")
104+
105+
106+
@event.listens_for(engine, "do_connect")
107+
def provide_token(dialect, conn_rec, cargs, cparams):
108+
cparams["token"] = get_authentication_token()
109+
```
24110

25-
- https://github.com/sqlalchemy/sqlalchemy/discussions/7148
26-
- https://github.com/sqlalchemy/sqlalchemy/discussions/12133
27-
- https://github.com/sqlalchemy/sqlalchemy/discussions/8349
28-
- https://github.com/sqlalchemy/sqlalchemy/discussions/11806
29-
- https://docs.sqlalchemy.org/en/20/dialects/mssql.html#mssql-pyodbc-access-tokens
30-
- https://community.snowflake.com/s/article/Snowflake-OAuth-Support-Guide
31-
- https://community.snowflake.com/s/article/Create-External-OAuth-Token-Using-Azure-AD-For-The-OAuth-Client-Itself
111+
Some vendor specific SQL servers ([Snowflake for .e.g](https://github.com/snowflakedb/snowflake-sqlalchemy/issues/550)) implementations some kind of keep-live heartbeat mechanism to keep the connection alive. Which means once the user is logged in, the connection (user session) will be kept alive until the user logs out even the token is expired. User don't need to send small query to keep alive, as the keep-alive signals are sent in background by the vendor specific module implicitly. This is useful for long running applications.
32112

33113
## mapped_column vs column property
34114

35-
- <https://docs.sqlalchemy.org/en/20/orm/declarative_tables.html#declarative-table-with-mapped-column>
36-
- <https://stackoverflow.com/a/76499049/5095636>
115+
* <https://docs.sqlalchemy.org/en/20/orm/declarative_tables.html#declarative-table-with-mapped-column>
116+
* <https://stackoverflow.com/a/76499049/5095636>
37117

38118
```python title="Column from sqlalchemy directly"
39119
from sqlalchemy import Column
@@ -48,8 +128,8 @@ from sqlalchemy.orm import mapped_column
48128
The [mapped_column()](https://docs.sqlalchemy.org/en/20/orm/mapping_api.html#sqlalchemy.orm.mapped_column) can have type annotations within a special SQLAlchemy type called [Mapped](https://docs.sqlalchemy.org/en/20/orm/internals.html#sqlalchemy.orm.Mapped).
49129
For e.g.:
50130

51-
- `fullname: Mapped[str]` is compiled to SQL: `fullname VARCHAR NOT NULL`
52-
- `fullname: Mapped[Optional[str]]` is compiled to SQL: `fullname VARCHAR`
131+
* `fullname: Mapped[str]` is compiled to SQL: `fullname VARCHAR NOT NULL`
132+
* `fullname: Mapped[Optional[str]]` is compiled to SQL: `fullname VARCHAR`
53133

54134
[Default type map](https://docs.sqlalchemy.org/en/20/orm/declarative_tables.html#mapped-column-derives-the-datatype-and-nullability-from-the-mapped-annotation) ():
55135

@@ -80,34 +160,3 @@ type_map: Dict[Type[Any], TypeEngine[Any]] = {
80160
uuid.UUID: types.Uuid(),
81161
}
82162
```
83-
84-
## Refreshing volatile authentication tokens
85-
86-
Use the [event lister to refresh volatile authentication credentials](https://docs.sqlalchemy.org/en/14/core/engines.html#generating-dynamic-authentication-tokens).
87-
88-
Event Hooks:
89-
90-
- `checkout` Event: Triggered when a connection is checked out from the pool. Useful for tasks like setting session-level parameters. each `engine.connect()` will trigger this event.
91-
- `checkin` Event: Triggered when a connection is returned to the pool (reverse operation of `checkout`). Can be used for cleanup tasks.
92-
- `connect` Event:
93-
Type: Notification Event
94-
Purpose: Triggered after a new DBAPI connection has been established.
95-
Usage: Primarily used for performing actions post-connection, such as setting session-level parameters, initializing database schemas, or logging connection details. First `engine.connect()` (not the subsequent) will trigger this event.
96-
- `do_connect` Event:
97-
Type: Customization Hook
98-
Purpose: Allows developers to override or customize the actual process of establishing a new DBAPI connection.
99-
Usage: Useful when you need to implement custom connection logic, integrate with non-standard DBAPI drivers, or modify connection parameters dynamically. First `engine.connect()` (not the subsequent) will trigger this event.
100-
`do_connect` event is triggered before the `connect` event.
101-
102-
```python
103-
from sqlalchemy import event
104-
105-
engine = create_engine("postgresql://user@hostname/dbname")
106-
107-
108-
@event.listens_for(engine, "do_connect")
109-
def provide_token(dialect, conn_rec, cargs, cparams):
110-
cparams["token"] = get_authentication_token()
111-
```
112-
113-
Some vendor specific SQL servers ([Snowflake for .e.g](https://github.com/snowflakedb/snowflake-sqlalchemy/issues/550)) implementations some kind of keep-live heartbeat mechanism to keep the connection alive. Which means once the user is logged in, the connection (user session) will be kept alive until the user logs out even the token is expired. User don't need to send small query to keep alive, as the keep-alive signals are sent in background by the vendor specific module implicitly. This is useful for long running applications.

0 commit comments

Comments
 (0)