You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python中为Fauna DB创建含其他集合文档引用的文档?

在Python中规范创建Fauna DB带文档引用的集合文档

问题背景

我在Fauna DB中有一个yalofiles集合,Schema定义如下:

collection yalofiles {
  yaloid: Ref<yalos>
  yaloContentId: String
  name: String
  *: Any
}

其中yaloid字段需要引用yalos集合中的文档。当前环境配置:

  • Python版本:3.12.5
  • PyPi的fauna 2.3.0(Fauna v10官方Python驱动)

我尝试编写代码创建yalofile文档,但遇到了错误。初始代码如下(已移除try/except块):

def insertYalofile(self, yalofile, yaloId):
   qyalo = fql(f'{YALOS_COLLECTION}.byId({yaloId})')
   ryalo: QuerySuccess = self._client.query(qyalo)
   yalofile["yaloid"] = ryalo.data  # 这里传入了完整的Document对象
   query = fql(f'{YALOFILES_COLLECTION}.create({yalofile})')
   res: QuerySuccess = self._client.query(query)  # 此查询失败
   return res.data

执行后抛出错误:

400: invalid_query The query failed 1 validation check
--- 
error: Expected `)` or `,` at *query*:1:40   
  |
1 | yalofiles.create({'yaloid': Document(id='412701900943655120',coll=Module(name='yalos'),ts=datetime.datetime(2024, 10, 25, 7, 40, 53, 280000, tzinfo=datetime.timezone.utc),data={'name':'alfred stevens','yalotype':'artist','displayname':'Alfred Stevens','owner':'yaluba','artist':'412652432707813579','tags':['412472715978473675']}), 'yaloContentId': '66f5bbd2bff7b6328f8fb52a', 'name': 'alfred stevens', 'isMain': True, 'mime': 'image/jpeg', 'provider': 'cloudflare', 'stosol': 'r2'})
  |                                        ^
  |

显然直接传入完整Document对象不行。我尝试过使用models.DocumentReference(YALOS_COLLECTION, yaloId),但依然报错。目前只能通过手动拼接FQL字符串实现,但这种方式需要手动处理格式,非常不规范:

yalofilestr = '{ \'yaloid\': yalos(' + yaloId + '), ' + repr(yalofile)[1:] 
yalofilestr = yalofilestr.replace("True", "true") ;
yalofilestr = yalofilestr.replace("False", "false")
query = fql(f'{YALOFILES_COLLECTION}.create({yalofilestr})')

请问在Python中,如何规范创建包含其他集合文档引用的Fauna DB集合文档?


规范解决方案

方案1:使用Document对象的ref属性

当你通过byId查询获取到完整Document对象时,直接取它的ref属性即可,这个属性就是符合要求的引用类型:

def insertYalofile(self, yalofile, yaloId):
    qyalo = fql(f'{YALOS_COLLECTION}.byId({yaloId})')
    ryalo: QuerySuccess = self._client.query(qyalo)
    yalofile["yaloid"] = ryalo.data.ref  # 使用Document的ref属性
    query = fql(f'{YALOFILES_COLLECTION}.create({yalofile})')
    res: QuerySuccess = self._client.query(query)
    return res.data

方案2:直接构造引用(无需先查询目标文档)

如果已经知道目标文档的ID,可以直接在FQL中构造引用,不需要提前查询文档,推荐用参数化查询避免字符串拼接风险:

def insertYalofile(self, yalofile, yaloId):
    # 合并数据并使用参数化查询
    create_data = {**yalofile, "yaloid": fql(f"{YALOS_COLLECTION}.byId({yaloId})")}
    query = fql('${coll}.create(${data})', coll=YALOFILES_COLLECTION, data=create_data)
    res: QuerySuccess = self._client.query(query)
    return res.data

方案3:正确使用DocumentReference类

使用DocumentReference时,需要将其作为参数传入FQL查询,而不是直接拼接到字符串中:

from fauna.models import DocumentReference

def insertYalofile(self, yalofile, yaloId):
    yalo_ref = DocumentReference(collection_name=YALOS_COLLECTION, document_id=yaloId)
    # 合并数据字典与引用
    create_data = {**yalofile, "yaloid": yalo_ref}
    query = fql('${coll}.create(${data})', coll=YALOFILES_COLLECTION, data=create_data)
    res: QuerySuccess = self._client.query(query)
    return res.data

内容的提问来源于stack exchange,提问作者juan noguera

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 20:23:16