@@ -8,9 +8,7 @@ SQLAlchemy CRUD Plus 提供强大的关系查询功能,支持 ORM 关系预加
88- ** join_conditions** - JOIN 条件控制(支持有无 relationship)
99- ** load_options** - 原生 SQLAlchemy 选项
1010
11- ## 两种关联方式
12-
13- ### ORM 关系(有 relationship)
11+ ## ORM 关系(有 relationship)
1412
1513使用 SQLAlchemy 的 ` relationship ` 定义关系,适合标准的外键关联。
1614
@@ -53,7 +51,7 @@ users = await user_crud.select_models(
5351)
5452```
5553
56- ### 纯逻辑关联(无 relationship)
54+ ## 纯逻辑关联(无 relationship)
5755
5856不定义 ` relationship ` ,在查询时通过 ` JoinConfig ` 动态关联。适合无外键约束的场景。
5957
@@ -324,110 +322,6 @@ users = await user_crud.select_models(
324322- ** 需要关联表数据** :使用 ` fill_result=True `
325323- ** 复杂查询/自定义字段** :使用原生 ` select() `
326324
327- #### 获取关联表数据
328-
329- ** 重要** :使用 ` join_conditions ` 的目的是获取多个表的数据,而不只是主表数据。
330-
331- ``` python
332- from sqlalchemy import select
333-
334- # 方式1:使用原生 select 获取多表数据
335- stmt = select(User, Post).join(
336- Post, User.id == Post.author_id
337- )
338- result = await session.execute(stmt)
339- for user, post in result.all():
340- print (f " { user.name} : { post.title} " )
341-
342- # 方式2:使用 JoinConfig + fill_result
343- results = await user_crud.select_models(
344- session,
345- join_conditions = [
346- JoinConfig(
347- model = Post,
348- join_on = User.id == Post.author_id,
349- join_type = ' left' ,
350- fill_result = True # 包含关联表数据
351- )
352- ]
353- )
354- for user, post in results:
355- print (f " { user.name} : { post.title if post else ' No post' } " )
356-
357- # 方式3:构建字典结果(推荐用于 API 返回)
358- stmt = select(User.name, User.email, Post.title, Post.created_at).join(
359- Post, User.id == Post.author_id
360- )
361- result = await session.execute(stmt)
362- data = [
363- {
364- ' user_name' : row.name,
365- ' user_email' : row.email,
366- ' post_title' : row.title,
367- ' post_created' : row.created_at
368- }
369- for row in result.all()
370- ]
371- ```
372-
373- #### 实际应用示例
374-
375- ``` python
376- # 查询用户和文章数据
377- async def get_users_with_posts (session : AsyncSession):
378- stmt = select(User, Post).join(
379- Post,
380- User.id == Post.author_id,
381- isouter = True
382- ).where(User.is_active == True )
383-
384- result = await session.execute(stmt)
385- rows = result.all()
386-
387- # 组织数据
388- user_posts = {}
389- for user, post in rows:
390- if user.id not in user_posts:
391- user_posts[user.id] = {
392- ' user' : user,
393- ' posts' : []
394- }
395- if post:
396- user_posts[user.id][' posts' ].append(post)
397-
398- return list (user_posts.values())
399-
400-
401- # 查询多表数据用于 API
402- async def get_post_list_api (session : AsyncSession, page : int = 1 ):
403- stmt = (
404- select(
405- Post.id,
406- Post.title,
407- Post.created_at,
408- User.name.label(' author_name' ),
409- Category.name.label(' category_name' )
410- )
411- .join(User, Post.author_id == User.id)
412- .join(Category, Post.category_id == Category.id, isouter = True )
413- .where(Post.is_published == True )
414- .limit(20 )
415- .offset((page - 1 ) * 20 )
416- )
417-
418- result = await session.execute(stmt)
419- return [
420- {
421- ' id' : row.id,
422- ' title' : row.title,
423- ' created_at' : row.created_at,
424- ' author' : row.author_name,
425- ' category' : row.category_name
426- }
427- for row in result.all()
428- ]
429- ```
430-
431325### JOIN 类型说明
432326
433327| 类型 | 说明 | 使用场景 |
@@ -657,6 +551,6 @@ user = await user_crud.select_model(
657551
658552## 相关资源
659553
660- - [ 过滤条件] ( ../advanced/ filter.md) - 高级过滤技术
661- - [ 事务控制] ( ../advanced/ transaction.md) - 事务管理
554+ - [ 过滤条件] ( filter.md ) - 高级过滤技术
555+ - [ 事务控制] ( transaction.md ) - 事务管理
662556- [ API 参考] ( ../api/crud-plus.md ) - 完整 API 文档
0 commit comments