Heim  >  Artikel  >  Backend-Entwicklung  >  So aktualisieren Sie nur ein einzelnes Feld in DynamoDB mit dem AWS Go SDK

So aktualisieren Sie nur ein einzelnes Feld in DynamoDB mit dem AWS Go SDK

WBOY
WBOYnach vorne
2024-02-05 23:51:12455Durchsuche

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

Frageninhalt

Hoffentlich kann jemand etwas Licht in dieses Problem bringen, mit dem ich zu kämpfen habe.

Ich habe diesen Tisch in Dynamo, nennen wir ihn people ,在这个表中,我有 id 的属性作为我们的分区键、namelastnamestatus . Ich möchte nur eine einzelne Eigenschaft aktualisieren oder alle Eigenschaften der ID speichern können. Nun, so mache ich es. Ich habe folgende Struktur erstellt:

type personupdate struct {
    firstname     string `json:"firstname,omitempty"`
    lastname      string `json:"lastname,omitempty"`
    status        string `json:"status,omitempty"`
}

Die Anfrage vom Server aktualisiert lediglich den Nachnamen der Person, sodass unser Anfragetext wie folgt aussieht:

{
    "lastname": "bob"
}

Nachdem die Anfrage an die Struktur gebunden wurde, sieht das Objekt, das an Dynamo gesendet wird, folgendermaßen aus:

{
    "firstname": "",
    "lastname": "bob",
    "status": "",
}

Wie Sie sehen können, sollte beim Schreiben an Dynamo nur eine Eigenschaft aktualisiert werden und die restlichen leeren/leeren Eigenschaften sollten ignoriert werden.

Der hierfür geschriebene Code kann wie folgt zusammengefasst werden:

// 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)

Jetzt gibt es kein Problem mit der Aktualisierung, das Problem ist das firstnamestatus 的 null 值也被传递。我尝试过阅读他们的文档,但还是有点困惑。我知道java sdk允许您传递一个名为update_skip_null_attributes-Flag, das es Ihnen ermöglicht, diese Nullwerte zu überspringen und nur die Werte zu aktualisieren, die Daten enthalten. Ich weiß nicht, was das Äquivalent in go ist, jede Hilfe/Anleitung wäre großartig.

Update:

Versuchen Sie es mit den folgenden Modellen:

type usermodel struct {
    firstname string `json:"firstname,omitempty" dynamodbav:"firstname,omitempty"`
    lastname  string `json:"lastname,omitempty" dynamodbav:"lastname,omitempty"`
}

Folgen Sie den Ratschlägen von @jarmod und @fedonev. Logischerweise und anhand der Dokumentation kann man nachvollziehen, warum das funktionieren sollte, leider funktioniert es nicht

Ich habe beschlossen, das SDK von Version 1 auf Version 2 umzustellen, um zu sehen, ob eine Aktualisierung helfen würde, obwohl ich wieder in der gleichen misslichen Lage stecke. So sieht meine Update-Funktion aus.

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..."

    }

Am Ende habe ich mein Problem gelöst, indem ich eine Abfrage- und Erstellungsfunktion geschrieben habe, die die JSON-Nutzlast praktisch anhand der ID abfragt, die wir aktualisieren möchten, und basierend auf dem Unterschied zwischen dem, was wir abfragen müssen, aktualisiert. Alle leeren Felder werden als Ergebnisersetzung abgefragt. Bisher hat es mein Problem gelöst, aber ich frage mich immer noch, wie ich es mit der beabsichtigten Funktionalität aktualisieren kann.


Richtige Antwort


Wie im Kommentar von @jarmod steht, werden Nullwertfelder übersprungen, wenn dynamodbav:",omitempty"-Tags auf Marshallingstrukturen angewendet werden:

type personupdate struct {
    firstname     string `json:"firstname,omitempty" dynamodbav:",omitempty"`
    lastname      string `json:"lastname,omitempty" dynamodbav:",omitempty"`
    status        string `json:"status,omitempty" dynamodbav:",omitempty"`
}

[BEARBEITEN: Verwendung hinzugefügt] marshalmap Nullwertfelder werden jetzt unter Berücksichtigung der Beschriftungen ignoriert. Durchlaufen Sie die Karte, um einen Aktualisierungsausdruck zu erstellen:

av, _ := attributevalue.MarshalMap(person)

update := expression.UpdateBuilder{}

for k, v := range av {
        update = update.Set(expression.Name(k), expression.Value(v))
}

Erstellen Sie den Ausdruck und übergeben Sie seine Ausgabe an updateitem, wie in der Operation gezeigt.

Das obige ist der detaillierte Inhalt vonSo aktualisieren Sie nur ein einzelnes Feld in DynamoDB mit dem AWS Go SDK. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen