Skip to content

Commit 78d3639

Browse files
committed
feat: update doc
1 parent 7227304 commit 78d3639

2 files changed

Lines changed: 41 additions & 17 deletions

File tree

README.md

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,17 @@ from commondao.annotation import TableId
3535
from pydantic import BaseModel
3636
from typing import Annotated
3737

38-
# Define your Pydantic model with TableId annotation
38+
# Define your Pydantic models with TableId annotation
3939
class User(BaseModel):
4040
id: Annotated[int, TableId('users')] # First field with TableId is the primary key
4141
name: str
4242
email: str
4343

44+
class UserInsert(BaseModel):
45+
id: Annotated[Optional[int], TableId('users')] = None # Optional for auto-increment
46+
name: str
47+
email: str
48+
4449
async def main():
4550
# Connect to database
4651
config = {
@@ -54,7 +59,7 @@ async def main():
5459

5560
async with connect(**config) as db:
5661
# Insert a new user using Pydantic model
57-
user = User(id=1, name='John Doe', email='john@example.com')
62+
user = UserInsert(name='John Doe', email='john@example.com')
5863
await db.insert(user)
5964

6065
# Query the user by key with Pydantic model validation
@@ -91,30 +96,35 @@ from pydantic import BaseModel
9196
from commondao.annotation import TableId
9297
from typing import Annotated, Optional
9398

94-
class User(BaseModel):
99+
class UserInsert(BaseModel):
95100
id: Annotated[Optional[int], TableId('users')] = None # Auto-increment primary key
96101
name: str
97102
email: str
98103

99104
# Insert using Pydantic model (id will be auto-generated)
100-
user = User(name='John', email='john@example.com')
105+
user = UserInsert(name='John', email='john@example.com')
101106
await db.insert(user)
102107
print(f"New user id: {db.lastrowid()}") # Get the auto-generated id
103108

104109
# Insert with ignore option (skips duplicate key errors)
105-
user2 = User(name='Jane', email='jane@example.com')
110+
user2 = UserInsert(name='Jane', email='jane@example.com')
106111
await db.insert(user2, ignore=True)
107112
```
108113

109114
### Update Data (with Pydantic Models)
110115

111116
```python
117+
class UserUpdate(BaseModel):
118+
id: Optional[int] = None
119+
name: Optional[str] = None
120+
email: Optional[str] = None
121+
112122
# Update by primary key (id must be provided)
113-
user = User(id=1, name='John Smith', email='john.smith@example.com')
123+
user = UserUpdate(id=1, name='John Smith', email='john.smith@example.com')
114124
await db.update_by_id(user)
115125

116-
# Update by custom key (partial update - only non-None fields)
117-
user_update = User(name='Jane Doe', email='jane.doe@example.com') # id can be None
126+
# Update by custom key (partial update - only specified fields)
127+
user_update = UserUpdate(name='Jane Doe', email='jane.doe@example.com')
118128
await db.update_by_key(user_update, key={'email': 'john.smith@example.com'})
119129
```
120130

@@ -294,23 +304,23 @@ result = await db.execute_query(
294304
from commondao.annotation import TableId
295305
from typing import Annotated, Optional
296306

297-
class Order(BaseModel):
307+
class OrderInsert(BaseModel):
298308
id: Annotated[Optional[int], TableId('orders')] = None
299309
customer_id: int
300310
total: float
301311

302-
class OrderItem(BaseModel):
312+
class OrderItemInsert(BaseModel):
303313
id: Annotated[Optional[int], TableId('order_items')] = None
304314
order_id: int
305315
product_id: int
306316

307317
async with connect(host='localhost', user='root', db='testdb') as db:
308318
# Start transaction (autocommit=False by default)
309-
order = Order(customer_id=1, total=99.99)
319+
order = OrderInsert(customer_id=1, total=99.99)
310320
await db.insert(order)
311321
order_id = db.lastrowid() # Get the auto-generated order id
312322

313-
item = OrderItem(order_id=order_id, product_id=42)
323+
item = OrderItemInsert(order_id=order_id, product_id=42)
314324
await db.insert(item)
315325

316326
# Commit the transaction

reference.md

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ Insert a Pydantic model instance into the database.
5454

5555
**Example:**
5656
```python
57-
user = User(name='John', email='john@example.com')
57+
user = UserInsert(name='John', email='john@example.com')
5858
affected_rows = await db.insert(user)
5959
```
6060

@@ -72,7 +72,7 @@ Update a record by its primary key using a Pydantic model.
7272

7373
**Example:**
7474
```python
75-
user = User(id=1, name='John Updated', email='john.new@example.com')
75+
user = UserUpdate(id=1, name='John Updated', email='john.new@example.com')
7676
affected_rows = await db.update_by_id(user)
7777
```
7878

@@ -88,7 +88,7 @@ Update records matching the specified key conditions.
8888

8989
**Example:**
9090
```python
91-
user_update = User(name='Jane', email='jane@example.com')
91+
user_update = UserUpdate(name='Jane', email='jane@example.com')
9292
affected_rows = await db.update_by_key(user_update, key={'id': 1})
9393
```
9494

@@ -494,7 +494,7 @@ Raised when attempting operations with empty or None primary key values.
494494
**Example:**
495495
```python
496496
try:
497-
user = User(id=None, name="John")
497+
user = UserUpdate(id=None, name="John")
498498
await db.update_by_id(user)
499499
except EmptyPrimaryKeyError as e:
500500
print(f"Primary key error: {e}")
@@ -566,7 +566,7 @@ def process_database_row(data: dict):
566566
assert is_row_dict(data)
567567
# Type checker now knows data is RowDict
568568
# Safe to use for database operations
569-
user = User(**data)
569+
user = UserInsert(**data)
570570
await db.insert(user)
571571

572572
def process_query_parameters(params: dict):
@@ -619,3 +619,17 @@ def example_function(unknown_data: dict):
619619
unknown_data # Type checker knows this is safe
620620
)
621621
```
622+
623+
## Best Practices
624+
625+
### Entity Class Naming Conventions
626+
627+
When designing Pydantic models for database operations, follow these naming conventions to improve code clarity and maintainability:
628+
629+
把dao.insert的实体类命名为以Insert为后缀的类名; 把dao.update的实体类重命名为以Update为后缀的类名; 其他用于查询的类名不变
630+
631+
一般来说, 用于查询的实体类如果字段DDL为not null,则字段就不能optional; 用于insert的实体类如果字段DDL为nullable,或者有默认值,则字段就可以optional;用于update的实体类的字段都是optional
632+
633+
用于insert的实体类只包含可能需要插入的字段;用于update的实体类只包含可能需要修改的字段
634+
635+
用于insert/update的实体类,即使主键字段是optional,也需要注解TableId

0 commit comments

Comments
 (0)