0

0

更新 Datastore 实体:如何在不改变实体键的情况下修改祖先

DDD

DDD

发布时间:2025-09-15 17:32:01

|

917人浏览过

|

来源于php中文网

原创

更新 datastore 实体:如何在不改变实体键的情况下修改祖先

在 Google Cloud Datastore 中,实体的键(Key)是其唯一标识符。键的组成部分包括种类(Kind)、名称或 ID,以及祖先路径(Ancestor Path)。祖先路径定义了实体在数据层级结构中的位置。因此,无法直接在不改变实体键的情况下修改实体的祖先,因为祖先是键的一部分。

如果尝试更改实体的祖先,实际上是在创建一个新的实体,而原始实体仍然存在。这可能会导致数据不一致或其他问题,特别是在现有代码中已经使用旧键引用的情况下。

替代方案:使用属性而非实体组

如果你的应用场景允许,可以考虑避免使用实体组,并采用以下替代方案:

  1. 在实体中添加属性来表示层级关系。 例如,对于 Company/Department/Employee 这种层级结构,可以在 Employee 实体中添加 Company 和 Department 属性。
type Employee struct {
    Company    string `datastore:"company"`
    Department string `datastore:"department"`
    Name       string `datastore:"name"`
}
  1. 使用属性进行查询。 即使没有实体组,你仍然可以通过这些属性进行查询。
q := datastore.NewQuery("Employee").
    Filter("company =", "MyCompany").
    Filter("department =", "MyDepartment")

var employees []*Employee
keys, err := client.GetAll(ctx, q, &employees)
if err != nil {
    // Handle error
}

示例代码

以下是一个完整的示例,展示了如何使用属性来模拟层级关系:

package main

import (
    "context"
    "fmt"
    "log"
    "os"

    "cloud.google.com/go/datastore"
)

type Employee struct {
    Company    string `datastore:"company"`
    Department string `datastore:"department"`
    Name       string `datastore:"name"`
}

func main() {
    ctx := context.Background()

    // Replace "your-project-id" with your actual Google Cloud project ID.
    projectID := os.Getenv("GOOGLE_CLOUD_PROJECT")
    if projectID == "" {
        log.Fatalf("GOOGLE_CLOUD_PROJECT environment variable must be set.")
    }

    client, err := datastore.NewClient(ctx, projectID)
    if err != nil {
        log.Fatalf("Failed to create client: %v", err)
    }
    defer client.Close()

    // Create a new Employee entity.
    employee := &Employee{
        Company:    "MyCompany",
        Department: "MyDepartment",
        Name:       "John Doe",
    }

    // Create a key for the entity.
    key := datastore.NameKey("Employee", "john.doe", nil)

    // Save the entity to Datastore.
    _, err = client.Put(ctx, key, employee)
    if err != nil {
        log.Fatalf("Failed to save employee: %v", err)
    }

    fmt.Println("Employee saved successfully.")

    // Query for the employee.
    q := datastore.NewQuery("Employee").
        Filter("company =", "MyCompany").
        Filter("department =", "MyDepartment").
        Filter("name =", "John Doe")

    var employees []*Employee
    keys, err := client.GetAll(ctx, q, &employees)
    if err != nil {
        log.Fatalf("Failed to query employees: %v", err)
    }

    if len(employees) > 0 {
        fmt.Printf("Found employee: %+v, key: %+v\n", employees[0], keys[0])
    } else {
        fmt.Println("Employee not found.")
    }
}

注意事项:

LobeHub
LobeHub

LobeChat brings you the best user experience of ChatGPT, OLLaMA, Gemini, Claude

下载
  • 确保已设置 GOOGLE_CLOUD_PROJECT 环境变量
  • 将 datastore:"company" 等标签添加到结构体字段,以便 Datastore 知道如何将数据映射到实体。
  • 使用 datastore.NameKey 创建具有名称的键,或使用 datastore.IDKey 创建具有 ID 的键。

强一致性与最终一致性

使用属性进行查询时,需要注意数据一致性。Datastore 查询通常是最终一致的,这意味着在属性更新后,可能需要几秒钟的时间才能反映在查询结果中。

如果需要强一致性,可以通过键直接查找实体。按键查找始终返回最新的版本。

// Get the employee by key.
var employee Employee
err = client.Get(ctx, key, &employee)
if err != nil {
    log.Fatalf("Failed to get employee by key: %v", err)
}

fmt.Printf("Employee retrieved by key: %+v\n", employee)

总结

虽然无法直接修改 Datastore 实体的祖先而不改变其键,但通过在实体中添加属性来表示层级关系,可以有效避免实体组带来的限制,并提供更灵活的数据管理方式。在选择方案时,请根据你的应用场景和对数据一致性的要求进行权衡。如果需要强一致性,请使用键直接查找实体。

相关专题

更多
mysql标识符无效错误怎么解决
mysql标识符无效错误怎么解决

mysql标识符无效错误的解决办法:1、检查标识符是否被其他表或数据库使用;2、检查标识符是否包含特殊字符;3、使用引号包裹标识符;4、使用反引号包裹标识符;5、检查MySQL的配置文件等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

182

2023.12.04

Python标识符有哪些
Python标识符有哪些

Python标识符有变量标识符、函数标识符、类标识符、模块标识符、下划线开头的标识符、双下划线开头、双下划线结尾的标识符、整型标识符、浮点型标识符等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

280

2024.02.23

java标识符合集
java标识符合集

本专题整合了java标识符相关内容,想了解更多详细内容,请阅读下面的文章。

255

2025.06.11

c++标识符介绍
c++标识符介绍

本专题整合了c++标识符相关内容,阅读专题下面的文章了解更多详细内容。

121

2025.08.07

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

197

2025.06.09

golang结构体方法
golang结构体方法

本专题整合了golang结构体相关内容,请阅读专题下面的文章了解更多。

190

2025.07.04

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

197

2025.06.09

golang结构体方法
golang结构体方法

本专题整合了golang结构体相关内容,请阅读专题下面的文章了解更多。

190

2025.07.04

Java编译相关教程合集
Java编译相关教程合集

本专题整合了Java编译相关教程,阅读专题下面的文章了解更多详细内容。

9

2026.01.21

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Go 教程
Go 教程

共32课时 | 4万人学习

Go语言实战之 GraphQL
Go语言实战之 GraphQL

共10课时 | 0.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号