Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/advanced/filter.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ items = await item_crud.select_models(
`or` 过滤器的高级用法,每个键都应是库已支持的过滤器,仅允许字典

```python title="__mor"
# 获取年龄等于 30 岁和 40 岁的员工
# 获取年龄等于 30 岁或 40 岁的员工
items = await item_crud.select_models(
session=db,
age__mor={'eq': [30, 40]}, # (1)
Expand All @@ -133,7 +133,7 @@ items = await item_crud.select_models(
`or` 过滤器的更高级用法,每个值都应是一个已受支持的条件过滤器,它应该是一个数组

```python title="__gor__"
# 获取年龄在 30 - 40 岁之间且薪资大于 20k 的员工
# 获取年龄在 30 - 40 岁之间或薪资大于 20k 的员工
items = await item_crud.select_models(
session=db,
__gor__=[
Expand Down
11 changes: 11 additions & 0 deletions docs/advanced/flush.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
## `flush()`

- `flush` 是将更改从 Python 移动到数据库的事务缓冲区
- 它会生成必要的 SQL 语句并发送到数据库执行,但不会提交(commit)事务
- 在 `flush` 之后,数据会被写入数据库,但事务依然是活跃的(未提交),除非发生错误,在这种情况下,整个事务将回滚,`flush`
的更改也会被撤销

!!! tip "提示"

如果你在事务提交前无需对新实例进行某些操作,`flush` 是没必要的,在 `commit` 时,SQLAlchemy 会隐式地调用一次 `flush`,
确保所有挂起的更改都被同步到数据库,然后提交事务
4 changes: 3 additions & 1 deletion docs/usage/create_model.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ async def create_model(
self,
session: AsyncSession,
obj: CreateSchema,
flush: bool = False,
commit: bool = False,
**kwargs,
) -> Model:
````

此方法提供 `commit` 参数,详见:[提交](../advanced/commit.md)
- 此方法提供 `flush` 参数,详见:[冲洗](../advanced/flush.md)
- 此方法提供 `commit` 参数,详见:[提交](../advanced/commit.md)

!!! note "关键字参数"

Expand Down
3 changes: 2 additions & 1 deletion docs/usage/create_models.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ async def create_models(
self,
session: AsyncSession,
objs: Iterable[CreateSchema],
flush: bool = False,
commit: bool = False,
**kwargs,
) -> list[Model]:
```

- 此方法提供 `flush` 参数,详见:[冲洗](../advanced/flush.md)
- 此方法提供 `commit` 参数,详见:[提交](../advanced/commit.md)

- 此方法还提供与 `create_model()` 相同用法的关键字参数,需要额外注意的是,`create_models()` 会将关键字参数写入每个实例中

## 示例
Expand Down
5 changes: 3 additions & 2 deletions docs/usage/delete_model.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ async def delete_model(
self,
session: AsyncSession,
pk: int,
flush: bool = False,
commit: bool = False,
) -> int:
```

- 此方法使用主键 pk 参数,详见:[主键](../advanced/primary_key.md)

- 此方法提供 `flush` 参数,详见:[冲洗](../advanced/flush.md)
- 此方法使用主键 `pk` 参数,详见:[主键](../advanced/primary_key.md)
- 此方法提供 `commit` 参数,详见:[提交](../advanced/commit.md)

## 示例
Expand Down
3 changes: 2 additions & 1 deletion docs/usage/delete_model_by_column.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ async def delete_model_by_column(
allow_multiple: bool = False,
logical_deletion: bool = False,
deleted_flag_column: str = 'del_flag',
flush: bool = False,
commit: bool = False,
**kwargs,
) -> int:
```

- 此方法提供 `flush` 参数,详见:[冲洗](../advanced/flush.md)
- 此方法提供 `commit` 参数,详见:[提交](../advanced/commit.md)

- 此方法可结合 [高级过滤器](../advanced/filter.md) 使用

## 删除多条
Expand Down
2 changes: 1 addition & 1 deletion docs/usage/select_model.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
async def select_model(self, session: AsyncSession, pk: int) -> Model | None:
```

此方法使用主键 pk 参数,详见:[主键](../advanced/primary_key.md)
此方法使用主键 `pk` 参数,详见:[主键](../advanced/primary_key.md)

## 示例

Expand Down
6 changes: 3 additions & 3 deletions docs/usage/update_model.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ async def update_model(
session: AsyncSession,
pk: int,
obj: UpdateSchema | dict[str, Any],
flush: bool = False,
commit: bool = False,
**kwargs,
) -> int:
```

- 此方法使用主键 pk 参数,详见:[主键](../advanced/primary_key.md)

- 此方法提供 `flush` 参数,详见:[冲洗](../advanced/flush.md)
- 此方法使用主键 `pk` 参数,详见:[主键](../advanced/primary_key.md)
- 此方法提供 `commit` 参数,详见:[提交](../advanced/commit.md)

- 此方法还提供与 `create_model()` 相同用法的关键字参数

## 示例
Expand Down
3 changes: 2 additions & 1 deletion docs/usage/update_model_by_column.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ async def update_model_by_column(
session: AsyncSession,
obj: UpdateSchema | dict[str, Any],
allow_multiple: bool = False,
flush: bool = False,
commit: bool = False,
**kwargs,
) -> int:
```

- 此方法提供 `flush` 参数,详见:[冲洗](../advanced/flush.md)
- 此方法提供 `commit` 参数,详见:[提交](../advanced/commit.md)

- 此方法可结合 [高级过滤器](../advanced/filter.md) 使用

## 更新多条
Expand Down
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ nav:
- 高级用法: usage/delete_model_by_column.md
- Advanced:
- 主键: advanced/primary_key.md
- 冲洗: advanced/flush.md
- 提交: advanced/commit.md
- 条件过滤: advanced/filter.md
- Changelog: changelog.md
Expand Down
30 changes: 27 additions & 3 deletions sqlalchemy_crud_plus/crud.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ async def create_model(
self,
session: AsyncSession,
obj: CreateSchema,
flush: bool = False,
commit: bool = False,
**kwargs,
) -> Model:
Expand All @@ -38,6 +39,7 @@ async def create_model(

:param session: The SQLAlchemy async session.
:param obj: The Pydantic schema containing data to be saved.
:param flush: If `True`, flush all object changes to the database. Default is `False`.
:param commit: If `True`, commits the transaction immediately. Default is `False`.
:param kwargs: Additional model data not included in the pydantic schema.
:return:
Expand All @@ -47,6 +49,8 @@ async def create_model(
else:
ins = self.model(**obj.model_dump(), **kwargs)
session.add(ins)
if flush:
await session.flush()
if commit:
await session.commit()
return ins
Expand All @@ -55,6 +59,7 @@ async def create_models(
self,
session: AsyncSession,
objs: Iterable[CreateSchema],
flush: bool = False,
commit: bool = False,
**kwargs,
) -> list[Model]:
Expand All @@ -63,6 +68,7 @@ async def create_models(

:param session: The SQLAlchemy async session.
:param objs: The Pydantic schema list containing data to be saved.
:param flush: If `True`, flush all object changes to the database. Default is `False`.
:param commit: If `True`, commits the transaction immediately. Default is `False`.
:param kwargs: Additional model data not included in the pydantic schema.
:return:
Expand All @@ -75,6 +81,8 @@ async def create_models(
ins = self.model(**obj.model_dump(), **kwargs)
ins_list.append(ins)
session.add_all(ins_list)
if flush:
await session.flush()
if commit:
await session.commit()
return ins_list
Expand Down Expand Up @@ -169,6 +177,7 @@ async def update_model(
session: AsyncSession,
pk: int,
obj: UpdateSchema | dict[str, Any],
flush: bool = False,
commit: bool = False,
**kwargs,
) -> int:
Expand All @@ -178,6 +187,7 @@ async def update_model(
:param session: The SQLAlchemy async session.
:param pk: The database primary key value.
:param obj: A pydantic schema or dictionary containing the update data
:param flush: If `True`, flush all object changes to the database. Default is `False`.
:param commit: If `True`, commits the transaction immediately. Default is `False`.
:return:
"""
Expand All @@ -189,6 +199,8 @@ async def update_model(
instance_data.update(kwargs)
stmt = update(self.model).where(self.primary_key == pk).values(**instance_data)
result = await session.execute(stmt)
if flush:
await session.flush()
if commit:
await session.commit()
return result.rowcount # type: ignore
Expand All @@ -198,6 +210,7 @@ async def update_model_by_column(
session: AsyncSession,
obj: UpdateSchema | dict[str, Any],
allow_multiple: bool = False,
flush: bool = False,
commit: bool = False,
**kwargs,
) -> int:
Expand All @@ -207,6 +220,7 @@ async def update_model_by_column(
:param session: The SQLAlchemy async session.
:param obj: A pydantic schema or dictionary containing the update data
:param allow_multiple: If `True`, allows updating multiple records that match the filters.
:param flush: If `True`, flush all object changes to the database. Default is `False`.
:param commit: If `True`, commits the transaction immediately. Default is `False`.
:param kwargs: Query expressions.
:return:
Expand All @@ -221,6 +235,8 @@ async def update_model_by_column(
instance_data = obj.model_dump(exclude_unset=True)
stmt = update(self.model).where(*filters).values(**instance_data) # type: ignore
result = await session.execute(stmt)
if flush:
await session.flush()
if commit:
await session.commit()
return result.rowcount # type: ignore
Expand All @@ -229,18 +245,22 @@ async def delete_model(
self,
session: AsyncSession,
pk: int,
flush: bool = False,
commit: bool = False,
) -> int:
"""
Delete an instance by model's primary key

:param session: The SQLAlchemy async session.
:param pk: The database primary key value.
:param flush: If `True`, flush all object changes to the database. Default is `False`.
:param commit: If `True`, commits the transaction immediately. Default is `False`.
:return:
"""
stmt = delete(self.model).where(self.primary_key == pk)
result = await session.execute(stmt)
if flush:
await session.flush()
if commit:
await session.commit()
return result.rowcount # type: ignore
Expand All @@ -251,18 +271,20 @@ async def delete_model_by_column(
allow_multiple: bool = False,
logical_deletion: bool = False,
deleted_flag_column: str = 'del_flag',
flush: bool = False,
commit: bool = False,
**kwargs,
) -> int:
"""
Delete
Delete an instance by model column

:param session: The SQLAlchemy async session.
:param commit: If `True`, commits the transaction immediately. Default is `False`.
:param kwargs: Query expressions.
:param allow_multiple: If `True`, allows deleting multiple records that match the filters.
:param logical_deletion: If `True`, enable logical deletion instead of physical deletion
:param deleted_flag_column: Specify the flag column for logical deletion
:param flush: If `True`, flush all object changes to the database. Default is `False`.
:param commit: If `True`, commits the transaction immediately. Default is `False`.
:param kwargs: Query expressions.
:return:
"""
filters = parse_filters(self.model, **kwargs)
Expand All @@ -275,6 +297,8 @@ async def delete_model_by_column(
else:
stmt = delete(self.model).where(*filters)
result = await session.execute(stmt)
if flush:
await session.flush()
if commit:
await session.commit()
return result.rowcount # type: ignore