---
title: "升級 SQLAlchemy 2.0 之路 - Kenji Pa"
tags: PyConTW2023, 2023-organize, 2023-共筆
---
# 升級 SQLAlchemy 2.0 之路 - Kenji Pa
{%hackmd H6-2BguNT8iE7ZUrnoG1Tg %}
<iframe src=https://app.sli.do/event/dXxw2n1GKq2sYsC6a2frua height=450 width=100%></iframe>
> Collaborative writing start from below
> 從這裡開始共筆
Basic stack: marshmallow + Werkzeug + SQLAlchemy
migration to 2.0 is too long
## Why bother upgrating ?
- Performance
- Nice to have... but not primany reason
- Maintainability --> Yes, risk management
- 1.x will be deprecated eventually (main reason)
- Better type checking support looks nice
## Goals
- Minimize impacts to the application
- Application behaviour unaltered
- To ensure we can reason it on code-level:
- All changes must be lexically 1-to-1 mapped
- Things should always work before and after a commit (safely revertible)
- Do not affect team development
- migration should not slow down team development velocity
- When possible, always migrate iteratively
- **Non-goals: Refactor / bug fixes**
## [The 9 steps of migration](https://docs.sqlalchemy.org/en/20/changelog/migration_20.html#x-2-x-migration-overview)
![](https://hackmd.io/_uploads/H1JmQEe02.png)
### RemovedIn20Warnings
1. Only emit when code are run => You need to have tests!
2. Interestingly, there is no consolidated list of these removed features
- Search for warn_deprecated_20 in 1.4 branch src
3. Tests *never* cover everything:
a. At one point we got all tests passed, but when we run the application, it's just dead
### Use the future flag on Engine & Session
- Implemented configuration to control these flags:
- So in case abnormal happens we could revert it back very quickly
- Tuned out extremely smooth, likely because
- We have request-scoped & task-scoped session, app code rarely needs to manage sessions (commit/create sessions)
### Convert old query API to new ones
- 2.0: separated query construction and execution
```python=
users = (
session.query(User).filter().all()
)
stmt = select(User)
users = session.execute(stmt)
```
- Not all queries are selects
### Abstraction is for the weak
- Pagenation
- Offset, limit, order by, total page, etc
- We happen to have a centralized place for all these queries
- Performance reason
- Reporting / batch data processing where *all* is too slow
OLD:
```py=
session.query(User).filter_by(...).first()
```
NEW:
```py=
session.scalars(
select(User).
filter(...).
limit(1)
).first()
```
## After 2.0
- New ORM declarative style
- Explore type checking
Below is the part that speaker updated the talk/tutorial after speech
講者於演講後有更新或勘誤投影片的部份