首頁 > 後端開發 > Golang > 如何使用 AWS Go SDK 僅更新 DynamoDB 中的單一字段

如何使用 AWS Go SDK 僅更新 DynamoDB 中的單一字段

WBOY
發布: 2024-02-05 23:51:12
轉載
541 人瀏覽過

如何使用 AWS Go SDK 仅更新 DynamoDB 中的单个字段

問題內容

希望有人能夠闡明我一直在努力解決的這個問題。

我在dynamo 中有這個表,我們稱之為people ,在這個表中,我有id 的屬性作為我們的分區鍵、namelastnamestatus 。 我希望能夠只更新單一屬性或保存 id 的所有屬性。 現在,這就是我的做法。我創建了以下結構:

type personupdate struct {
    firstname     string `json:"firstname,omitempty"`
    lastname      string `json:"lastname,omitempty"`
    status        string `json:"status,omitempty"`
}
登入後複製

來自伺服器的請求只是更新該人的姓氏,因此我們的請求正文將如下所示:

{
    "lastname": "bob"
}
登入後複製

將請求綁定到結構後,將傳送到 dynamo 的物件如下所示:

{
    "firstname": "",
    "lastname": "bob",
    "status": "",
}
登入後複製

現在,如您所見,當需要寫入 dynamo 時,只應更新一個屬性,而其餘為空/空的屬性應被忽略。

為執行此操作而編寫的程式碼可以壓縮為以下操作:

// marshal our object
    _, err := dynamodbattribute.marshalmap(person)
    if err != nil{
        fmt.println("some error marshaling")
    }
    // create our update input
    input := &dynamodb.updateiteminput{
        key: map[string]*dynamodb.attributevalue{
            "id":{
                s: aws.string("1234"),
            },
        },
        tablename: aws.string("people"),
        expressionattributevalues: map[string]*dynamodb.attributevalue{
            ":fn": {
                s: aws.string(person.firstname),
            },
            ":ln":{
                s: aws.string(person.lastname),
            },
            ":st":{
                s: aws.string(person.status),
            },
        },
        updateexpression: aws.string("set firstname = :fn, lastname = :ln, status = :st"),
        returnvalues: aws.string("updated_new"),
    }
    // send update request to dynamo
    _, err := service.updateitem(input)
登入後複製

現在,更新沒有任何問題,問題是 firstnamestatus 的 null 值也被傳遞。我嘗試過閱讀他們的文檔,但還是有點困惑。我知道java sdk允許您傳遞一個名為update_skip_null_attributes的標誌,它允許您跳過那些空值並只更新那些有資料的值。我不知道 go 中的等效項是什麼,任何幫助/指導都會很棒。

更新:

嘗試使用以下模型:

type usermodel struct {
    firstname string `json:"firstname,omitempty" dynamodbav:"firstname,omitempty"`
    lastname  string `json:"lastname,omitempty" dynamodbav:"lastname,omitempty"`
}
登入後複製

遵循@jarmod 和@fedonev 給予的建議。從邏輯上講並使用文件就可以理解為什麼這應該有效,不幸的是,它沒有

決定將 sdk 從 v1 切換到 v2,看看更新它是否會有所幫助,儘管我又陷入了同樣的困境。這是我的更新函數的樣子。

update :=expression.Set(expression.Name("firstName"),expression.Value(user.FirstName))
    update.Set(expression.Name("lastName"), expression.Value(user.LastName))

    expr, err := expression.NewBuilder().WithUpdate(update).Build()

    if err != nil {
        "log error here..."
    }

    _, err = svc.UpdateItem(context.TODO(), &dynamodb.UpdateItemInput{
        TableName:                 aws.String("people"),
        Key:                       map[string]types.AttributeValue{"id": id},
        ExpressionAttributeNames:  expr.Names(),
        ExpressionAttributeValues: expr.Values(),
        UpdateExpression:          expr.Update(),
        ReturnValues:              types.ReturnValueUpdatedNew,
    })

    if err != nil {
        "log error here..."

    }
登入後複製

我最終通過編寫一個查詢和創建函數解決了我的問題,該函數幾乎通過我們想要更新的id 來查詢json 負載,並根據我們需要的內容進行查詢的差異進行更新,任何空字段都會被查詢結果替換。到目前為止它解決了我的問題,但我仍然想知道如何使用其預期功能進行更新。


正確答案


正如@jarmod 的評論所說,將dynamodbav:",omitempty" 標籤應用到編組結構時跳過零值欄位

type personupdate struct {
    firstname     string `json:"firstname,omitempty" dynamodbav:",omitempty"`
    lastname      string `json:"lastname,omitempty" dynamodbav:",omitempty"`
    status        string `json:"status,omitempty" dynamodbav:",omitempty"`
}
登入後複製

[編輯:新增用法] marshalmap 現在將忽略零值字段,尊重標籤。迭代地圖以建構更新表達式:

av, _ := attributevalue.MarshalMap(person)

update := expression.UpdateBuilder{}

for k, v := range av {
        update = update.Set(expression.Name(k), expression.Value(v))
}
登入後複製

建立表達式並將其輸出傳遞給 updateitem,如op中所示。

以上是如何使用 AWS Go SDK 僅更新 DynamoDB 中的單一字段的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:stackoverflow.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板