Skip to content

Commit c78ce44

Browse files
authored
Add mkdocs usage documentation (#12)
* Add mkdocs usage documentation * Add basic documents * Update basic documents * Improve the documentation of the use
1 parent 2a3f583 commit c78ce44

20 files changed

+814
-22
lines changed

.github/workflows/docs.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
name: docs
2+
on:
3+
push:
4+
branches:
5+
- master
6+
permissions:
7+
contents: write
8+
jobs:
9+
deploy:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: actions/checkout@v4
13+
- name: Configure Git Credentials
14+
run: |
15+
git config user.name github-actions[bot]
16+
git config user.email 41898282+github-actions[bot]@users.noreply.github.com
17+
- uses: actions/setup-python@v5
18+
with:
19+
python-version: 3.10
20+
- run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV
21+
- uses: actions/cache@v4
22+
with:
23+
key: mkdocs-material-${{ env.cache_id }}
24+
path: .cache
25+
restore-keys: |
26+
mkdocs-material-
27+
- run: pip install mkdocs-material
28+
- run: mkdocs gh-deploy --force

README.md

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,29 +8,9 @@ Asynchronous CRUD operations based on SQLAlChemy 2.0
88
pip install sqlalchemy-crud-plus
99
```
1010

11-
## Use
11+
## 文档
1212

13-
```python
14-
# example:
15-
from sqlalchemy.orm import declarative_base
16-
from sqlalchemy_crud_plus import CRUDPlus
17-
18-
Base = declarative_base()
19-
20-
21-
class ModelIns(Base):
22-
# your sqlalchemy model
23-
pass
24-
25-
26-
class CRUDIns(CRUDPlus[ModelIns]):
27-
# your controller service
28-
pass
29-
30-
31-
# singleton
32-
ins_dao: CRUDIns = CRUDIns(ModelIns)
33-
```
13+
[SQLAlchemy CRUD Plus](https://fastapi-practices.github.io/sqlalchemy-crud-plus)
3414

3515
## 互动
3616

docs/advanced/filter.md

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
SQLAlchemy CRUD Plus 支持高级过滤选项,允许使用运算符查询记录,如大于(`__gt`)、小于(`__lt`);
2+
3+
大多数过滤器操作符需要一个字符串或整数值
4+
5+
```python
6+
# 获取年龄大于 30 岁以上的员工
7+
items = await item_crud.select_models(
8+
session=db,
9+
age__gt=30,
10+
)
11+
```
12+
13+
## 比较运算符
14+
15+
- `__gt`:大于
16+
- `__lt`:小于
17+
- `__ge`:大于或等于
18+
- `__le`:小于或等于
19+
- `__eq`: 等于
20+
- `__ne`: 不等于
21+
- `__between`: 在两者之间
22+
23+
## IN 比较
24+
25+
- `__in`: 包含
26+
- `__not_in`: 不包括
27+
28+
## 身份比较
29+
30+
- `__is`:用于测试 “真”、“假” 和 “无”。
31+
- `__is_not`:“is” 的否定
32+
- `__is_distinct_from`: 产生 SQL IS DISTINCT FROM
33+
- `__is_not_distinct_from`: Produces SQL IS NOT DISTINCT FROM
34+
- `__like`:针对特定文本模式的 SQL “like” 搜索
35+
- `__not_like`:“like” 的否定
36+
- `__ilike`:大小写不敏感的 “like”
37+
- `__not_ilike`:大小写不敏感的 “not_like”
38+
39+
## 字符串比较
40+
41+
- `__startswith`:文本以给定的字符串开始
42+
- `__endswith`:文本以给定字符串结束
43+
- `__contains`:文本包含给定字符串
44+
45+
## 字符串匹配
46+
47+
- `__match`:特定于数据库的匹配表达式
48+
49+
## 字符串修改
50+
51+
- `__concat`: 字符串连接
52+
53+
## 算术运算符
54+
55+
此过滤器使用方法需查看:[算数](#_8)
56+
57+
- `__add`: Python `+` 运算符
58+
- `__radd`: Python `+` 反向运算
59+
- `__sub`: Python `-` 运算符
60+
- `__rsub`: Python `-` 反向运算
61+
- `__mul`: Python `*` 运算符
62+
- `__rmul`: Python `*` 反向运算
63+
- `__truediv`: Python `/` 运算符,这是 Python 的 truediv 操作符,它将确保发生整数真除法
64+
- `__rtruediv`: Python `/` 反向运算
65+
- `__floordiv`: Python `//` operator,这是 Python 的 floordiv 运算符,它将确保发生底除
66+
- `__rfloordiv`: Python `//` 反向运算
67+
- `__mod`: Python `%` 运算符
68+
- `__rmod`: Python `%` 反向运算
69+
70+
## BETWEEN、IN、NOT IN
71+
72+
!!! note
73+
74+
运算符需要多个值,且仅允许元组,列表,集合
75+
76+
```python
77+
# 获取年龄在 30 - 40 岁之间的员工
78+
items = await item_crud.select_models(
79+
session=db,
80+
age__between=[30, 40],
81+
)
82+
```
83+
84+
## AND
85+
86+
可以通过将多个过滤器链接在一起来实现 AND 子句
87+
88+
```python
89+
# 获取年龄在 30 以上,薪资大于 2w 的员工
90+
items = await item_crud.select_models(
91+
session=db,
92+
age__gt=30,
93+
payroll__gt=20000,
94+
)
95+
```
96+
97+
## OR
98+
99+
!!! note
100+
101+
每个键都应是库已支持的过滤器,仅允许字典
102+
103+
```python
104+
# 获取年龄在 40 岁以上或 30 岁以下的员工
105+
items = await item_crud.select_models(
106+
session=db,
107+
age__or={'gt': 40, 'lt': 30},
108+
)
109+
```
110+
111+
## 算数
112+
113+
!!! note
114+
115+
此过滤器必须传递字典,且字典结构必须为 `{'value': xxx, 'condition': {'已支持的过滤器': xxx}}`
116+
117+
`value`:此值将与列值进行运算
118+
119+
`condition`:此值将作为运算后的比较值,比较条件取决于使用的过滤器
120+
121+
```python
122+
# 获取薪资打八折以后仍高于 15000 的员工
123+
items = await item_crud.select_models(
124+
session=db,
125+
payroll__mul={'value': 0.8, 'condition': {'gt': 15000}},
126+
)
127+
```

docs/advanced/primary_key.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
!!! note 主键参数命名
2+
3+
由于在 python 内部 id 的特殊性,我们设定 pk (参考 Django) 作为模型主键命名,所以在 crud 方法中,任何涉及到主键的地方,入参都为 `pk`
4+
5+
```py title="e.g." hl_lines="2"
6+
async def delete(self, db: AsyncSession, primary_key: int) -> int:
7+
return self.delete_model(db, pk=primary_key)
8+
```

docs/changelog.md

Whitespace-only changes.

docs/ext/async_db_session.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#!/usr/bin/env python3
2+
# -*- coding: utf-8 -*-
3+
from sqlalchemy.ext.asyncio import async_sessionmaker, create_async_engine
4+
5+
async_engine = create_async_engine('数据库连接', future=True)
6+
async_db_session = async_sessionmaker(async_engine, autoflush=False, expire_on_commit=False)

docs/index.md

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
---
2+
3+
**Documentation**: <a href="https://fastapi-practices.github.io/sqlalchemy-crud-plus" target="_blank">https://fastapi-practices.github.io/sqlalchemy-crud-plus</a>
4+
5+
**Source Code**: <a href="https://github.com/fastapi-practices/sqlalchemy-crud-plus" target="_blank">https://github.com/fastapi-practices/sqlalchemy-crud-plus</a>
6+
7+
---
8+
9+
## Installing
10+
11+
=== "pip"
12+
13+
```sh
14+
pip install sqlalchemy-crud-plus
15+
```
16+
17+
=== "pdm"
18+
19+
```sh
20+
pdm add sqlalchemy-crud-plus
21+
```
22+
23+
## 示例
24+
25+
=== "api.py"
26+
27+
```py
28+
from typing import Annotated
29+
30+
from fastapi import APIRouter
31+
32+
router = APIRouter()
33+
34+
35+
@router.get('/{pk}', summary="获取实例")
36+
async def get_ins(pk: Annotated[int, Path(...)]) -> InsParam:
37+
ins = await ins_service.get_ins()
38+
return InsParam(ins)
39+
```
40+
41+
=== "model.py"
42+
43+
```py
44+
from sqlalchemy.orm import declarative_base
45+
46+
Base = declarative_base()
47+
48+
49+
class ModelIns(Base):
50+
# sqlalchemy model
51+
pass
52+
```
53+
54+
=== "schema.py"
55+
56+
```py
57+
from pydantic import BaseModel
58+
59+
60+
class InsParam(BaseModel):
61+
# field
62+
pass
63+
```
64+
65+
=== ":star: crud.py"
66+
67+
```py hl_lines="7"
68+
from sqlalchemy.ext.asyncio import AsyncSession
69+
70+
from sqlalchemy_crud_plus import CRUDPlus
71+
72+
73+
# 在使用 IDE 时,传入类参数,将获得更友好的键入提示
74+
class CRUDIns(CRUDPlus[ModelIns]):
75+
async def get(self, db: AsyncSession, pk: int) -> ModelIns:
76+
return await self.select_model(db, pk)
77+
78+
ins_dao: CRUDIns = CRUDIns(ModelIns)
79+
```
80+
81+
=== "service.py"
82+
83+
```py
84+
class InsService:
85+
async def get_ins():
86+
async with async_db_session(pk: int) as db:
87+
ins = ins_dao.get(db, pk)
88+
89+
ins_service = InsService()
90+
```
91+
92+
## 互动
93+
94+
[WeChat / QQ](https://github.com/wu-clan)
95+
96+
## 赞助
97+
98+
如果此项目能够帮助到你,你可以赞助作者一些咖啡豆表示鼓励:[Sponsor](https://wu-clan.github.io/sponsor/)

docs/installing.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
## 依赖
2+
3+
在安装 sqlalchemy-crud-plus 之前,请确保您满足以下先决条件:
4+
5+
- **Python:** 版本 3.10 或更高
6+
- **SQLAlchemy:** sqlalchemy-crud-plus 使用 SQLAlchemy 2.0 进行数据库操作,因此您需要 SQLAlchemy 2.0 或更高版本
7+
8+
## 安装
9+
10+
=== "pip"
11+
12+
```sh
13+
pip install sqlalchemy-crud-plus
14+
```
15+
16+
=== "pdm"
17+
18+
```sh
19+
pdm add sqlalchemy-crud-plus
20+
```

docs/usage/create_model.md

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
````py
2+
async def create_model(
3+
self,
4+
session: AsyncSession,
5+
obj: CreateSchema,
6+
commit: bool = False,
7+
**kwargs
8+
) -> Model:
9+
````
10+
11+
!!! note "create_model 独特的关键字参数"
12+
13+
除了必须传入 obj schema 外,还可以通过关键字入参,传入非 schema
14+
参数,比如,对于某些特定场景,其中一个字段并不是通用的,也不需要进行输入控制,只需在写入时赋予指定值,那么你可以使用关键字入参即可
15+
16+
e.g.
17+
18+
```PY
19+
async def create(self, obj: CreateIns) -> None:
20+
async with async_db_session.begin() as db:
21+
await self.create_model(db, obj, status=1) # (1)
22+
```
23+
24+
1. 在数据被最终写入前,所有入参(schema 和关键字参数)都会赋值给 SQLAlchemy 模型,即便你传入了非模型数据,
25+
这也是安全的,因为它不会被模型所引用
26+
27+
## 提交
28+
29+
此方法提供 `commit` 参数,默认值为 False,它既不会执行提交操作,也不包含 `flush` 等行为,要想真正写入到数据库,你可以通过以下几种方案
30+
31+
1. 设置 `commit=True` 手动提交
32+
33+
```py hl_lines="2"
34+
async def create(self, db: AsyncSession, obj: CreateIns) -> None:
35+
await self.create_model(db, obj, commit=True)
36+
```
37+
38+
2. 使用 `begin()` 事务自动提交
39+
40+
```py hl_lines="9"
41+
--8<-- "docs/ext/async_db_session.py"
42+
43+
async def create(self, obj: CreateIns) -> None:
44+
async with async_db_session.begin() as db:
45+
await self.create_model(db, obj)
46+
```
47+
48+
## 示例
49+
50+
```py title="create_model" hl_lines="21"
51+
from pydantic import BaseModel
52+
53+
from sqlalchemy_crud_plus import CRUDPlus
54+
55+
from sqlalchemy import DeclarativeBase as Base
56+
from sqlalchemy.ext.asyncio import AsyncSession
57+
58+
59+
class ModelIns(Base):
60+
# your sqlalchemy model
61+
pass
62+
63+
64+
class CreateIns(BaseModel):
65+
# your pydantic schema
66+
pass
67+
68+
69+
class CRUDIns(CRUDPlus[ModelIns]):
70+
async def create(self, db: AsyncSession, obj: CreateIns) -> ModelIns:
71+
return await self.create_model(db, obj)
72+
```

0 commit comments

Comments
 (0)