tortoise-orm 怎麼將兩張無關聯的表根據相同欄位進行join
时间: 2025-03-31 09:12:19 浏览: 24
### Tortoise-ORM 中 Join 两个无关联表的操作
在 Tortoise-ORM 中,默认情况下,`JOIN` 操作仅支持具有显式定义的外键关系的模型之间的操作。然而,在某些场景下,可能需要对两个没有直接外键关系的表通过某个共同字段执行 `JOIN` 操作。这种需求可以通过自定义 SQL 或者利用 Tortoise-ORM 提供的原始查询功能来实现。
#### 自定义 SQL 实现 JOIN
如果两个表之间不存在外键关系,但希望通过某一公共字段进行连接,则可以使用 Tortoise-ORM 的 `.raw()` 方法来运行原生 SQL 查询。以下是具体实现方式:
```python
from tortoise.models import Model
from tortoise.fields import IntField, CharField
from tortoise.expressions import RawSQL
class TableA(Model):
id = IntField(pk=True)
common_field = CharField(max_length=50)
class TableB(Model):
id = IntField(pk=True)
common_field = CharField(max_length=50)
# 原始 SQL 查询
query = """
SELECT a.*, b.*
FROM table_a AS a
INNER JOIN table_b AS b ON a.common_field = b.common_field;
"""
results = await TableA.raw(query)
for result in results:
print(result.id, result.common_field) # 输出结果
```
上述代码展示了如何通过 `.raw()` 执行一条标准的 SQL `JOIN` 查询[^1]。此方法允许开发者绕过 ORM 对于外键约束的要求,从而自由地设计复杂的查询逻辑。
#### 使用表达式构建复杂查询
尽管 Tortoise-ORM 并未提供内置的支持用于处理非外键关联的两张表间的联结操作,但是它允许我们借助其灵活的表达式系统创建更高级别的条件过滤器。不过需要注意的是,这种方式通常只适用于简单的筛选而非真正的多表联合检索。
例如,假设存在如下情况——我们需要找到所有匹配特定条件的数据项而无需实际建立正式的关系链接时,可采用以下策略之一作为替代方案:
```python
async def get_joined_data():
table_a_records = await TableA.all()
table_b_records = await TableB.all()
joined_results = []
for record_a in table_a_records:
matching_record_b = [
rec_b for rec_b in table_b_records
if rec_b.common_field == record_a.common_field
]
if matching_record_b:
combined_result = {**record_a.__dict__, **matching_record_b[0].__dict__}
joined_results.append(combined_result)
return joined_results
```
这种方法虽然有效,但在性能上可能会有所牺牲,特别是在涉及大量记录的时候。因此推荐优先考虑基于数据库层面优化过的解决方案比如前面提到的 raw sql 方案[^3]。
### 总结
当面对无法直接应用传统 ORM 关系映射的情况时,可以选择适当工具完成任务目标。对于 Tortoise-ORM 而言,无论是运用强大的 raw query 功能还是巧妙组合现有 API 都能够帮助解决这类问题。
阅读全文
相关推荐


















