2017-10-08 17 views
1

Pour plus d'informations sur l'ajout d'une entité dans le magasin de données cloud Google, procédez comme suit:Comment ajouter une entité à une banque de données dans Go Lang

La fonction Put est toujours remplacée par de nouvelles valeurs.

Toutes les suggestions seraient utiles.

09-OCT-2017:

I Used ci-dessous le code, mais la mise à jour encore entité au lieu d'ajouter (son effacement ancien & mis à jour avec la nouvelle valeur, mais je veux conserver les deux valeurs)

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

fmt.Fprint(w, input) 
taskKey := datastore.NameKey("Entity", "stringID", nil) 
var task Entity 
if err := tx.Get(taskKey, &task); err != nil { 
    log.Fatalf("tx.Get: %v", err) 
} 
task.Value = input 
if _, err := tx.Put(taskKey, &task); err != nil { 
    log.Fatalf("tx.Put: %v", err) 
} 
if _, err := tx.Commit(); err != nil { 
    log.Fatalf("tx.Commit: %v", err) 
} 
+0

Qu'est-ce que 'Entity' et' input'? Veuillez les poster et ce que vous voulez réaliser exactement. – icza

+0

L'entité est struct & input est une chaîne. _type struct entité { \t chaîne de valeur } entrée: = r.URL.Query() Get ("entrée") _ – vindl

+0

Et que voulez-vous "ajouter".? Que veux-tu accomplir? – icza

Répondre

1

Il ne peut y avoir qu'une seule instance, une seule entité liée/indiquée par la même clé de magasin de données.

Et les entités (liées à une clé) peuvent uniquement être remplacées, pas mises à jour/étendues/ajoutées progressivement. Donc, si vous avez déjà une entité enregistrée, pour la mettre à jour/la modifier, vous devez d'abord la charger, puis modifier l'entité en mémoire et écrire (enregistrer) l'entité modifiée. Cette sauvegarde remplacera l'entité existante dans le magasin de données.

Si, pour une propriété, vous souhaitez stocker plusieurs valeurs, le type de cette propriété doit prendre en charge le stockage de plusieurs valeurs. Slices dans Go sont de type.

Donc, dans votre exemple, votre entité devrait ressembler à ceci:

type Entity struct { 
    Values []string 
} 

Lorsque vous chargez un Entity existant, vous devez ajouter la nouvelle valeur à son champ Values, quelque chose comme ça (en pseudo-code):

e := ... // load existing entity 
e.Values = append(e.Values, input) // Append new data to Values 
// And now save Entity (e) with the same key 

Dans le code:

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

fmt.Fprint(w, input) 
taskKey := datastore.NameKey("Entity", "stringID", nil) 
var task Entity 
if err := tx.Get(taskKey, &task); err != nil { 
    log.Fatalf("tx.Get: %v", err) 
} 
task.Values = append(task.Values, input) 
if _, err := tx.Put(taskKey, &task); err != nil { 
    log.Fatalf("tx.Put: %v", err) 
} 
if _, err := tx.Commit(); err != nil { 
    log.Fatalf("tx.Commit: %v", err) 
} 

Si vous devez indexer cette propriété Values, vous risquez de rencontrer des problèmes si elle contient de nombreuses valeurs. Voir cette duplication possible pour plus de détails: App Engine Datastore: How to set multiple values on a property using golang?

Si vous rencontrez ce problème, vous devriez envisager de modéliser et de stocker vos données dans un format différent, par ex.enregistrement dans plusieurs entités, où une entité ne stockerait qu'un seul input, connecté à la clé à laquelle il appartient.

+0

Merci pour la suggestion Double bravo :) – vindl

1

Vous devez:

  • obtenir une entité première,
  • puis modifiez une valeur
  • et après cela mettez à jour l'entité dans le magasin de données.

S'il vous plaît consulter docs: https://cloud.google.com/datastore/docs/concepts/entities#updating_an_entity:

Pour mettre à jour une entité existante, modifier les propriétés de l'entité précédemment récupérés et le stocker en utilisant la clé:

tx, err := client.NewTransaction(ctx) 
if err != nil { 
     log.Fatalf("client.NewTransaction: %v", err) 
} 
var task Task 
if err := tx.Get(taskKey, &task); err != nil { 
     log.Fatalf("tx.Get: %v", err) 
} 
task.Priority = 5 
if _, err := tx.Put(taskKey, task); err != nil { 
     log.Fatalf("tx.Put: %v", err) 
} 
if _, err := tx.Commit(); err != nil { 
     log.Fatalf("tx.Commit: %v", err) 
} 
+0

J'ai utilisé le code ci-dessous. Je viens curieux de savoir pourquoi ci-dessous ne fonctionne pas de code (ajouter) .K: = datastore.NameKey ("entité", "stringID", nul) \t \t e: = Entité {entrée} \t si _, err = client.Put (ctx, k, &e); err! = nil { \t} – vindl

+0

J'ai mis à jour la requête selon votre suggestion, mais toujours pas de succès – vindl