Amazon DynamoDB - Manuel du développeur
Transcription
Amazon DynamoDB - Manuel du développeur
Amazon DynamoDB Manuel du développeur API Version 2012-08-10 Amazon DynamoDB Manuel du développeur Amazon DynamoDB Manuel du développeur Amazon DynamoDB: Manuel du développeur Copyright © 2017 Amazon Web Services, Inc. and/or its affiliates. All rights reserved. Amazon's trademarks and trade dress may not be used in connection with any product or service that is not Amazon's, in any manner that is likely to cause confusion among customers, or in any manner that disparages or discredits Amazon. All other trademarks not owned by Amazon are the property of their respective owners, who may or may not be affiliated with, connected to, or sponsored by Amazon. Amazon DynamoDB Manuel du développeur Table of Contents Qu'est-ce que Amazon DynamoDB ? ............................................................................................... 1 Comment ça fonctionne ......................................................................................................... 2 Composants de base .................................................................................................... 2 L'API DynamoDB .......................................................................................................... 9 Règles de dénomination et types de données .................................................................. 11 Cohérence en lecture .................................................................................................. 16 Débit réservé .............................................................................................................. 17 Partitions et distribution des données ............................................................................. 20 De SQL à NoSQL ............................................................................................................... 23 SQL ou NoSQL ? ........................................................................................................ 23 Accès à la base de données ........................................................................................ 25 Création d'une table .................................................................................................... 27 Obtention d'informations sur une table ............................................................................ 29 Ecriture de données dans une table ............................................................................... 30 Lecture de données à partir d'une table .......................................................................... 32 Gestion des index ....................................................................................................... 38 Modification de données dans une table ......................................................................... 41 Suppression de données d'une table .............................................................................. 43 Suppression d'une table ............................................................................................... 44 Configuration d'DynamoDB ........................................................................................................... 45 Configuration de DynamoDB (version téléchargeable) ............................................................... 45 Téléchargement et exécution de DynamoDB ................................................................... 45 Définition du point de terminaison local ........................................................................... 47 Notes d'utilisation ........................................................................................................ 48 Configuration de DynamoDB (service web) ............................................................................. 49 Inscrivez-vous à AWS .................................................................................................. 49 Obtenir votre ID de clé d'accès AWS et votre clé secrète .................................................. 49 Accès à DynamoDB .................................................................................................................... 51 Utilisation de la console ....................................................................................................... 51 Utilisation des éléments et des attributs .......................................................................... 53 Surveillance des tables ................................................................................................ 57 Configuration des alarmes CloudWatch .......................................................................... 58 Gestion de Flux DynamoDB et des déclencheurs ............................................................. 58 Utilisation de l'interface de ligne de commande ........................................................................ 59 Téléchargement et configuration de la AWS CLI .............................................................. 60 Utilisation de la AWS CLI avec DynamoDB ..................................................................... 60 Utilisation de la AWS CLI avec DynamoDB téléchargeable ................................................ 61 Utilisation de l'API ............................................................................................................... 62 Programmation avec DynamoDB ................................................................................................... 63 Présentation de la prise en charge du kit SDK AWS pour DynamoDB .......................................... 63 Interfaces par programmation ................................................................................................ 65 Interfaces de bas niveau .............................................................................................. 66 Interfaces de document ................................................................................................ 67 Interface de persistance des objets ................................................................................ 67 API DynamoDB de bas niveau .............................................................................................. 69 Format des demandes ................................................................................................. 71 Format de la réponse .................................................................................................. 71 Descripteurs de type de données .................................................................................. 72 Données numériques ................................................................................................... 73 Données binaires ........................................................................................................ 73 Gestion des erreurs ............................................................................................................. 73 Composants erreur ...................................................................................................... 74 Codes et messages d'erreur ......................................................................................... 74 Gestion des erreurs dans votre application ...................................................................... 77 Nouvelles tentatives après erreur et interruptions exponentielles ......................................... 77 API Version 2012-08-10 iv Amazon DynamoDB Manuel du développeur Opérations par lot et gestion des erreurs ........................................................................ 78 Interfaces de programmation de niveau supérieur pour DynamoDB ............................................. 79 Java : DynamoDBMapper ............................................................................................. 79 .NET : Modèle de document ........................................................................................ 117 .NET : modèle de persistance des objets ...................................................................... 140 Exécution des exemples de code ......................................................................................... 167 Chargement des exemples de données ........................................................................ 167 Exemples de Code Java ............................................................................................. 173 Exemples de code .NET ............................................................................................. 175 Exemples de Code PHP ............................................................................................. 177 Utilisation d'DynamoDB .............................................................................................................. 179 Utilisation de tables ........................................................................................................... 179 Spécification de la clé primaire .................................................................................... 180 Exigences de lecture et d'écriture pour des tables .......................................................... 180 Calcul des unités de capacité ...................................................................................... 182 Liste et description des tables ..................................................................................... 184 Balisage pour DynamoDB ........................................................................................... 185 Utilisation des tables : Java ........................................................................................ 187 Utilisation de tables : .NET .......................................................................................... 192 Utilisation des tables : PHP ......................................................................................... 199 Utilisation d'éléments ......................................................................................................... 206 Présentation ............................................................................................................. 206 Lecture d'un élément .................................................................................................. 207 Ecriture d'un élément ................................................................................................. 208 Opérations par lot ...................................................................................................... 208 Compteurs atomiques ................................................................................................ 209 Ecritures conditionnelles ............................................................................................. 209 Lecture et écriture d'éléments à l'aide d'expressions ....................................................... 211 Utilisation d'éléments : Java ........................................................................................ 231 Utilisation des éléments : .NET .................................................................................... 253 Utilisation des éléments : PHP ..................................................................................... 277 Utilisation des requêtes et des analyses ............................................................................... 290 Interrogation ............................................................................................................. 291 Analyser ................................................................................................................... 292 Filtrage des résultats d'une opération Query ou Scan ...................................................... 292 Unités de capacité consommées par les opérations Query et Scan .................................... 293 Pagination des résultats ............................................................................................. 293 Limite ....................................................................................................................... 294 Comptabilisation des éléments d'une réponse ................................................................ 294 Cohérence en lecture ................................................................................................. 295 Performances des opérations Query et Scan ................................................................. 295 Analyse en parallèle .................................................................................................. 296 Interrogation ............................................................................................................. 298 Analyse .................................................................................................................... 314 Utilisation des index ........................................................................................................... 337 Index secondaires globaux .......................................................................................... 340 Index secondaires locaux ........................................................................................... 387 Utilisation des flux ............................................................................................................. 430 Point de terminaisons pour Flux DynamoDB .................................................................. 431 Activation d'un flux ..................................................................................................... 432 Lecture et traitement de flux ........................................................................................ 433 Utilisation de Flux DynamoDB Kinesis Adapter pour traiter les enregistrements de flux .......... 435 Procédure pas à pas : API de bas niveau Flux DynamoDB .............................................. 448 Réplication entre régions ............................................................................................ 455 Déclencheurs Flux DynamoDB et AWS Lambda ............................................................. 455 Authentification et contrôle d'accès ............................................................................................... 465 Authentification .................................................................................................................. 465 Contrôle d'accès ................................................................................................................ 467 API Version 2012-08-10 v Amazon DynamoDB Manuel du développeur Présentation de la gestion de l'accès .................................................................................... Opérations et ressources Amazon DynamoDB ............................................................... Présentation de la propriété des ressources .................................................................. Gestion de l'accès aux ressources ............................................................................... Spécification des éléments d'une stratégie : actions, effets et mandataires .......................... Spécification des conditions dans une stratégie .............................................................. Utilisation des stratégies basées sur une identité (stratégies IAM) ............................................. Autorisations de la console ......................................................................................... Stratégies gérées AWS (prédéfinies) pour Amazon DynamoDB ......................................... Exemples de stratégies gérées par le client ................................................................... Référence des autorisations d'API DynamoDB ....................................................................... Rubriques connexes .................................................................................................. Utilisation de conditions ...................................................................................................... Présentation ............................................................................................................. Spécification de conditions : Utilisation de clés de condition .............................................. Rubriques connexes .................................................................................................. Utilisation de la fédération d'identité web ............................................................................... Ressources supplémentaires pour la fédération d'identité web .......................................... Exemple de stratégie pour la fédération d'identité web ..................................................... Préparation de l'utilisation de la fédération d'identité web ................................................. Ecriture de votre application pour utiliser la fédération d'identité web .................................. Supervision de Amazon DynamoDB ............................................................................................. Outils de supervision .......................................................................................................... Outils automatiques ................................................................................................... Outils manuels .......................................................................................................... Supervision avec Amazon CloudWatch ................................................................................. Métriques et dimensions ............................................................................................. Utilisation de métriques .............................................................................................. Création d'alarmes ..................................................................................................... Journalisation des opérations DynamoDB à l'aide de AWS CloudTrail ........................................ Informations DynamoDB dans CloudTrail ...................................................................... Présentation des entrées des fichiers journaux DynamoDB .............................................. Intégration à d'autres services AWS ............................................................................................. Intégration à Amazon Redshift ............................................................................................. Intégration à Amazon EMR ................................................................................................. Présentation ............................................................................................................. Didacticiel : Utilisation avec Amazon DynamoDB et Apache Hive ...................................... Création d'une table externe dans Hive ......................................................................... Traitement des instructions HiveQL .............................................................................. Interrogation de données dans DynamoDB .................................................................... Copie de données vers et depuis Amazon DynamoDB .................................................... Personnalisation de performances ................................................................................ Intégration à Amazon Data Pipeline ..................................................................................... Prérequis à l'exportation et à l'importation des données ................................................... Exportation de données de DynamoDB vers Amazon S3 ................................................. Importation des données de Amazon S3 vers DynamoDB ................................................ Dépannage ............................................................................................................... Modèles prédéfinis pour AWS Data Pipeline et DynamoDB .............................................. Limites dans DynamoDB ............................................................................................................ Unités de capacité et débit alloué ........................................................................................ Tailles des unités de capacité ..................................................................................... Valeurs maximales et minimales de débit alloué ............................................................. Augmentation du débit alloué ...................................................................................... Diminution du débit alloué ........................................................................................... Tables ............................................................................................................................. Taille de la table ....................................................................................................... Tables par compte ..................................................................................................... Index secondaires ............................................................................................................. API Version 2012-08-10 vi 467 467 468 468 470 470 471 471 472 472 479 482 483 483 485 494 494 494 495 497 498 501 502 502 502 503 503 514 515 517 518 518 524 524 525 526 526 533 536 537 539 550 554 556 560 561 562 563 564 564 564 564 565 565 565 565 566 566 Amazon DynamoDB Manuel du développeur Index secondaires par table ........................................................................................ 566 Attributs d'index secondaire par table ........................................................................... 566 Clés de partition et clés de tri ............................................................................................. 566 Longueur de clé de partition ........................................................................................ 566 Valeurs de clé de partition .......................................................................................... 566 Longueur de la clé de tri ............................................................................................ 566 Valeurs de clé de tri .................................................................................................. 566 Règles de dénomination ..................................................................................................... 567 Noms de table et noms d'index secondaire .................................................................... 567 Noms d'attribut .......................................................................................................... 567 Type de données .............................................................................................................. 567 String ....................................................................................................................... 567 Numéro .................................................................................................................... 567 Binary ...................................................................................................................... 568 Articles ............................................................................................................................. 568 Taille de l'élément ..................................................................................................... 568 Taille d'élément pour les tables avec index secondaires locaux ......................................... 568 Attributs ........................................................................................................................... 568 Paires nom-valeur d'attribut par élément ....................................................................... 568 Nombre de valeurs dans un type List, Map ou Set .......................................................... 568 Valeurs d'attribut ....................................................................................................... 569 Profondeur des attributs imbriqués ............................................................................... 569 Paramètre d'expression ...................................................................................................... 569 Longueurs ................................................................................................................ 569 Opérateurs et opérandes ............................................................................................ 569 Mots réservés ........................................................................................................... 569 Flux DynamoDB ................................................................................................................ 569 Lecteurs simultanés d'une partition dans Flux DynamoDB ................................................ 569 Capacité d'écriture maximum pour une table avec un flux activé ....................................... 570 Limites propres à l'API ....................................................................................................... 570 Bonnes pratiques ...................................................................................................................... 571 Bonnes pratiques pour les tables ......................................................................................... 571 Bonnes pratiques pour les éléments ..................................................................................... 571 Bonnes pratiques d'interrogation et d'analyse ......................................................................... 572 Bonnes pratiques sur les index secondaires locaux ................................................................ 572 Bonnes pratiques sur les index secondaires globaux ............................................................... 572 Instructions pour l'utilisation des tables ................................................................................. 572 Conception d'un accès aux données uniforme entre les éléments de vos tables ................... 573 Comprendre le comportement des partitions .................................................................. 575 Utiliser la capacité de transmission en mode rafale avec modération .................................. 579 Distribuer l'activité d'écriture pendant le chargement des données ..................................... 579 Comprendre les modèles d'accès des données chronologiques ........................................ 580 Mettre en cache les éléments populaires ...................................................................... 581 Prendre en compte l'uniformité de la charge de travail lors de l'ajustement du débit alloué ...... 581 Test de votre application à l'échelle .............................................................................. 582 Instructions pour l'utilisation des éléments ............................................................................. 583 Utiliser des tables 1-à-n au lieu d'attributs de type Set volumineux ..................................... 583 Utiliser plusieurs tables pour prendre en charge différents modèles d'accès ......................... 584 Compresser les valeurs d'attribut volumineuses .............................................................. 585 Stocker les valeurs d'attribut volumineux dans Amazon S3 ............................................... 586 Décomposer les attributs volumineux entre plusieurs éléments ......................................... 586 Consignes pour interrogation et analyse ................................................................................ 588 Evitez les rafales soudaines de l'activité en lecture ......................................................... 588 Tirer parti des analyses parallèles ................................................................................ 590 Consignes pour les index secondaires locaux ........................................................................ 590 Utiliser les index avec modération ................................................................................ 591 Choisir soigneusement les projections .......................................................................... 591 Optimiser les requêtes fréquentes pour éviter les extractions ............................................ 591 API Version 2012-08-10 vii Amazon DynamoDB Manuel du développeur Tirer profit des index partiellement alloués ..................................................................... 592 Surveiller l'extension des collections d'éléments ............................................................. 592 Consignes pour les Index global secondaire .......................................................................... 593 Choisissez une clé qui fournira des charges de travail uniformes ....................................... 593 Tirer profit des index partiellement alloués ..................................................................... 593 Utilisez un Index global secondaire pour les recherches rapides ........................................ 594 Créer un réplica en lecture cohérente à terme ............................................................... 594 Annexe .................................................................................................................................... 596 Exemples de tables et de données ...................................................................................... 596 Exemples de fichiers de données ................................................................................ 597 Création d'exemples de table et de chargement de données .................................................... 606 Création d'exemples de table et de chargement de données - Java ................................... 607 Création d'exemples de table et de chargement de données - .NET ................................... 615 Création d'exemples de table et de chargement de données - PHP .................................... 624 Exemple d'application à l'aide d'AWS SDK pour Python (Boto) .................................................. 633 Etape 1 : Déploiement et test localement ...................................................................... 634 Etape 2 : Examen du modèle de données et des détails de la mise en œuvre ...................... 637 Etape 3 : Déploiement en production ............................................................................ 645 Etape 4 : Nettoyage des ressources ............................................................................. 651 Outils et ressources supplémentaires pour DynamoDB ............................................................ 652 Back-end de stockage Amazon DynamoDB pour Titan .................................................... 652 Plug-in Logstash pour Amazon DynamoDB ................................................................... 676 Mots réservés dans DynamoDB ........................................................................................... 676 Paramètres conditionnels hérités ......................................................................................... 686 AttributesToGet ......................................................................................................... 687 AttributeUpdates ........................................................................................................ 688 ConditionalOperator ................................................................................................... 690 Expected .................................................................................................................. 690 KeyConditions ........................................................................................................... 694 QueryFilter ................................................................................................................ 696 ScanFilter ................................................................................................................. 697 Ecriture de conditions avec les paramètres existants ....................................................... 698 Version actuelle de l'API de bas niveau (2012-08-10) .............................................................. 705 Version précédente de l'API de bas niveau (2011-12-05) ......................................................... 706 BatchGetItem ............................................................................................................ 706 BatchWriteItem .......................................................................................................... 712 CreateTable .............................................................................................................. 717 DeleteItem ................................................................................................................ 723 DeleteTable .............................................................................................................. 727 Décrire des tables ..................................................................................................... 731 GetItem .................................................................................................................... 734 ListTables ................................................................................................................. 736 PutItem .................................................................................................................... 738 Interrogation ............................................................................................................. 744 Analyser ................................................................................................................... 753 UpdateItem ............................................................................................................... 765 UpdateTable ............................................................................................................. 771 Historique du document .............................................................................................................. 775 API Version 2012-08-10 viii Amazon DynamoDB Manuel du développeur Qu'est-ce que Amazon DynamoDB ? Bienvenue dans le Amazon DynamoDB Guide du développeur. Amazon DynamoDB est un service de base de données NoSQL intégralement géré, qui offre des performances prévisibles et rapides, ainsi qu'une extensibilité transparente. Comme DynamoDB vous permet de ne pas avoir à assurer les charges administratives liées au fonctionnement et au dimensionnement d'une base de données distribuée, vous n'avez pas à vous soucier de la mise en service, du paramétrage, de la configuration et de la réplication du matériel, ainsi que des correctifs logiciels ou du dimensionnement des clusters. Avec DynamoDB, vous pouvez créer des tables de base de données capables de stocker et de récupérer n'importe quelle quantité de données, ainsi que de traiter n'importe quel niveau de trafic de demande. Vous pouvez augmenter ou diminuer la capacité de débit de vos tables sans temps d'arrêt ou dégradation des performances, et utiliser AWS Management Console pour surveiller les métriques de performance et l'utilisation des ressources. DynamoDB répartit automatiquement les données et le trafic de vos tables sur un nombre suffisant de serveurs pour gérer vos besoins en débit et en stockage, tout en assurant des performances régulières et rapides. Tous vos données sont stockées sur des disques SSD (Solid State Drive) et sont automatiquement répliquées sur plusieurs zones de disponibilité d'une région AWS pour fournir une haute disponibilité et une durabilité des données intégrées. Nous vous recommandons de commencer par lire les sections suivantes : • Amazon DynamoDB : fonctionnement (p. 2)—Pour découvrir les concepts essentiels relatifs à DynamoDB. • Configuration d'DynamoDB (p. 45)—Pour apprendre à configurer DynamoDB (version téléchargeable ou service web). • Accès à DynamoDB (p. 51)—Pour apprendre à accéder à DynamoDB à l'aide de la console, de l'interface de ligne de commande ou de l'API. Pour en savoir plus sur le développement des applications, consultez : • Programmation avec DynamoDB et les kits SDK AWS (p. 63) • Utilisation d'DynamoDB (p. 179) API Version 2012-08-10 1 Amazon DynamoDB Manuel du développeur Comment ça fonctionne Note Vous pouvez également consulter le manuel Guide de démarrage de Amazon DynamoDB pour obtenir des didacticiels spécifiques au langage avec des exemples de code. Les kits SDK AWS sont disponibles pour une grande variété de langues. Pour obtenir la liste complète, consultez Outils d'Amazon Web Services. Pour trouver rapidement les recommandations sur l'optimisation des performances et la réduction des coûts de débit, consultez Bonnes pratiques pour DynamoDB (p. 571). Pour apprendre à baliser les ressources DynamoDB, consultez Balisage pour DynamoDB (p. 185). En dernier lieu, si vous souhaitez identifier et migrer les bases de données Relational Database Management Systems (RDBMS) dans DynamoDB, consultez Bonnes pratiques de migration de RDBMS vers Amazon DynamoDB. Amazon DynamoDB : fonctionnement Les sections suivantes fournissent une vue d'ensemble des composants du service Amazon DynamoDB et de leur interaction. Une fois que vous avez lu cette introduction, essayez de parcourir la section Création de tables et chargement d'exemples de données (p. 167), qui vous guide à travers le processus de création d'exemples de tables, de chargement de données et d'exécution de certaines opérations élémentaires de base de données. Vous pouvez également consulter le manuel Guide de démarrage de Amazon DynamoDB pour obtenir des didacticiels spécifiques au langage avec des exemples de code. Rubriques • Composants de base DynamoDB (p. 2) • L'API DynamoDB (p. 9) • Règles de dénomination et types de données (p. 11) • Cohérence en lecture (p. 16) • Débit réservé (p. 17) • Partitions et distribution des données (p. 20) Composants de base DynamoDB Dans DynamoDB, les tables, les éléments et les attributs sont les principaux composants que vous utilisez. Une table est un ensemble d'éléments et chaque élément est un ensemble d'attributs. DynamoDB utilise les clés primaires pour identifier de façon unique chaque élément d'une table et les index secondaires pour fournir une plus grande flexibilité d'interrogation. Vous pouvez utiliser Flux DynamoDB pour capturer les événements de modification des données des tables DynamoDB. Il existe des limites dans DynamoDB. Pour plus d'informations, consultez Limites dans DynamoDB (p. 564). Rubriques • • • • Tables, éléments et attributs (p. 3) Clé primaire (p. 5) Index secondaires (p. 6) Flux DynamoDB (p. 8) API Version 2012-08-10 2 Amazon DynamoDB Manuel du développeur Composants de base Tables, éléments et attributs Les composants DynamoDB de base sont les suivants : • Tables : de même que les autres systèmes de base de données, DynamoDB stocke les données dans des tables. Une table est un ensemble de données. Par exemple, consultez l'exemple de table appelée People (illustrée ci-après) que vous pouvez utiliser pour stocker les informations sur les contacts. • Eléments : chaque table contient plusieurs éléments. Un élément est un groupe d'attributs identifiable de façon unique parmi tous les autres éléments. Les éléments dans DynamoDB sont similaires en de nombreux points aux lignes, enregistrements ou tuples des autres systèmes de base de données. Dans l'exemple de table People, chaque élément représente une personne. • Attributs : chaque élément se compose d'un ou de plusieurs attributs. Un attribut est un élément de donnée fondamental, qui n'a pas besoin d'être décomposé plus avant. Les attributs de DynamoDB sont similaires en de nombreux points aux champs ou colonnes des autres systèmes de base de données. Par exemple, un élément de l'exemple de table People contient les attributs appelés PersonID, LastName, FirstName, et ainsi de suite. Le schéma suivant montre une table nommée People avec certains exemples d'éléments et d'attributs. Notez ce qui suit à propos de la table People : • Chaque élément de la table possède un identifiant unique, ou clé primaire, qui distingue l'élément de tous les autres éléments de la table. Dans la table People, la clé primaire se compose d'un seul attribut (PersonID). API Version 2012-08-10 3 Amazon DynamoDB Manuel du développeur Composants de base • En dehors de la clé primaire, la table People est sans schéma, ce qui signifie que ni les attributs ni leurs types de données ne doivent être définis au préalable. Chaque élément peut avoir ses propres attributs distincts. • La plupart des attributs sont scalaires, ce qui signifie qu'ils ne peuvent avoir qu'une seule valeur. Les chaînes et les nombres sont des exemples courants de scalaires. • Certains éléments ont un attribut imbriqué (Address). DynamoDB prend en charge les attributs imbriqués jusqu'à 32 niveaux de profondeur. Ce qui suit est un autre exemple de table nommée Music que vous pouvez utiliser pour effectuer le suivi de votre collection musicale. Notez ce qui suit à propos de la table Music : API Version 2012-08-10 4 Amazon DynamoDB Manuel du développeur Composants de base • La clé primaire de Music se compose de deux attributs (Artist et SongTitle). Chaque élément de la table doit avoir ces deux attributs. La combinaison de Artist et de SongTitle distingue chaque élément de la table de tous les autres. • En dehors de la clé primaire, la table Music est sans schéma, ce qui signifie que ni les attributs ni leurs types de données ne doivent être définis au préalable. Chaque élément peut avoir ses propres attributs distincts. • L'un des éléments a un attribut imbriqué (PromotionInfo), qui contient les autres attributs imbriqués. DynamoDB prend en charge les attributs imbriqués jusqu'à 32 niveaux de profondeur. Pour plus d'informations, consultez Utilisation de tables dans DynamoDB (p. 179). Clé primaire Lorsque vous créez une table, en plus du nom de la table, vous devez spécifier la clé primaire de la table. La clé primaire identifie de manière unique chaque élément de la table, afin qu'aucun deux éléments n'ait la même clé. DynamoDB prend en charge deux différents types de clés primaires : • Clé de partition : clé primaire simple, composée d'un attribut appelé clé de partition. DynamoDB utilise la valeur de la clé de partition comme entrée d'une fonction de hachage interne. La sortie de la fonction de hachage détermine la partition (stockage physique interne de DynamoDB) dans laquelle l'élément est stocké. Dans une table comportant une seule clé de partition, deux éléments d'une table ne peuvent pas avoir la même valeur de clé de partition. La Peopletable décrite dans Tables, éléments et attributs (p. 3) est un exemple de table avec une clé primaire simple (PersonID). Vous pouvez accéder immédiatement à n'importe quel élément de la table People en fournissant la valeur PersonId de cet élément. • Clé de partition et clé de tri : défini comme clé primaire composite, ce type de clé se compose de deux attributs. Le premier attribut est la clé de partition et le second attribut est la clé de tri. DynamoDB utilise la valeur de la clé de partition comme entrée d'une fonction de hachage interne. La sortie de la fonction de hachage détermine la partition (stockage physique interne de DynamoDB) dans laquelle l'élément est stocké. Tous les éléments avec la même clé de partition sont stockés ensemble, dans l'ordre par valeur de clé de tri. Dans une table comportant une clé de partition et une clé de tri, il est possible pour deux éléments d'avoir la même valeur de clé de partition, mais ces deux éléments doivent avoir des valeurs de clés de tri différentes. La Musictable décrite dans Tables, éléments et attributs (p. 3)est un exemple de table avec une clé primaire composite (Artist et SongTitle). Vous pouvez accéder immédiatement à n'importe quel élément de la table Music, si vous fournissez les valeurs Artist et SongTitle de cet élément. Une clé primaire composite vous offre plus de flexibilité lors de l'interrogation des données. Par exemple, si vous fournissez uniquement la valeur pour Artist, DynamoDB permet de récupérer tous les morceaux de cet artiste. Vous pouvez même fournir une valeur pour Artist et une plage de valeurs SongTitle, pour récupérer uniquement un sous-ensemble de titres d'un artiste en particulier. API Version 2012-08-10 5 Amazon DynamoDB Manuel du développeur Composants de base Note La clé de partition d'un élément est également appelée attribut de hachage. Le terme attribut de hachage dérive de l'utilisation par DynamoDB d'une fonction de hachage interne pour répartir uniformément les éléments de données entre les partitions, en fonction de leurs valeurs de clé de partition. La clé de tri d'un élément est également appelée attribut de plage. Le terme attribut de plage dérive de la façon dont DynamoDB stocke les éléments avec la même clé de partition physiquement proches les uns des autres, dans l'ordre de la valeur de la clé de tri. Chaque attribut de clé primaire doit être un scalaire (ce qui signifie qu'il ne peut contenir qu'une seule valeur). Les seuls types de données autorisés pour les attributs de clé primaires sont string, number ou binary. Il n'y a aucune restriction semblable pour les autres attributs non-clés. Index secondaires Vous pouvez créer un ou plusieurs index secondaires sur une table. Un index secondaire vous permet d'interroger les données de la table à l'aide d'une clé secondaire, en plus des requêtes sur la clé primaire. DynamoDB ne requiert pas que vous utilisiez des index, mais ceux-ci offrent à vos applications plus de flexibilité lorsqu'il s'agit d'interroger vos données. DynamoDB prend en charge deux types d'index : • Index secondaire global : un index avec une clé de partition et une clé de tri qui peuvent être différentes de celles de la table. • Index secondaire local : un index possédant la même clé de partition que la table, mais une clé de tri différente. Vous pouvez définir jusqu'à 5 index secondaires globaux et 5 index secondaires locaux par table. Dans l'exemple de table Music précédent, vous pouvez interroger les éléments de données par Artist (clé de partition) ou par Artist et SongTitle (clé de partition et clé de tri). Que faire si vous souhaitez également interroger les données par Genre et par AlbumTitle ? Pour ce faire, vous pouvez créer un index sur ces attributs, puis interroger l'index à peu près de la même manière que vous interrogeriez la table Music. Le schéma suivant montre l'exemple de table Music, avec un nouvel index appelé GenreAlbumTitle. API Version 2012-08-10 6 Amazon DynamoDB Manuel du développeur Composants de base Notez les éléments suivants sur l'index GenreAlbumTitle : • Chaque index appartient à une table, qui est appelée la table de base de l'index. Dans l'exemple précédent, Music est la table de base de l'index GenreAlbumTitle. • DynamoDB gère les index automatiquement. Lorsque vous ajoutez, mettez à jour ou supprimez un élément de la table de base, DynamoDB ajoute, met à jour ou supprime l'élément correspondant dans les index qui appartiennent à cette table. • Lorsque vous créez un index, vous spécifiez quels attributs seront copiés, ou projetés, depuis la table de base vers l'index. Au minimum, DynamoDB projette les attributs clés de la table de base vers l'index. Tel est le cas avec GenreAlbumTitle, où seuls les attributs clés de la table Music sont projetés dans l'index. API Version 2012-08-10 7 Amazon DynamoDB Manuel du développeur Composants de base Vous pouvez interroger l'index GenreAlbumTitle pour rechercher tous les albums d'un genre particulier (par exemple, tous les albums Rock). Vous pouvez également interroger l'index pour rechercher tous les albums au sein d'un genre particulier, mais seulement ceux avec certains titres d'album (par exemple, tous les albums Country dont les titres commencent par la lettre H). Pour de plus amples informations, veuillez consulter Amélioration de l'accès aux données avec les index secondaires (p. 337). Flux DynamoDB Flux DynamoDB est une fonction facultative qui capture les événements de modification de données dans les tables DynamoDB. Les données sur ces événements apparaissent dans le flux de données presque en temps réel et dans l'ordre où les événements se sont produits. Chaque événement est représenté par un enregistrement de flux. Si vous activez un flux de données sur une table, Flux DynamoDB écrit un enregistrement de flux chaque fois que l'un des événements suivants se produit : • Si un nouvel élément est ajouté à la table, le flux capture une image de la totalité de l'élément, y compris l'ensemble de ses attributs. • Si un élément est mis à jour, le flux capture l'image « avant » et « après » des attributs qui ont été modifiés dans l'élément. • Si un élément est supprimé de la table, le flux saisit une image de la totalité de l'élément avant qu'il n'ait été supprimé. Chaque enregistrement de flux contient aussi le nom de la table, l'horodatage de l'événement et autres métadonnées. Les enregistrements de flux ont une durée de vie de 24 heures ; passé ce délai, ils sont automatiquement supprimés du flux. Vous pouvez utiliser Flux DynamoDB avec AWS Lambda pour créer un déclencheur (code qui s'exécute automatiquement chaque fois qu'un événement d'intérêt apparaît dans un flux). Par exemple, imaginons une table Customers qui contient les informations client d'une entreprise. Supposons que vous souhaitiez envoyer un e-mail à chaque nouveau client pour les accueillir. Vous pouvez activer un flux de données sur cette table, puis associer le flux à une fonction Lambda. La fonction Lambda s'exécute chaque fois qu'un nouvel enregistrement de flux s'affiche, mais traite uniquement les nouveaux éléments ajoutés à la table Customers. Pour tout élément ayant un attribut EmailAddress, la fonction Lambda appelle Amazon Simple Email Service (Amazon SES) pour envoyer un e-mail à cette adresse. Le schéma suivant illustre ce scénario. API Version 2012-08-10 8 Amazon DynamoDB Manuel du développeur L'API DynamoDB Note Dans cet exemple, notez que le dernier client, Craig Roe, ne reçoit pas d'e-mail, car il n'a pas d'EmailAddress. En plus des déclencheurs, Flux DynamoDB permet des solutions puissantes telles que la réplication de données au sein des régions AWS ou entre elles, les vues matérialisées des données des tables DynamoDB, l'analyse des données à l'aide des vues matérialisées Amazon Kinesis et plus encore. Pour plus d'informations, consultez Capture d'activité Table avec Flux DynamoDB (p. 430). L'API DynamoDB Pour utiliser DynamoDB, votre application doit utiliser quelques opérations d'API simples. Voici un résumé de ces opérations, classées par catégorie. Rubriques • Plan de contrôle (p. 10) • Plan de données (p. 10) • Flux DynamoDB (p. 11) API Version 2012-08-10 9 Amazon DynamoDB Manuel du développeur L'API DynamoDB Plan de contrôle Les opérations de plan de contrôle vous permettent de créer et de gérer des tables DynamoDB. Elles vous permettent également d'utiliser les index, les flux et autres objets qui dépendent des tables. • CreateTable : crée une table. Le cas échéant, vous pouvez créer un ou plusieurs index secondaires, puis activer Flux DynamoDB pour la table. • DescribeTable : retourne des informations sur une table, telles que son schéma de clé primaire, ses paramètres de débit, ses informations d'index, et ainsi de suite. • ListTables : retourne les noms de toutes vos tables dans une liste. • UpdateTable : modifie les paramètres d'une table ou de ses index, crée ou supprime de nouveaux index sur une table, ou modifie les paramètres Flux DynamoDB pour une table. • DeleteTable : supprime une table et tous ses objets dépendants de DynamoDB. Plan de données Les opérations de plan de données vous permettent d'exécuter les opérations de création, lecture, mise à jour et suppression (également appelées opérations CRUD) sur les données d'une table. Certaines opérations de plan de données vous permettent également de lire les données à partir d'un index secondaire. Création de données • PutItem : écrit un seul élément sur une table. Vous devez spécifier les attributs de clé primaire, mais vous n'avez pas à spécifier d'autres attributs. • BatchWriteItem : écrit jusqu'à 25 éléments sur une table. Cette solution est plus efficace que l'appel répété de PutItem parce que votre application a uniquement besoin d'un seul aller-retour réseau pour écrire les éléments. Notez que vous pouvez également utiliser BatchWriteItempour supprimer plusieurs éléments d'une ou de plusieurs tables. Lecture de données • GetItem : extrait un seul élément d'une table. Vous devez spécifier la clé primaire de l'élément que vous voulez. Vous pouvez récupérer l'élément entier ou juste un sous-ensemble de ses attributs. • BatchGetItem : récupère jusqu'à 100 éléments à partir d'une ou de plusieurs tables. Cette solution est plus efficace que l'appel répété de GetItem parce que votre application a uniquement besoin d'un seul aller-retour réseau pour lire les éléments. • Query : récupère tous les éléments ayant une clé de partition spécifique. Vous devez spécifier la valeur de la clé de partition. Vous pouvez récupérer des éléments entiers, ou juste un sousensemble de leurs attributs. Le cas échéant, vous pouvez appliquer une condition aux valeurs de clé de tri, afin de récupérer uniquement un sous-ensemble des données ayant la même clé de partition. Vous pouvez utiliser cette opération sur une table, à condition que la table ait une clé de partition et une clé de tri. Vous pouvez également utiliser cette opération sur un index, à condition que l'index ait une clé de partition et une clé de tri. • Scan : récupère tous les éléments de la table ou de l'index spécifié. Vous pouvez récupérer des éléments entiers, ou juste un sous-ensemble de leurs attributs. Le cas échéant, vous pouvez appliquer une condition de filtre pour renvoyer uniquement les valeurs qui vous intéressent et ignorer les autres. Mise à jour de données • UpdateItem : modifie un ou plusieurs attributs d'un élément. Vous devez spécifier la clé primaire de l'élément que vous voulez modifier. Vous pouvez ajouter de nouveaux attributs, ainsi que modifier ou API Version 2012-08-10 10 Amazon DynamoDB Manuel du développeur Règles de dénomination et types de données supprimer des attributs existants. Vous pouvez également effectuer des mises à jour conditionnelles, afin que la mise à jour ne réussisse que lorsqu'une condition définie par l'utilisateur est remplie. Le cas échéant, vous pouvez mettre en place un compteur atomique, qui augmente ou diminue un attribut numérique sans interférer avec d'autres demandes d'écriture. Suppression des données • DeleteItem : supprime un seul élément d'une table. Vous devez spécifier la clé primaire de l'élément que vous voulez supprimer. • BatchWriteItem : supprime jusqu'à 25 éléments d'une ou de plusieurs tables. Cette solution est plus efficace que l'appel répété de DeleteItem parce que votre application a uniquement besoin d'un seul aller-retour réseau pour supprimer les éléments. Notez que vous pouvez également utiliser BatchWriteItem pour ajouter plusieurs éléments à une ou plusieurs tables. Flux DynamoDB Les opérations Flux DynamoDB vous permettent d'activer ou de désactiver un flux sur une table, et d'autoriser l'accès aux enregistrements de modification des données contenus dans un flux. • ListStreams : retourne une liste de tous vos flux, ou simplement le flux d'une table spécifique. • DescribeStream : retourne des informations sur un flux, telles que son ARN et l'emplacement où votre application peut commencer à lire les tout premiers enregistrements de flux. • GetShardIterator : retourne un itérateur de partition, lequel est une structure de données que votre application utilise pour extraire les enregistrements du flux. • GetRecords : récupère un ou plusieurs enregistrements de flux, à l'aide d'un itérateur de partition donné. Règles de dénomination et types de données Cette section décrit les règles de dénomination DynamoDB et les différents types de données que DynamoDB prend en charge. Des limites s'appliquent aux types de données. Pour de plus amples informations, veuillez consulter Type de données (p. 567). Rubriques • Règles de dénomination (p. 11) • Type de données (p. 12) Règles de dénomination Les tables, les attributs et autres objets de DynamoDB doivent avoir des noms. Les noms doivent être significatifs et concis : par exemple, les noms comme Products, Books et Authors sont explicites. Voici les règles de dénomination de DynamoDB : • Tous les noms doivent être codés à l'aide d'UTF-8 et sont sensibles à la casse. • Les noms de table et les noms d'index doivent être compris entre 3 et 255 caractères, et peuvent contenir uniquement les caractères suivants : • a-z • A-Z • 0-9 • _ (soulignement) API Version 2012-08-10 11 Amazon DynamoDB Manuel du développeur Règles de dénomination et types de données • - (tiret) • . (point) • Les noms d'attribut peuvent comporter entre 1 et 255 caractères. Mots réservés et caractères spéciaux A l'instar de nombreux autres systèmes de gestion de base de données, DynamoDB possède une liste de mots réservés et de caractères spéciaux. • Pour obtenir la liste complète des mots réservés dans DynamoDB, consultez Mots réservés dans DynamoDB (p. 676). • Les caractères suivants ont une signification spéciale dans DynamoDB : # (hachage) et : (deux points) Même si DynamoDB vous permet d'utiliser ces mots réservés et ces caractères spéciaux à des fins de dénomination, nous vous recommandons d'éviter de procéder ainsi, car vous devez définir les variables d'espace réservé chaque fois que vous utilisez ces noms dans une expression. Pour de plus amples informations, veuillez consulter Utilisation d'espaces réservés pour valeurs et noms d'attributs (p. 215). Type de données DynamoDB prend en charge différents types de données pour les attributs d'une table. Ils peuvent être classés comme suit : • Types scalar : un type scalar peut représenter exactement une valeur. Les types scalar sont les suivants : number, string, binary, Boolean et null. • Types document : un type document peut représenter une structure complexe avec des attributs imbriqués, comme vous en trouvez dans un document JSON. Les types document sont les suivants : list et map. • Types set : un type set peut représenter plusieurs valeurs scalaires. Les types set sont les suivants : string set, number set et binary set. Lorsque vous créez une table ou un index secondaire, vous devez spécifier les noms et les types de données de chaque attribut de clé primaire (clé de partition et clé de tri). En outre, chaque attribut de clé primaire doit être défini en tant que type string, number ou binary (chaîne, nombre ou binaire). DynamoDB est une base de données NoSQL et est sans schéma, ce qui signifie que, en dehors des attributs de clé primaire, vous n'avez pas besoin de définir d'attributs ou de types de données au moment de la création de la table. En comparaison, les bases de données relationnelles nécessitent que vous définissiez les noms et les types de données de chaque colonne lorsque vous créez une table. Les descriptions suivantes concernent chaque type de données, ainsi que des exemples au format JSON. Types scalar Les types scalar sont les suivants : number, string, binary, Boolean et null. String Les chaînes sont Unicode avec codage binaire UTF-8. La longueur d'une chaîne doit être supérieure à zéro et est contrainte par la taille limite maximale 400 KB d'un élément DynamoDB. API Version 2012-08-10 12 Amazon DynamoDB Manuel du développeur Règles de dénomination et types de données Si vous définissez un attribut de clé primaire comme attribut de type string (chaîne), les contraintes supplémentaires suivantes s'appliquent : • Pour une clé primaire simple, la longueur maximale de la première valeur d'attribut (la clé de partition) est 2048 bytes. • Pour une clé primaire composite, la longueur maximale de la deuxième valeur d'attribut (la clé de tri) est 1024 bytes. DynamoDB rassemble et compare les chaînes à l'aide des octets de l'encodage de chaîne UTF-8 sous-jacent. Par exemple, « a » (0x61) est supérieur à « A » (0x41) et « ¿ » (0xC2BF) est supérieur à « z » (0x7A). Example "Bicycle" Vous pouvez utiliser le type de données String pour représenter une date ou un horodatage. Une solution pour cela consiste à utiliser les chaînes ISO 8601, comme illustré dans ces exemples : • 2016-02-15 • 2015-12-21T17:42:34Z • 20150311T122706Z Pour plus d'informations, consultez http://en.wikipedia.org/wiki/ISO_8601. Numéro Les nombres peuvent être positifs, négatifs ou nuls. Les nombres peuvent avoir une précision de 38 chiffres au plus (tout dépassement entraînerait une exception). • Plage positive : 1E-130 à 9,9999999999999999999999999999999999999E+125 • Plage négative : -9,9999999999999999999999999999999999999E+125 à -1E-130 Dans DynamoDB, les nombres sont représentés sous forme de longueur variable. Les zéros de début et de fin sont tronqués. Tous les nombres sont envoyés à DynamoDB via le réseau sous forme de chaînes, afin d'optimiser la compatibilité entre les langages et les bibliothèques. Toutefois, DynamoDB les traite comme attributs de type numérique pour les opérations mathématiques. Note Si la précision numérique est importante, passez les nombres à DynamoDB à l'aide de chaînes que vous convertissez à partir du type number. Example 300 API Version 2012-08-10 13 Amazon DynamoDB Manuel du développeur Règles de dénomination et types de données Vous pouvez utiliser le type de données Number pour représenter une date ou un horodatage. Une façon de procéder consiste à utiliser l'heure Posix, à savoir le nombre de secondes depuis le 1er janvier 1970, 00:00:00 UTC. Par exemple, l'heure Posix 1437136300 correspond au 17 juillet 2015, 12:31:40 UTC. Pour plus d'informations, consultez la page http://fr.wikipedia.org/wiki/Heure_Unix. Binary Les attributs de type binary peuvent stocker n'importe quelle donnée binaire, telle que texte compressé, données chiffrées ou images. Chaque fois que DynamoDB compare les valeurs binaires, il traite chaque octet de données binaires comme non signé. La longueur d'un attribut de type binary doit être supérieure à zéro ; il est contraint par la taille limite maximale 400 KB d'un élément DynamoDB. Si vous définissez un attribut de clé primaire comme attribut de type binary (binaire), les contraintes supplémentaires suivantes s'appliquent : • Pour une clé primaire simple, la longueur maximale de la première valeur d'attribut (la clé de partition) est 2048 bytes. • Pour une clé primaire composite, la longueur maximale de la deuxième valeur d'attribut (la clé de tri) est 1024 bytes. Vos applications doivent encoder les valeurs binaires au format codé en base64 avant de les envoyer à DynamoDB A la réception de ces valeurs, DynamoDB décode les données d'un tableau d'octets non signés et utilise ces informations comme longueur de l'attribut de type binary. Example L'exemple suivant est un attribut binaire, utilisant un texte codé en base64. dGhpcyB0ZXh0IGlzIGJhc2U2NC1lbmNvZGVk Booléen Un attribut de type Boolean peut stocker true ou false. Example true Null Null représente un attribut avec un état inconnu ou non défini. Example NULL API Version 2012-08-10 14 Amazon DynamoDB Manuel du développeur Règles de dénomination et types de données Types document Les types document sont les suivants : list et map. Ces types de données peuvent être imbriqués les uns dans les autres, pour représenter les structures de données complexes jusqu'à 32 niveaux de profondeur. Il n'y a aucune limite sur le nombre de valeurs d'un type list ou map, aussi longtemps que l'élément qui contient les valeurs s'inscrit dans la limite de taille des éléments DynamoDB (400 KB). Une valeur d'attribut ne peut pas être un élément de type String ou Set vide (String Set, Number Set ou Binary Set). Cependant, les éléments de type List et Map vides sont autorisés. Pour plus d'informations, consultez Attributs (p. 568). List Un attribut de type list peut stocker une collection ordonnée de valeurs. Les types list sont entourés de crochets :[ ... ] Une liste est similaire à un tableau JSON. Il n'y a aucune restriction sur les types de données qui peuvent être stockés dans un élément de type list et les éléments d'un élément de type list n'ont pas à être du même type. L'exemple suivant montre une liste contenant deux chaînes et un nombre. Example FavoriteThings: ["Cookies", "Coffee", 3.14159] Note DynamoDB vous permet d'utiliser des éléments individuels dans une liste, même si ces éléments sont profondément imbriqués. Pour de plus amples informations, veuillez consulter Chemins d'accès du document (p. 213). Map Un attribut de type map peut stocker une collection non ordonnée de paires nom-valeur. Les types map sont placés entre accolades : { ... } Un type map est similaire à un objet JSON. Il n'y a aucune restriction sur les types de données qui peuvent être stockés dans un élément de type map et les éléments d'un élément de type map n'ont pas à être du même type. Les éléments de type map sont particulièrement adaptés pour stocker les documents JSON dans DynamoDB. L'exemple suivant montre un élément de type map qui contient une chaîne, un nombre et une liste imbriquée contenant un autre élément de type map. API Version 2012-08-10 15 Amazon DynamoDB Manuel du développeur Cohérence en lecture Example { Day: "Monday", UnreadEmails: 42, ItemsOnMyDesk: [ "Coffee Cup", "Telephone", { Pens: { Quantity : 3}, Pencils: { Quantity : 2}, Erasers: { Quantity : 1} } ] } Note DynamoDB vous permet d'utiliser des éléments individuels dans un type map, même si ces éléments sont profondément imbriqués. Pour de plus amples informations, veuillez consulter Chemins d'accès du document (p. 213). Sets DynamoDB prend en charge les types qui représentent des ensembles de valeurs String, Number ou Binary. Tous les éléments au sein d'un ensemble doivent être du même type. Par exemple, un attribut de type Number Set peut contenir uniquement des nombres ; String Set peut contenir uniquement des chaînes ; et ainsi de suite. Il n'y a aucune limite sur le nombre de valeurs d'un type Set, aussi longtemps que l'élément qui contient les valeurs s'inscrit dans la limite de taille des éléments DynamoDB (400 KB). Chaque valeur au sein d'un ensemble doit être unique. L'ordre des valeurs d'un ensemble n'est pas conservé ; par conséquent, vos applications ne doivent pas reposer sur un ordre particulier des éléments au sein de l'ensemble. Enfin, DynamoDB ne prend pas en charge les ensembles vides. Example (String Set, Number Set et Binary Set) ["Black", "Green" ,"Red"] [42.2, -19, 7.5, 3.14] ["U3Vubnk=", "UmFpbnk=", "U25vd3k="] Cohérence en lecture Amazon DynamoDB est disponible dans plusieurs régions AWS du monde. Chaque région est totalement indépendante et isolée des autres régions AWS. Par exemple, si vous avez une table appelée People dans la région us-east-1 et une autre table appelée People dans la région uswest-2, elles sont considérées comme deux tables entièrement distinctes. Pour obtenir la liste de toutes les régions AWS dans lesquelles DynamoDB est disponible, consultez Régions AWS et points de terminaison dans le Référence générale d'Amazon Web Services. Chaque région AWS se compose de plusieurs emplacements distincts, appelés zones de disponibilité. Chaque zone de disponibilité est isolée des pannes dans d'autres zones de disponibilité et fournit une API Version 2012-08-10 16 Amazon DynamoDB Manuel du développeur Débit réservé connectivité réseau peu coûteuse et à faible latence vers d'autres zones de disponibilité de la même région. Cela permet une réplication des données entre plusieurs zones de disponibilité d'une région. Lorsque votre application écrit les données sur une table DynamoDB et reçoit une réponse HTTP 200 (OK), toutes les copies des données sont mises à jour. Les données seront cohérentes à terme sur tous les emplacements de stockage, généralement en une seconde ou moins. DynamoDB prendre en charge les lectures cohérentes à terme et à cohérence forte. Lectures cohérentes à terme Lorsque vous lisez des données à partir d'une table DynamoDB, la réponse peut ne pas refléter les résultats d'une opération d'écriture récemment terminée. La réponse peut comporter des données obsolètes. Si vous répétez votre demande de lecture après un bref instant, la réponse doit retourner les données les plus récentes. Lectures à cohérence forte Lorsque vous demandez une lecture à cohérence forte, DynamoDB retourne une réponse comportant les données les plus récentes, reflétant ainsi les mises à jour de toutes les opérations d'écriture précédentes ayant réussi. Une lecture à cohérence forte peut ne pas être disponible en cas de retard ou de panne réseau. Note DynamoDB utilise les lectures cohérentes à terme, sauf mention contraire. Les opérations en lecture (telles que GetItem, Query et Scan) fournissent un paramètre ConsistentRead : si vous définissez ce paramètre sur true, DynamoDB utilise les lectures à cohérence forte pendant l'opération. Débit réservé Rubriques • Unités de capacité en lecture (p. 18) • Unités de capacité en écriture (p. 19) • Achat de la capacité réservée (p. 20) Lorsque vous créez une table, vous spécifiez la capacité de débit alloué que vous voulez réserver pour les lectures et les écritures. DynamoDB réserve les ressources nécessaires pour répondre à vos besoins de débit tout en assurant des performances régulières et à faible latence. Vous pouvez également modifier vos paramètres de débit alloué, en augmentant ou en diminuant la capacité selon vos besoins. Dans DynamoDB, vous spécifiez les exigences de débit alloué en termes d'unités de capacité. Utilisez les consignes suivantes pour déterminer votre débit alloué : • Une unité de capacité en lecture représente une lecture à cohérence forte par seconde, ou deux lectures cohérentes à terme par seconde, pour les éléments dont la taille peut atteindre jusqu'à 4 KB. Si vous avez besoin de lire un élément plus grand que 4 KB, DynamoDB devra utiliser les unités supplémentaires de capacité en lecture. Le nombre total d'unités requises de capacité en lecture dépend de la taille de l'élément et du fait que vous vouliez ou pas une lecture cohérente à terme ou une lecture à cohérence forte. • Une unité de capacité en écriture représente une écriture par seconde pour les éléments dont la taille peut atteindre jusqu'à 1 KB. Si vous avez besoin d'écrire un élément plus grand que 1 KB, DynamoDB doit utiliser les unités supplémentaires de capacité en écriture. Le nombre total d'unités requises de capacité en écriture dépend de la taille de l'élément. API Version 2012-08-10 17 Amazon DynamoDB Manuel du développeur Débit réservé Pour les tables avec index secondaires, DynamoDB consomme des unités de capacité supplémentaires. Par exemple, si vous voulez ajouter un seul élément de 1 KB à une table et que cet élément contient un attribut indexé, vous avez besoin de deux unités de capacité en écriture : l'une pour écrire dans la table et l'autre pour écrire dans l'index. Pour de plus amples informations, veuillez consulter: • Considérations sur le débit provisionné pour les index secondaires locaux (p. 393) • Considérations sur le débit provisionné pour les index secondaires globaux (p. 346) Si les demandes de lecture ou d'écriture de votre application dépassent le débit alloué pour une table, DynamoDB peut limiter cette demande. Dans ce cas, la demande échoue avec un code HTTP 400 (Bad Request), accompagné d'une exception ProvisionedThroughputExceededException. Les kits de développement logiciel SDK AWS ont une prise en charge intégrée des nouvelles tentatives de demandes limitées. Cependant, vous pouvez envisager d'utiliser la logique d'interruption exponentielle dans votre code de gestion des erreurs. Pour de plus amples informations, veuillez consulter Nouvelles tentatives après erreur et interruptions exponentielles (p. 77). Vous pouvez utiliser AWS Management Console pour surveiller votre débit alloué et votre débit réel, afin de déterminer s'il existe des demandes limitées et de modifier vos paramètres de capacité allouée en prévision des modifications du trafic. Unités de capacité en lecture Si la taille de vos éléments est inférieure à 4 KB, chaque unité de capacité en lecture génère une lecture à cohérence forte par seconde ou deux lectures cohérentes à terme par seconde. Par exemple, supposons que vous vouliez lire 80 éléments d'une table par seconde. Supposons que les éléments aient une taille de 3 Ko et que vous vouliez des lectures à cohérence forte. Dans ce scénario, chaque lecture nécessite une unité provisionnée de capacité en lecture. Pour le déterminer, vous divisez la taille d'élément de l'opération par 4 KB, puis arrondissez au nombre entier le plus proche, comme dans l'exemple suivant : 3 KB / 4 KB = 0.75 --> 1 Dans ce scénario, vous devez définir le débit alloué en lecture de la table sur 80 unités de capacité en lecture : 1 read capacity unit per item × 80 reads per second = 80 read capacity units Si vous vouliez des lectures cohérentes à terme au lieu de lectures à cohérence forte, vous devez uniquement provisionner 40 unités de capacité en lecture. Si vos objets sont plus grands que 4 KB, vous devez arrondir la taille d'élément à la limite 4 KB suivante. Par exemple, supposons que vous souhaitiez exécuter 100 lectures à cohérence forte par seconde, et que les éléments aient une taille de 6 Ko. D'abord, vous devez déterminer le nombre d'unités requises de capacité en lecture par élément et l'arrondir au nombre entier le plus proche, comme illustré ci-après : 6 KB / 4 KB = 1.5 --> 2 Le résultat est deux unités de capacité en lecture par élément. Maintenant, vous multipliez le résultat par le nombre de lectures à cohérence forte par seconde : 2 read capacity units per item × 100 reads per second = 200 API Version 2012-08-10 18 Amazon DynamoDB Manuel du développeur Débit réservé Par conséquent, vous devez définir les unités provisionnées de capacité en lecture de la table sur 200. (Si vous vouliez des lectures cohérentes à terme au lieu de lectures à cohérence forte, vous devez uniquement provisionner 100 unités de capacité en lecture.) Pour lire un seul élément, vous utilisez l'opération GetItem. Si vous voulez lire plusieurs éléments, vous pouvez utiliser BatchGetItem pour extraire jusqu'à 100 éléments d'une table. Vous pouvez utiliser les opérations Query et Scan pour récupérer plusieurs éléments consécutifs d'une table ou d'un index en une seule demande. Avec ces opérations, DynamoDB utilise la taille cumulée des éléments traités pour calculer le débit alloué. Par exemple, si une opération Query récupère 100 éléments qui font chacun 1 Ko, le calcul de la capacité en lecture n'est pas (100 × 4 KB) = 100 unités de capacité en lecture, comme si ces éléments avaient été récupérés individuellement à l'aide de GetItem ou de BatchGetItem. Au lieu de cela, le total sera seulement de 25 unités de capacité en lecture, comme illustré ci-après : (100 * 1024 bytes = 100 KB) / 4 KB = 25 read capacity units Pour de plus amples informations, veuillez consulter Calcul des unités de capacité (p. 182). Unités de capacité en écriture Si la taille de vos éléments est inférieure à 1 KB, chaque unité de capacité en écriture génère une écriture par seconde. Par exemple, supposons que vous vouliez écrire 100 éléments par seconde sur votre table et que les éléments aient une taille de 512 octets. Dans ce scénario, chaque écriture nécessite une unité provisionnée de capacité en écriture. Pour le déterminer, vous divisez la taille d'élément de l'opération par 1 KB, puis arrondissez au nombre entier le plus proche : 512 bytes / 1 KB = 0.5 --> 1 Dans ce scénario, vous voulez définir le débit alloué en écriture de la table sur 100 unités de capacité en écriture : 1 write capacity unit per item × 100 writes per second = 100 write capacity units Si la taille de vos éléments est supérieure à 1 KB, vous devez arrondir la taille d'élément à la limite 1 KB suivante. Par exemple, supposons que vous vouliez effectuer 10 écritures par seconde, et que les éléments aient une taille de 1,5 Ko. Tout d'abord, déterminez le nombre d'unités requises de capacité en écriture par élément, en arrondissant au nombre entier plus proche, comme illustré ci-après : 1.5 KB / 1 KB = 1.5 --> 2 Le résultat est deux unités de capacité en écriture par élément. Maintenant, multipliez le résultat par le nombre d'écritures par seconde : 2 write capacity units per item × 10 writes per second = 20 write capacity units Par conséquent, vous devez définir les unités allouées de capacité en écriture sur 20 dans ce scénario. Pour utiliser un seul élément, choisissez l'opération PutItem, UpdateItem ou DeleteItem, le cas échéant. Vous pouvez aussi utiliser BatchWriteItem pour insérer ou supprimer jusqu'à 25 éléments en une seule opération. (Notez que BatchWriteItem prend en charge les opérations PutItem et DeleteItem, mais pas UpdateItem.) API Version 2012-08-10 19 Amazon DynamoDB Manuel du développeur Partitions et distribution des données Achat de la capacité réservée DynamoDB permet aux clients d'acheter une capacité réservée, comme décrit à l'adresse Tarification Amazon DynamoDB. Avec une capacité réservée, vous payez une fois un droit initial et vous vous engagez à un niveau d'utilisation minimal sur une période donnée. En réservant à l'avance vos unités de capacité en lecture et à l'écriture, vous réalisez des économies importantes par rapport au débit alloué à la demande. Pour gérer la capacité réservée, accédez à la console DynamoDB, puis choisissez Reserved Capacity. Note Vous pouvez empêcher les utilisateurs d'afficher ou d'acheter une capacité réservée, tout en leur permettant d'accéder au reste de la console. Pour plus d'informations, consultez « Octroi des autorisations pour empêcher l'achat d'offres de capacité réservée » dans Authentification et contrôle d'accès pour Amazon DynamoDB (p. 465). Partitions et distribution des données DynamoDB stocke les données dans les partitions. Une partition est une allocation de stockage pour une table, basée sur des disques SSD et automatiquement répliquée sur plusieurs zones de disponibilité au sein d'une région AWS. L'administration de la partition est entièrement gérée par DynamoDB ; les clients n'ont jamais besoin de gérer les partitions eux-mêmes. Lorsque vous créez une table, l'état initial de la table est CREATING. Au cours de cette phase, DynamoDB alloue les partitions suffisantes à la table afin qu'elle puisse gérer vos exigences de débit alloué. Vous pouvez commencer à écrire et à lire les données de table une fois que l'état de la table est devenu ACTIVE. DynamoDB alloue des partitions supplémentaires à une table dans les cas suivants : • Si vous augmentez les paramètres de débit alloué de la table au-delà de ce que les partitions existantes peuvent prendre en charge. • Si la capacité d'une partition existante est pleine et qu'un espace de stockage supplémentaire est obligatoire. Pour en savoir plus, consultez Comprendre le comportement des partitions (p. 575). La gestion de la partition s'effectue automatiquement à l'arrière-plan et est transparente pour vos applications. Votre table reste disponible tout au long et prend entièrement en charge vos besoins de débit alloué. Notez que les index dans DynamoDB sont également composés de partitions. Les données d'un index sont stockées séparément des données de sa table de base, mais les partitions d'index se comportent de la même manière que les partitions de table. Données de distribution : clé de partition Si votre table possède une clé primaire simple (clé de partition uniquement), DynamoDB stocke et récupère chaque élément en fonction de sa valeur de clé de partition. Pour écrire un élément dans la table, DynamoDB utilise la valeur de la clé de partition comme entrée d'une fonction de hachage interne. La valeur de sortie de la fonction de hachage détermine la partition dans laquelle l'élément sera stocké. API Version 2012-08-10 20 Amazon DynamoDB Manuel du développeur Partitions et distribution des données Pour lire un élément de la table, vous devez spécifier la valeur de clé de partition de l'élément. DynamoDB utilise cette valeur comme entrée de sa fonction de hachage, ce qui donne la partition dans laquelle l'élément est disponible. Le schéma suivant montre une table nommée Pets, qui s'étend sur plusieurs partitions. La clé primaire de la table est AnimalType (seul cet attribut de clé est affiché). DynamoDB utilise sa fonction de hachage pour déterminer où stocker un nouvel élément : dans le cas présent, en fonction de la valeur de hachage de la chaîne Dog. Notez que les éléments ne sont pas stockés selon un ordre trié. L'emplacement de chaque élément est déterminé par la valeur de hachage de sa clé de partition. Note DynamoDB est optimisé pour une distribution uniforme des éléments entre les partitions d'une table, quel que soit le nombre de partitions. Nous vous conseillons de choisir une clé de partition qui peut avoir un grand nombre de valeurs distinctes par rapport au nombre d'éléments de la table. Pour de plus amples informations, veuillez consulter Instructions pour l'utilisation des tables (p. 572). Distribution de données : clé de partition et clé de tri Si la table possède une clé primaire (clé de partition et clé de tri), DynamoDB calcule la valeur de hachage de la clé de partition de la même manière, comme décrit dans Données de distribution : clé de partition (p. 20), mais stocke tous les éléments avec la même valeur de clé de partition physiquement proches les uns des autres, triés par la valeur de clé de tri. API Version 2012-08-10 21 Amazon DynamoDB Manuel du développeur Partitions et distribution des données Pour écrire un élément dans la table, DynamoDB calcule la valeur de hachage de la clé de partition pour déterminer quelle partition doit contenir l'élément. Dans cette partition, comme il peut y avoir plusieurs éléments avec la même valeur de clé de partition, DynamoDB stocke l'élément parmi les autres avec la même clé de partition, par ordre croissant de la clé de tri. Pour lire un élément de la table, vous devez spécifier la valeur de clé de partition et la valeur de clé de tri. DynamoDB calcule la valeur de hachage de la clé de partition, produisant la partition dans laquelle l'élément est disponible. Vous pouvez lire plusieurs éléments de la table en une seule opération (Query), à condition que les éléments que vous voulez aient la même valeur de clé de partition. DynamoDB retourne tous les éléments avec cette valeur de clé de partition. Le cas échéant, vous pouvez appliquer une condition à la clé de tri afin qu'elle retourne uniquement les éléments d'une plage de valeurs donnée. Supposons que la table Pets ait une clé primaire composite, consistant en AnimalType (clé de partition) et Name (clé de tri). Le schéma suivant illustre DynamoDB écrivant un élément avec une valeur de clé de partition de Dog et une valeur de clé de tri de Fido. Pour lire ce même élément depuis la table Pets, DynamoDB calcule la valeur de hachage de Dog, produisant la partition dans laquelle ces éléments sont stockés. DynamoDB analyse ensuite les valeurs d'attribut de la clé de tri jusqu'à trouver Fido. Pour lire tous les éléments avec un AnimalType égal à Dog, vous pouvez émettre une opération Query sans spécifier une condition de clé de tri. Par défaut, les éléments sont retournés dans l'ordre où ils sont stockés (c'est-à-dire, en ordre croissant par clé de tri). Le cas échéant, vous pouvez demander à la place l'ordre décroissant. API Version 2012-08-10 22 Amazon DynamoDB Manuel du développeur De SQL à NoSQL Pour interroger uniquement certains éléments Dog, vous pouvez appliquer une condition à la clé de tri (par exemple, seuls les éléments Dog où Name se trouve dans la plage A à K). Note Dans une table DynamoDB, il n'existe pas de limite supérieure au nombre de valeurs de clé de tri distinctes par valeur de clé de partition. Si vous avez besoin de stocker plusieurs milliards d'éléments Dog dans la table Pets, DynamoDB alloue automatiquement assez de stockage pour gérer cette exigence. De SQL à NoSQL Si vous développez des applications, il se peut que vous ayez une certaine expérience de l'utilisation des systèmes de gestion de base de données relationnelles (SGBDR) et des langages de requête structurée (SQL). Lorsque vous commencerez à travailler avec Amazon DynamoDB, vous rencontrerez beaucoup d'aspects similaires, mais également beaucoup d'aspects différents. Cette section décrit les tâches courantes de base de données, en comparant les instructions SQL et leurs opérations DynamoDB équivalentes. NoSQL est le terme utilisé pour décrire les systèmes de base de données non relationnelles qui sont hautement disponible, évolutifs et optimisés pour des performances élevées. Au lieu du modèle relationnel, les bases de données NoSQL (comme DynamoDB) utilisent d'autres modèles pour la gestion des données, tels que les paires clé-valeur ou le stockage de document. Pour plus d'informations, consultez http://aws.amazon.com/nosql. Note Les exemples SQL de cette section sont compatibles avec le système de gestion de base de données relationnelle MySQL. Les exemples DynamoDB de cette section affichent le nom de l'opération DynamoDB, ainsi que les paramètres de l'opération au format JSON. Pour les exemples de code qui utilisent ces opérations, consultez le manuel Guide de démarrage de Amazon DynamoDB. Rubriques • SQL ou NoSQL ? (p. 23) • Accès à la base de données (p. 25) • Création d'une table (p. 27) • Obtention d'informations sur une table (p. 29) • Ecriture de données dans une table (p. 30) • Lecture de données à partir d'une table (p. 32) • Gestion des index (p. 38) • Modification de données dans une table (p. 41) • Suppression de données d'une table (p. 43) • Suppression d'une table (p. 44) SQL ou NoSQL ? Aujourd'hui, les applications ont des besoins plus exigeants que par le passé. Par exemple, un jeu en ligne peut démarrer avec quelques utilisateurs seulement et une très petite quantité de données. Cependant, si le jeu devient un succès, il peut facilement dépasser les ressources du système de gestion de la base de données sous-jacente. Il n'est pas rare que les applications web aient des API Version 2012-08-10 23 Amazon DynamoDB Manuel du développeur SQL ou NoSQL ? centaines, des milliers ou des millions d'utilisateurs simultanés, avec des téraoctets ou plus de nouvelles données générées par jour. Les bases de données de telles applications doivent gérer des dizaines (voire des centaines) de milliers de lectures et d'écritures par seconde. Amazon DynamoDB convient parfaitement à ces types de charges de travail. En tant que développeur, vous pouvez commencer par une faible quantité de débit alloué et l'augmenter progressivement au fur et à mesure que votre application devient plus populaire. DynamoDB s'adapte en toute transparence pour gérer un très grand nombre d'utilisateurs et de très importantes quantités de données. Le tableau suivant montre quelques différences de haut niveau entre un système de gestion de base de données relationnelles (SGBDR) et DynamoDB : Caractéristiques Système de gestion de base de données relationnelles (SGBDR) Amazon DynamoDB Charges de travail optimales Requêtes ad hoc ; entreposage de données ; traitement analytique en ligne (OLAP). Applications web, y compris les réseaux sociaux, les jeux, le partage des fichiers multimédias et l'IoT (Internet des objets). Modèle de données Le modèle relationnel nécessite un schéma bien défini, dans lequel les données sont normalisées en tables, lignes et colonnes. De plus, toutes les relations sont définies entre tables, colonnes, index et autres éléments de base de données. DynamoDB est sans schéma. Chaque table doit avoir une clé primaire pour identifier de façon unique chaque élément de données, mais il n'y a pas de contraintes similaires sur les autres attributs non-clés. DynamoDB permet de gérer les données structurées ou semi-structurées, y compris les documents JSON. Accès aux données SQL (Structured Query Language) constitue la norme pour le stockage et la récupération de données. Les bases de données relationnelles offrent un riche ensemble d'outils pour simplifier le développement d'applications de base de données, mais tous ces outils utilisent SQL. Vous pouvez choisir AWS Management Console ou l'interface de ligne de commande pour utiliser DynamoDB et exécuter les tâches ad hoc. Les applications peuvent mettre à profit les kits de développement logiciel (SDK) AWS pour utiliser DynamoDB avec les interfaces basées sur les objets, orientées documents ou de bas niveau. Performances Les bases de données relationnelles étant optimisées pour le stockage, les performances dépendent généralement du sous-système du disque. Les développeurs et les administrateurs de base de données doivent optimiser les requêtes, les index et les structures de table afin d'atteindre des performances de pointe. DynamoDB étant optimisé pour le calcul, les performances dépendent principalement du matériel sous-jacent et de la latence réseau. En tant que service géré, DynamoDB vous protège, ainsi que vos applications, de ces détails de mise en œuvre, si bien que vous pouvez vous concentrer sur la conception et la création d'applications robustes, aux hautes performances. API Version 2012-08-10 24 Amazon DynamoDB Manuel du développeur Accès à la base de données Caractéristiques Système de gestion de base de données relationnelles (SGBDR) Amazon DynamoDB Dimensionnement Il est plus facile d'agrandir avec un matériel plus rapide. Il est également possible pour les tables de base de données de s'étendre sur plusieurs hôtes d'un système distribué, mais cela nécessite des investissements supplémentaires. Les bases de données relationnelles possèdent une taille maximale pour le nombre de fichiers et leur taille, ce qui impose des limites supérieures sur l'évolutivité. DynamoDB est conçu pour monter en charge à l'aide de clusters distribués de matériel. Cette conception permet un débit accru sans augmentation de la latence. Les clients spécifient leurs exigences de débit et DynamoDB alloue les ressources suffisantes pour répondre à ces exigences. Il n'y a aucune limite supérieure sur le nombre d'éléments par table, ni sur la taille totale de la table. Accès à la base de données Avant que votre application ne puisse accéder à une base de données, elle doit être authentifiée afin de garantir que l'application a le droit d'utiliser la base de données et autorisée afin que l'application ne puisse exécuter que les actions pour lesquelles elle dispose d'autorisations. Le schéma suivant illustre l'interaction client avec une base de données relationnelle et avec DynamoDB. Le tableau suivant propose plus d'informations sur les tâches liées à l'interaction client : API Version 2012-08-10 25 Amazon DynamoDB Manuel du développeur Accès à la base de données Caractéristiques Système de gestion de base de données relationnelles (SGBDR) Amazon DynamoDB Outils pour accéder à la base de données La plupart des bases de données relationnelles offrent une interface de ligne de commande, de telle sorte que vous pouvez entrer les instructions SQL ad hoc et voir les résultats immédiatement. Dans la plupart des cas, vous écrivez le code de l'application. Vous pouvez également utiliser AWS Management Console ou l'AWS Command Line Interface (AWS CLI) pour envoyer des demandes ad hoc à DynamoDB et afficher les résultats. Connexion à la base de données Un programme d'application établit et gère une connexion réseau avec la base de données. Lorsque l'application est terminée, il met fin à la connexion. DynamoDB est un service web, et les interactions dont il est l'objet sont sans état. Les applications n'ont pas besoin de maintenir des connexions réseau permanentes. Au lieu de cela, l'interaction avec DynamoDB se produit à l'aide de réponses et de demandes HTTP(S). Authentification Une application ne peut pas se connecter à la base de données tant qu'elle n'est pas authentifiée. Le SGBDR peut effectuer l'authentification luimême ou déléguer cette tâche au système d'exploitation hôte ou à un service d'annuaire. Chaque demande adressée à DynamoDB doit être accompagnée d'une signature de chiffrement, qui authentifie cette requête particulière. Les kits de développement logiciel (SDK) AWS offrent toute la logique nécessaire pour la création de signatures et la signature de demandes. Pour plus d'informations, consultez Signatures de demandes d'API AWS dans le manuel AWS General Reference. Autorisation Les applications peuvent uniquement exécuter les actions auxquelles elles sont autorisés. Les administrateurs de base de données ou les propriétaires d'applications peuvent utiliser les instructions SQL GRANT et REVOKE pour contrôler l'accès aux objets de base de données (tels que les tables) et aux données (telles que les lignes d'une table), ou la possibilité d'émettre certaines instructions SQL. Dans DynamoDB, l'autorisation est gérée par AWS Identity and Access Management (IAM). Vous pouvez écrire une stratégie IAM pour accorder les autorisations sur une ressource DynamoDB (une table, par exemple), puis autoriser les utilisateurs et les rôles IAM à utiliser cette stratégie. IAM propose également un contrôle d'accès précis pour les éléments de données individuels des tables DynamoDB. Pour de plus amples informations, veuillez consulter Authentification et contrôle d'accès pour Amazon DynamoDB (p. 465). API Version 2012-08-10 26 Amazon DynamoDB Manuel du développeur Création d'une table Caractéristiques Système de gestion de base de données relationnelles (SGBDR) Amazon DynamoDB Envoi d'une demande L'application émet une instruction SQL pour chaque opération de base de données qu'elle souhaite effectuer. A la réception de l'instruction SQL, le SGBDR vérifie sa syntaxe, crée un plan pour effectuer l'opération, puis exécute le plan. L'application envoie les requêtes HTTP(S) à DynamoDB. Les requêtes contiennent le nom de l'opération DynamoDB à effectuer, ainsi que les paramètres. DynamoDB exécute la requête immédiatement. Réception d'une réponse Le SGBDR retourne les résultats de l'instruction SQL. S'il y a une erreur, le SGBDR retourne un statut d'erreur et un message. DynamoDB retourne une réponse HTTP(S) contenant les résultats de l'opération. S'il y a une erreur, DynamoDB retourne un statut d'erreur HTTP et un message. Création d'une table Les tables sont les structures de données fondamentales dans les bases de données relationnelles et dans DynamoDB. Un systèmes de gestion de base de données relationnelles (SGBDR) vous permet de définir le schéma de la table lorsque vous la créez. En revanche, les tables DynamoDB sont sans schéma : en dehors de la clé primaire, vous n'avez pas besoin de définir d'attributs ou de types de données au moment de la création de la table. SQL Utilisez l'instruction CREATE TABLE pour créer une table, comme illustré dans l'exemple suivant. CREATE TABLE Music ( Artist VARCHAR(20) NOT NULL, SongTitle VARCHAR(30) NOT NULL, AlbumTitle VARCHAR(25), Year INT, Price FLOAT, Genre VARCHAR(10), Tags TEXT, PRIMARY KEY(Artist, SongTitle) ); La clé primaire de la table se compose d'Artist et de SongTitle. Vous devez définir toutes les colonnes de la table et leurs types de données, ainsi que la clé primaire de la table. (Vous pouvez utiliser l'instruction ALTER TABLE pour modifier ces définitions ultérieurement, si nécessaire.) De nombreuses implémentations SQL vous permettent de définir les spécifications de stockage de votre table, dans le cadre de l'instruction CREATE TABLE. Sauf spécification contraire, la table est créée avec les paramètres de stockage par défaut. Dans un environnement de production, un administrateur de base de données peut aider à déterminer les paramètres de stockage optimaux. API Version 2012-08-10 27 Amazon DynamoDB Manuel du développeur Création d'une table DynamoDB Utilisez l'action CreateTable pour créer une table, en spécifiant les paramètres, comme illustré ciaprès : { TableName : "Music", KeySchema: [ { AttributeName: "Artist", KeyType: "HASH", //Partition key }, { AttributeName: "SongTitle", KeyType: "RANGE" //Sort key } ], AttributeDefinitions: [ { AttributeName: "Artist", AttributeType: "S" }, { AttributeName: "SongTitle", AttributeType: "S" } ], ProvisionedThroughput: { ReadCapacityUnits: 1, WriteCapacityUnits: 1 } } La clé primaire de cette table se compose de la clé de partition Artist et de la clé de tri SongTitle. Vous devez fournir les paramètres suivants à CreateTable : • TableName : nom de la table. • KeySchema : attributs utilisés pour la clé primaire. Pour plus d'informations, consultez Tables, éléments et attributs (p. 3) et Clé primaire (p. 5). • AttributeDefinitions : types de données pour les attributs du schéma de clé. • ProvisionedThroughput : nombre de lectures et d'écritures par seconde dont vous avez besoin pour cette table. DynamoDB se réserve un stockage et des ressources système suffisants afin que vos exigences de débit soient toujours satisfaites. Vous pouvez utiliser l'action UpdateTable pour modifier ces éléments ultérieurement, si nécessaire. Vous n'avez pas besoin de spécifier les besoins de stockage d'une table, car l'allocation du stockage est entièrement gérée par DynamoDB. Note Pour obtenir des exemples de code utilisant CreateTable, consultez le manuel Guide de démarrage de Amazon DynamoDB. API Version 2012-08-10 28 Amazon DynamoDB Manuel du développeur Obtention d'informations sur une table Obtention d'informations sur une table Vous pouvez vérifier qu'une table a été créée selon vos spécifications. Dans une base de données relationnelle, la totalité du schéma de la table est affiché. Les tables DynamoDB sont sans schéma, si bien que seuls les attributs de clé primaires sont affichés. SQL La plupart des systèmes de gestion de base de données relationnelle (SGBDR) vous permettent de décrire la structure de la table : colonnes, types de données, définition de la clé primaire, et ainsi de suite. Il n'existe aucune méthode standard pour ce faire dans SQL. Cependant, beaucoup de systèmes de base de données offrent une commande DESCRIBE. Voici un exemple dans MySQL : DESCRIBE Music; Cette commande retourne la structure de votre table, avec tous les noms de colonnes, types de données et tailles : +------------+-------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +------------+-------------+------+-----+---------+-------+ | Artist | varchar(20) | NO | PRI | NULL | | | SongTitle | varchar(30) | NO | PRI | NULL | | | AlbumTitle | varchar(25) | YES | | NULL | | | Year | int(11) | YES | | NULL | | | Price | float | YES | | NULL | | | Genre | varchar(10) | YES | | NULL | | | Tags | text | YES | | NULL | | +------------+-------------+------+-----+---------+-------+ La clé primaire de la table se compose d'Artist et de SongTitle. DynamoDB DynamoDB a une action DescribeTable, qui est similaire. Le seul paramètre est le nom de la table, comme illustré ci-après : { TableName : "Music" } La réponse de DescribeTable se présente ainsi : { "Table": { "AttributeDefinitions": [ { "AttributeName": "Artist", "AttributeType": "S" }, { "AttributeName": "SongTitle", "AttributeType": "S" } ], API Version 2012-08-10 29 Amazon DynamoDB Manuel du développeur Ecriture de données dans une table "TableName": "Music", "KeySchema": [ { "AttributeName": "Artist", "KeyType": "HASH" //Partition key }, { "AttributeName": "SongTitle", "KeyType": "RANGE" //Sort key } ], ... DescribeTable retourne également des informations. sur les index de la table, les paramètres de débit alloué, le nombre approximatif d'éléments et autres métadonnées. Ecriture de données dans une table Les tables des bases de données relationnelles contiennent des lignes de données. Les lignes se composent de colonnes. Les tables DynamoDB contiennent des éléments. Les éléments sont composés d'attributs. Cette section décrit comment écrire une ligne (ou un élément) dans une table. SQL Une table d'une base de données relationnelle est une structure de données à deux dimensions, composée de lignes et de colonnes. Certains systèmes de gestion de base de données fournissent également la prise en charge des données semi-structurées, généralement avec les types de données natifs JSON ou XML. Cependant, les détails de la mise en œuvre varient selon les fournisseurs. Dans SQL, vous utilisez l'instruction INSERT pour ajouter une ligne à une table : INSERT INTO Music (Artist, SongTitle, AlbumTitle, Year, Price, Genre, Tags) VALUES( 'No One You Know', 'Call Me Today', 'Somewhat Famous', 2015, 2.14, 'Country', '{"Composers": ["Smith", "Jones","Davis"],"LengthInSeconds": 214}' ); La clé primaire de la table se compose d'Artist et de SongTitle. Vous devez spécifier les valeurs de ces colonnes. Note Dans cet exemple, nous utilisons la colonne Tags pour stocker les données semi-structurées sur les chansons de la table Music. Nous avons défini la colonne Tags comme type TEXT, ce qui permet de stocker jusqu'à 65 535 caractères dans MySQL. DynamoDB Dans Amazon DynamoDB, vous utilisez l'action PutItem pour ajouter un élément à une table : API Version 2012-08-10 30 Amazon DynamoDB Manuel du développeur Ecriture de données dans une table { TableName: "Music", Item: { "Artist":"No One You Know", "SongTitle":"Call Me Today", "AlbumTitle":"Somewhat Famous", "Year": 2015, "Price": 2.14, "Genre": "Country", "Tags": { "Composers": [ "Smith", "Jones", "Davis" ], "LengthInSeconds": 214 } } } La clé primaire de la table se compose d'Artist et de SongTitle. Vous devez spécifier les valeurs de ces attributs. Voici quelques éléments clés à savoir sur cet exemple PutItem : • DynamoDB assure un support natif pour les documents, à l'aide de JSON. Cela fait de DynamoDB un outil idéal pour stocker les données semi-structurées, telles que Tags. Vous pouvez également récupérer et manipuler les données à partir des documents JSON. • La table Music n'a pas d'attributs prédéfinis, autres que la clé primaire (Artist et SongTitle). • La plupart des bases de données SQL sont orientées transactions. Lorsque vous émettez une instruction INSERT, les modifications des données ne sont pas permanentes jusqu'à ce que vous lanciez une instruction COMMIT. Avec Amazon DynamoDB, les effets d'une action PutItem sont permanents lorsque DynamoDB répond avec un code d'état HTTP 200 (OK). Note Pour obtenir des exemples de code utilisant PutItem, consultez le manuel Guide de démarrage de Amazon DynamoDB. Voici quelques autres exemples de PutItem. { TableName: "Music", Item: { "Artist": "No One You Know", "SongTitle": "My Dog Spot", "AlbumTitle":"Hey Now", "Price": 1.98, "Genre": "Country", "CriticRating": 8.4 } } { TableName: "Music", API Version 2012-08-10 31 Amazon DynamoDB Manuel du développeur Lecture de données à partir d'une table Item: { "Artist": "No One You Know", "SongTitle": "Somewhere Down The Road", "AlbumTitle":"Somewhat Famous", "Genre": "Country", "CriticRating": 8.4, "Year": 1984 } } { TableName: "Music", Item: { "Artist": "The Acme Band", "SongTitle": "Still In Love", "AlbumTitle":"The Buck Starts Here", "Price": 2.47, "Genre": "Rock", "PromotionInfo": { "RadioStationsPlaying":[ "KHCR", "KBQX", "WTNR", "WJJH" ], "TourDates": { "Seattle": "20150625", "Cleveland": "20150630" }, "Rotation": "Heavy" } } } { TableName: "Music", Item: { "Artist": "The Acme Band", "SongTitle": "Look Out, World", "AlbumTitle":"The Buck Starts Here", "Price": 0.99, "Genre": "Rock" } } Note En plus de PutItem, Amazon DynamoDB prend en charge une action BatchWriteItem pour écrire plusieurs éléments à la fois. Lecture de données à partir d'une table Avec SQL, vous utilisez l'instruction SELECT pour extraire une ou plusieurs lignes d'une table. Vous utilisez la clause WHERE pour déterminer les données qui vous sont renvoyées. DynamoDB fournit les opérations suivantes pour lire les données : • GetItem : extrait un seul élément d'une table. C'est le moyen le plus efficace de lire un seul élément, car il fournit un accès direct à l'emplacement physique de l'élément. (DynamoDB fournit API Version 2012-08-10 32 Amazon DynamoDB Manuel du développeur Lecture de données à partir d'une table aussi l'opération BatchGetItem, ce qui vous permet d'effectuer jusqu'à 100 appels GetItem en une seule opération.) • Query : récupère tous les éléments ayant une clé de partition spécifique. Au sein de ces éléments, vous pouvez appliquer une condition à la clé de tri et récupérer uniquement un sous-ensemble des données. Query fournit un accès rapide et efficace aux partitions où les données sont stockées. (Pour de plus amples informations, veuillez consulter Partitions et distribution des données (p. 20).) • Scan : récupère tous les éléments de la table spécifiée. (Cette opération ne doit pas être utilisée avec les grandes tables, car elle peut consommer d'importantes quantités de ressources système.) Note Avec une base de données relationnelle, vous pouvez utiliser l'instruction SELECT pour joindre les données de plusieurs tables et retourner les résultats. Les jointures sont fondamentales pour le modèle relationnel. Pour garantir que les jointures s'exécutent efficacement, la base de données et ses applications doivent être optimisées sur une base continue. DynamoDB est une base de données NoSQL non relationnelle et ne prend pas en charge les jointures de tables. Au lieu de cela, les applications lisent les données d'une seule table à la fois. Les sections suivantes décrivent les différents cas d'utilisation de lecture des données et comment exécuter ces tâches avec une base de données relationnelle et avec DynamoDB. Rubriques • Lecture d'un élément à l'aide de sa clé primaire (p. 33) • Interrogation d'une table (p. 35) • Analyse d'une table (p. 37) Lecture d'un élément à l'aide de sa clé primaire Un modèle d'accès commun aux bases de données consiste à lire un seul élément d'une table. Vous devez spécifier la clé primaire de l'élément que vous voulez. SQL Dans SQL, vous utilisez l'instruction SELECT pour récupérer les données d'une table. Vous pouvez demander une ou plusieurs colonnes du résultat (ou la totalité, si vous utilisez l'opération *). La clause WHERE détermine les lignes à retourner. L'instruction SELECT suivante permet d'extraire une seule ligne de la table Music. La clause WHERE spécifie les valeurs de clé primaire. SELECT * FROM Music WHERE Artist='No One You Know' AND SongTitle = 'Call Me Today' Vous pouvez modifier cette requête pour récupérer uniquement un sous-ensemble des colonnes : SELECT AlbumTitle, Year, Price FROM Music WHERE Artist='No One You Know' AND SongTitle = 'Call Me Today' API Version 2012-08-10 33 Amazon DynamoDB Manuel du développeur Lecture de données à partir d'une table Notez que la clé primaire de la table se compose d'Artist et de SongTitle. DynamoDB DynamoDB fournit l'action GetItem pour récupérer un élément à partir de sa clé primaire. L'action GetItem est extrêmement efficace, car elle fournit un accès direct à l'emplacement physique de l'élément. (Pour de plus amples informations, veuillez consulter Partitions et distribution des données (p. 20).) Par défaut, GetItem retourne l'élément entier avec tous ses attributs. { TableName: "Music", Key: { "Artist": "No One You Know", "SongTitle": "Call Me Today" } } Vous pouvez ajouter un paramètre ProjectionExpression pour renvoyer uniquement certains des attributs : { TableName: "Music", Key: { "Artist": "No One You Know", "SongTitle": "Call Me Today" }, "ProjectionExpression": "AlbumTitle, Year, Price" } Notez que la clé primaire de la table se compose d'Artist et de SongTitle. L'action DynamoDB GetItem est très efficace : elle utilise les valeurs de clé primaire pour déterminer l'emplacement de stockage exact de l'élément en question, et y récupérer directement ce dernier. L'instruction SQL SELECT est efficace de la même façon, en ce qui concerne la récupération d'éléments par valeurs de clé primaire. L'instruction SQL SELECT prend en charge de nombreux types de requêtes et d'analyses de table. DynamoDB fournit une fonctionnalité similaire avec les actions Query et Scan, qui sont décrites dans Interrogation d'une table (p. 35) et Analyse d'une table (p. 37). L'instruction SQL SELECT permet d'effectuer des jointures de tables, ce qui vous permet de récupérer les données de plusieurs tables à la fois. Les jointures sont plus efficaces lorsque les tables de base de données sont normalisées et que les relations entre les tables sont claires. Toutefois, si vous joignez un trop grand nombre de tables dans une instruction SELECT, les performances de l'application peuvent en être affectées. Vous pouvez contourner ces problèmes en utilisant la réplication de base de données, les vues matérialisées ou les réécritures de requête. DynamoDB est une base de données non relationnelle. En tant que tel, il ne prend pas en charge les jointures de table. Si vous migrez une application existante à partir d'une base de données relationnelle vers DynamoDB, vous devez dénormaliser votre modèle de données pour éliminer la nécessité de jointures. Note Pour obtenir des exemples de code utilisant GetItem, consultez le manuel Guide de démarrage de Amazon DynamoDB. API Version 2012-08-10 34 Amazon DynamoDB Manuel du développeur Lecture de données à partir d'une table Interrogation d'une table Un autre modèle commun d'accès est la lecture de plusieurs éléments d'une table, selon les critères de votre requête. SQL L'instruction SQL SELECT permet d'interroger les colonnes clés, les colonnes non-clés ou toute autre combinaison. La clause WHERE détermine quelles lignes sont retournées, comme illustré dans les exemples suivants : /* Return a single song, by primary key */ SELECT * FROM Music WHERE Artist='No One You Know' AND SongTitle = 'Call Me Today'; /* Return all of the songs by an artist */ SELECT * FROM Music WHERE Artist='No One You Know'; /* Return all of the songs by an artist, matching first part of title */ SELECT * FROM Music WHERE Artist='No One You Know' AND SongTitle LIKE 'Call%'; /* Return all of the songs by an artist, with a particular word in the title... ...but only if the price is less than 1.00 */ SELECT * FROM Music WHERE Artist='No One You Know' AND SongTitle LIKE '%Today%' AND Price < 1.00; Notez que la clé primaire de la table se compose d'Artist et de SongTitle. DynamoDB L'action DynamoDB Query vous permet de récupérer les données d'une manière similaire. L'action Query fournit un accès rapide et efficace aux emplacements physiques dans lesquels les données sont stockées. (Pour de plus amples informations, veuillez consulter Partitions et distribution des données (p. 20).) Vous pouvez utiliser Query avec n'importe quelle table ayant une clé primaire composite (clé de partition et clé de tri). Vous devez spécifier une condition d'égalité pour la clé de partition et, le cas échéant, fournir une autre condition pour la clé de tri. Le paramètre KeyConditionExpression spécifie les valeurs clés que vous souhaitez interroger. Vous pouvez utiliser un paramètre FilterExpression facultatif pour supprimer des résultats certains éléments avant qu'ils ne vous soient retournés. Dans DynamoDB, vous devez utiliser ExpressionAttributeValues comme espaces réservés dans les paramètres de l'expression (tels que KeyConditionExpression et FilterExpression). C'est analogue à l'utilisation des variables de liaison des bases de données relationnelles, où vous remplacez les valeurs réelles dans l'instruction SELECT au moment de l'exécution. API Version 2012-08-10 35 Amazon DynamoDB Manuel du développeur Lecture de données à partir d'une table Notez que la clé primaire de la table se compose d'Artist et de SongTitle. Voici quelques exemples d'action Query dans DynamoDB : // Return a single song, by primary key { TableName: "Music", KeyConditionExpression: "Artist = :a and SongTitle = :t", ExpressionAttributeValues: { ":a": "No One You Know", ":t": "Call Me Today" } } // Return all of the songs by an artist { TableName: "Music", KeyConditionExpression: "Artist = :a", ExpressionAttributeValues: { ":a": "No One You Know" } } // Return all of the songs by an artist, matching first part of title { TableName: "Music", KeyConditionExpression: "Artist = :a and begins_with(SongTitle, :t)", ExpressionAttributeValues: { ":a": "No One You Know", ":t": "Call" } } // Return all of the songs by an artist, with a particular word in the title... // ...but only if the price is less than 1.00 { TableName: "Music", KeyConditionExpression: "Artist = :a and contains(SongTitle, :t)", FilterExpression: "price < :p", ExpressionAttributeValues: { ":a": "No One You Know", ":t": "Today", ":p": 1.00 } } Note Pour obtenir des exemples de code utilisant Query, consultez le manuel Guide de démarrage de Amazon DynamoDB. API Version 2012-08-10 36 Amazon DynamoDB Manuel du développeur Lecture de données à partir d'une table Analyse d'une table Dans SQL, une instruction SELECT sans une clause WHERE retourne chaque ligne d'une table. Dans DynamoDB, l'opération Scan effectue la même chose. Dans les deux cas, vous pouvez extraire tous les éléments, ou seulement certains d'entre eux. Que vous utilisiez une base de données SQL ou NoSQL, les analyses doivent être utilisées avec modération, car elles peuvent consommer d'importantes quantités de ressources système. Parfois, une analyse est appropriée (analyse d'une petite table, par exemple) ou inévitable (exportation en bloc de données, par exemple). Cependant, en règle générale, vous devez concevoir vos applications de façon à éviter d'exécuter des analyses. SQL Dans SQL, vous pouvez analyser une table et récupérer toutes ses données en utilisant une instruction SELECT sans spécifier une clause WHERE. Vous pouvez demander une ou plusieurs colonnes dans le résultat. Ou, vous pouvez demander leur totalité si vous utilisez le caractère générique (*). Voici quelques exemples : /* Return all of the data in the table */ SELECT * FROM Music; /* Return all of the values for Artist and Title */ SELECT Artist, Title FROM Music; DynamoDB DynamoDB fournit une action Scan qui fonctionne d'une manière similaire. Voici quelques exemples : // Return all of the data in the table { TableName: "Music" } // Return all of the values for Artist and Title { TableName: "Music", ProjectionExpression: "Artist, Title" } L'action Scan fournit également un paramètre FilterExpression pour ignorer les éléments que vous ne souhaitez pas voir apparaître dans les résultats. Un paramètre FilterExpression est appliqué une fois la totalité de la table analysée, mais avant que les résultats ne vous soient retournés. (Cette option n'est pas recommandé avec les grandes tables : vous continuez à être facturé pour l'opération Scan complète, même si seulement quelques éléments correspondants sont retournés.) Note Pour les exemples de code qui utilisent Scan, consultez le manuel Guide de démarrage de Amazon DynamoDB. API Version 2012-08-10 37 Amazon DynamoDB Manuel du développeur Gestion des index Gestion des index Les index donnent accès à d'autres modèles de requête et peuvent accélérer les requêtes. Cette section compare la création et l'utilisation des index dans SQL et DynamoDB. Que vous utilisiez une base de données relationnelle ou DynamoDB, vous devez utiliser la création d'index avec réflexion. Chaque fois qu'une écriture se produit sur une table, tous les index de la table doivent être mis à jour. Dans un environnement à forte densité d'écritures avec de grandes tables, cette opération peut consommer d'importantes quantité de ressources système. Dans un environnement en lecture seule ou principalement en lecture, il ne s'agit pas réellement d'un problème ; cependant, vous devez vous assurer que les index sont effectivement utilisés par votre application et pas simplement qu'ils occupent de l'espace. Rubriques • Création d'un index (p. 38) • Interrogation et analyse d'un index (p. 40) Création d'un index SQL Dans une base de données relationnelle, un index est une structure de données qui vous permet d'exécuter des requêtes rapides sur différentes colonnes d'une table. Vous pouvez utiliser l'instruction SQL CREATE INDEX pour ajouter un index à une table existante, en spécifiant les colonnes à indexer. Une fois que l'index a été créé, vous pouvez interroger les données de la table comme à l'habitude, mais maintenant la base de données peut utiliser l'index pour retrouver rapidement les lignes spécifiées dans le tableau au lieu d'analyser la totalité de la table. Une fois que vous créez un index, la base de données le gère automatiquement. Chaque fois que vous modifiez les données de la table, l'index est automatiquement modifié pour refléter les modifications de la table. Dans MySQL, vous pouvez créer un index comme suit : CREATE INDEX GenreAndPriceIndex ON Music (genre, price); DynamoDB Dans DynamoDB, vous pouvez créer et utiliser un index secondaire à des fins similaires. Les index dans DynamoDB sont différents de leurs homologues relationnels. Lorsque vous créez un index secondaire, vous devez spécifier ses attributs clés, à savoir une clé de partition et une clé de tri. Après avoir créé l'index secondaire, vous pouvez lui appliquer une opération Query ou Scan tout comme vous le feriez avec une table. Comme DynamoDB n'a pas d'optimiseur de requête, un index secondaire est utilisé uniquement lorsque vous lui appliquez une opération Query ou Scan. DynamoDB prend en charge deux types différents d'index : • Les index secondaires globaux : la clé primaire de l'index peut être n'importe lequel des deux attributs de la table. • Les index secondaires locaux : la clé de partition de l'index doit être identique à la clé de partition de la table. Cependant, la clé de tri peut être n'importe quel autre attribut. DynamoDB garantit que les données d'un index secondaire sont cohérentes à terme avec la table. Vous pouvez demander des actions Query ou Scan à cohérence forte sur une table ou un index API Version 2012-08-10 38 Amazon DynamoDB Manuel du développeur Gestion des index secondaire local. Cependant, les index secondaires globaux ne prennent en charge que la cohérence à terme. Vous pouvez ajouter un index secondaire global à une table existante, à l'aide de l'action UpdateTable et en spécifiant GlobalSecondaryIndexUpdates : { TableName: "Music", AttributeDefinitions:[ {AttributeName: "Genre", AttributeType: "S"}, {AttributeName: "Price", AttributeType: "N"} ], GlobalSecondaryIndexUpdates: [ { Create: { IndexName: "GenreAndPriceIndex", KeySchema: [ {AttributeName: "Genre", KeyType: "HASH"}, //Partition key {AttributeName: "Price", KeyType: "RANGE"}, //Sort key ], Projection: { "ProjectionType": "ALL" }, ProvisionedThroughput: { "ReadCapacityUnits": 1,"WriteCapacityUnits": 1 } } } ] } Vous devez fournir les paramètres suivants à UpdateTable : • TableName : table à laquelle l'index sera associé. • AttributeDefinitions : types de données des attributs du schéma de clé de l'index. • GlobalSecondaryIndexUpdates : informations détaillées sur l'index que vous voulez créer : • IndexName : nom de l'index. • KeySchema : attributs utilisés pour la clé primaire de l'index. • Projection : attributs de la table copiés sur l'index. Dans ce cas, ALL signifie que tous les attributs sont copiés. • ProvisionedThroughput : nombre de lectures et d'écritures par seconde dont vous avez besoin pour cet index. (Cette information est distincte des paramètres de débit alloué de la table.) Une partie de cette opération implique le renvoi de données de la table vers le nouvel index. Pendant le renvoi, la table demeure disponible. Cependant, l'index n'est pas prêt jusqu'à ce que son attribut Backfilling passe de true à false. Vous pouvez utiliser l'action DescribeTable pour afficher cet attribut. Note Pour les exemples de code qui utilisent UpdateTable, consultez le manuel Guide de démarrage de Amazon DynamoDB. API Version 2012-08-10 39 Amazon DynamoDB Manuel du développeur Gestion des index Interrogation et analyse d'un index SQL Dans une base de données relationnelle, vous n'utilisez pas directement les index. Au lieu de cela, vous interrogez les tables à l'aide d'instructions SELECT et l'optimiseur de requête peut utiliser tous les index. Un optimiseur de requête est un composant d'un système de gestion de base de données relationnelle (SGBDR) qui évalue les index disponibles et détermine s'ils peuvent être utilisés pour accélérer une requête. Si tel est le cas, le SGBDR accède d'abord à l'index, puis l'utilise pour rechercher les données dans la table. Voici quelques instructions SQL qui peuvent utiliser GenreAndPriceIndex pour améliorer les performances. Nous supposons que la table Music possède suffisamment de données pour que l'optimiseur de requête décide d'utiliser cet index, plutôt que de simplement analyser la totalité de la table. /* All of the rock songs */ SELECT * FROM Music WHERE Genre = 'Rock'; /* All of the cheap country songs */ SELECT Artist, SongTitle, Price FROM Music WHERE Genre = 'Country' AND Price < 0.50; DynamoDB Dans DynamoDB, vous effectuez directement les opérations Query sur l'index, de la même manière que vous le feriez sur une table. Vous devez spécifier à la fois TableName et IndexName. Voici quelques requêtes sur GenreAndPriceIndex dans DynamoDB. (Le schéma de clé de l'index est composé de Genre et de Price.) // All of the rock songs { TableName: "Music", IndexName: "GenreAndPriceIndex", KeyConditionExpression: "Genre = :genre", ExpressionAttributeValues: { ":genre": "Rock" }, }; // All of the cheap country songs { TableName: "Music", IndexName: "GenreAndPriceIndex", KeyConditionExpression: "Genre = :genre and Price < :price", ExpressionAttributeValues: { API Version 2012-08-10 40 Amazon DynamoDB Manuel du développeur Modification de données dans une table ":genre": "Country", ":price": 0.50 }, ProjectionExpression: "Artist, SongTitle, Price" }; Cet exemple utilise une ProjectionExpression pour indiquer que nous voulons que certains attributs seulement, et non leur totalité, apparaissent dans les résultats. Vous pouvez également exécuter des opérations Scan sur un index secondaire, de la même manière que vous le feriez sur une table. Voici une analyse sur GenreAndPriceIndex : // Return all of the data in the index { TableName: "Music", IndexName: "GenreAndPriceIndex" } Modification de données dans une table Le langage SQL fournit l'instruction UPDATE pour la modification de données. DynamoDB utilise l'opération UpdateItem pour accomplir des tâches similaires. SQL Dans SQL, vous utilisez l'instruction UPDATE pour modifier une ou plusieurs lignes. La clause SET spécifie de nouvelles valeurs pour une ou plusieurs colonnes, et la clause WHERE détermine les lignes qui sont modifiées. Voici un exemple : UPDATE Music SET RecordLabel = 'Global Records' WHERE Artist = 'No One You Know' AND SongTitle = 'Call Me Today'; Si aucune ligne ne correspond à la clause WHERE, l'instruction UPDATE n'a aucun effet. DynamoDB Dans DynamoDB, vous utilisez l'action UpdateItem pour modifier un seul élément. (Si vous voulez modifier plusieurs éléments, vous devez utiliser plusieurs opérations UpdateItem.) Voici un exemple : { TableName: "Music", Key: { "Artist":"No One You Know", "SongTitle":"Call Me Today" }, UpdateExpression: "SET RecordLabel = :label", ExpressionAttributeValues: { ":label": "Global Records" } } API Version 2012-08-10 41 Amazon DynamoDB Manuel du développeur Modification de données dans une table Vous devez spécifier les attributs Key de l'élément à modifier et un paramètre UpdateExpression pour spécifier les valeurs d'attribut. UpdateItem remplace l'élément entier, plutôt que de remplacer des attributs individuels. UpdateItem se comporte comme une opération de « mise à jour/insertion » : l'élément est mis à jour s'il existe dans la tableau, mais dans le cas contraire, un nouvel élément est ajouté (inséré). UpdateItem prend en charge les écritures conditionnelles, où l'opération aboutit uniquement si un attribut ConditionExpression a la valeur true. Par exemple, l'action UpdateItem suivante n'effectue pas la mise à jour, à moins que le prix du morceau ne soit supérieur ou égal à 2,00 : { TableName: "Music", Key: { "Artist":"No One You Know", "SongTitle":"Call Me Today" }, UpdateExpression: "SET RecordLabel = :label", ConditionExpression: "Price >= :p", ExpressionAttributeValues: { ":label": "Global Records", ":p": 2.00 } } UpdateItem prend également en charge les compteurs atomiques, ou les attributs de type numérique qui peuvent être incrémentés ou décrémentés. Les compteurs atomiques sont similaires en de nombreuses façons aux générateurs de séquence, aux colonnes d'identité ou aux champs d'incrémentation automatique dans les bases de données SQL. Voici un exemple d'action UpdateItem pour initialiser un nouvel attribut (Plays) et suivre le nombre de fois où une chanson a été jouée : { TableName: "Music", Key: { "Artist":"No One You Know", "SongTitle":"Call Me Today" }, UpdateExpression: "SET Plays = :val", ExpressionAttributeValues: { ":val": 0 }, ReturnValues: "UPDATED_NEW" } Le paramètre ReturnValues est défini sur UPDATED_NEW, qui retourne les nouvelles valeurs de tous les attributs qui ont été mis à jour. Dans ce cas, la valeur 0 (zéro) est retournée. Chaque fois que quelqu'un écoute cette chanson, nous pouvons utiliser l'action UpdateItem suivante pour incrémenter Plays d'une unité : { TableName: "Music", Key: { "Artist":"No One You Know", "SongTitle":"Call Me Today" API Version 2012-08-10 42 Amazon DynamoDB Manuel du développeur Suppression de données d'une table }, UpdateExpression: "SET Plays = Plays + :incr", ExpressionAttributeValues: { ":incr": 1 }, ReturnValues: "UPDATED_NEW" } Note Pour obtenir des exemples de code utilisant UpdateItem, consultez le manuel Guide de démarrage de Amazon DynamoDB. Suppression de données d'une table Dans SQL, l'instruction DELETE supprime une ou plusieurs lignes d'une table. DynamoDB utilise l'opération DeleteItem pour supprimer un élément à la fois. SQL Dans SQL, vous utilisez l'instruction DELETE pour supprimer une ou plusieurs lignes. La clause WHERE détermine les lignes que vous voulez modifier. Voici un exemple : DELETE FROM Music WHERE Artist = 'The Acme Band' AND SongTitle = 'Look Out, World'; Vous pouvez modifier la clause WHERE pour supprimer plusieurs lignes. Par exemple, vous pouvez supprimer tous les morceaux d'un artiste particulier, comme illustré ci-après : DELETE FROM Music WHERE Artist = 'The Acme Band' Note Si vous omettez la clause WHERE, la base de données tente de supprimer toutes les lignes de la table. DynamoDB Dans DynamoDB, vous utilisez l'action DeleteItem pour supprimer les données d'une table, un élément à la fois. Vous devez spécifier les valeurs de clé primaire de l'élément. Voici un exemple : { TableName: "Music", Key: { Artist: "The Acme Band", SongTitle: "Look Out, World" } } Note En plus de DeleteItem, Amazon DynamoDB prend en charge une action BatchWriteItem pour supprimer plusieurs éléments à la fois. API Version 2012-08-10 43 Amazon DynamoDB Manuel du développeur Suppression d'une table DeleteItem prend en charge les écritures conditionnelles, où l'opération aboutit uniquement si un attribut ConditionExpression a la valeur true. Par exemple, l'action DeleteItem suivante supprime l'élément uniquement si elle dispose d'un attribut RecordLabel : { TableName: "Music", Key: { Artist: "The Acme Band", SongTitle: "Look Out, World" }, ConditionExpression: "attribute_exists(RecordLabel)" } Note Pour obtenir des exemples de code utilisant DeleteItem, consultez le manuel Guide de démarrage de Amazon DynamoDB. Suppression d'une table Dans SQL, vous utilisez l'instruction DROP TABLE pour supprimer une table. Dans DynamoDB, vous utilisez l'opération DeleteTable. SQL Lorsque vous n'avez plus besoin d'une table et que vous voulez l'ignorer de façon permanente, vous utilisez l'instruction DROP TABLE dans SQL : DROP TABLE Music; Une fois qu'une table est supprimée, elle ne peut pas être récupérée. (Certaines bases de données relationnelles vous permettent réellement d'annuler une opération DROP TABLE, mais il s'agit d'une fonctionnalité propre au fournisseur et qui n'est pas largement appliquée.) DynamoDB DynamoDB possède une action similaire :DeleteTable. Dans l'exemple suivant, la table est supprimée de façon définitive : { TableName: "Music" } Note Pour obtenir des exemples de code utilisant DeleteTable, consultez le manuel Guide de démarrage de Amazon DynamoDB. API Version 2012-08-10 44 Amazon DynamoDB Manuel du développeur Configuration de DynamoDB (version téléchargeable) Configuration d'DynamoDB Outre le service web Amazon DynamoDB, AWS fournit une version téléchargeable de DynamoDB que vous pouvez exécuter localement sur votre ordinateur. Pour configurer DynamoDB (version téléchargeable ou service web), consultez les sections suivantes. Rubriques • Configuration de DynamoDB (version téléchargeable) (p. 45) • Configuration de DynamoDB (service web) (p. 49) Configuration de DynamoDB (version téléchargeable) La version téléchargeable de DynamoDB vous permet d'écrire des applications sans accéder au service web Amazon DynamoDB réel. Au lieu de cela, la base de données est autonome sur votre ordinateur. Cette version locale de DynamoDB peut vous aider à économiser sur les frais de transfert de données, de stockage de données et de débit alloué. En outre, vous n'avez pas besoin d'une connexion Internet pendant que vous développez votre application. Lorsque vous êtes prêt à déployer votre application en production, vous pouvez apporter quelques modifications mineures à votre code afin qu'il utilise le service web Amazon DynamoDB. Rubriques • Téléchargement et exécution de DynamoDB (p. 45) • Définition du point de terminaison local (p. 47) • Notes d'utilisation (p. 48) Téléchargement et exécution de DynamoDB La version téléchargeable de DynamoDB est fournie comme fichier exécutable .jar. Il s'exécute sur Windows, Linux, Mac OS X et autres plateformes qui prennent en charge Java. Suivez ces étapes pour télécharger et exécuter DynamoDB sur votre ordinateur : API Version 2012-08-10 45 Amazon DynamoDB Manuel du développeur Téléchargement et exécution de DynamoDB 1. Téléchargez DynamoDB gratuitement en utilisant l'un de ces liens : • Format .tar.gz : https://s3-us-west-2.amazonaws.com/dynamodb-local/ dynamodb_local_latest.tar.gz • Format .zip : https://s3-us-west-2.amazonaws.com/dynamodb-local/dynamodb_local_latest.zip Important Bien que la version téléchargeable de DynamoDB puisse être disponible ailleurs, rien ne garantit qu'il s'agisse de la dernière version. Pour vous assurer d'avoir la dernière version, utilisez l'un des liens ci-dessus. DynamoDB sur votre ordinateur nécessite la version Java Runtime Environment (JRE) 6.x ou plus récente ; il ne fonctionne pas sur les versions JRE antérieures. DynamoDB (version téléchargeable) est également disponible dans AWS Toolkit pour Eclipse. Pour plus d'informations, consultez AWS Toolkit pour Eclipse. 2. Une fois que vous avez téléchargé l'archive, extrayez le contenu et copiez le répertoire extrait vers un emplacement de votre choix. 3. Pour démarrer DynamoDB sur votre ordinateur, ouvrez une fenêtre d'invite de commande, accédez au répertoire où vous avez extrait DynamoDBLocal.jar et entrez la commande suivante : java -Djava.library.path=./DynamoDBLocal_lib -jar DynamoDBLocal.jar sharedDb Les messages de diagnostic occasionnels s'affichent dans la fenêtre où DynamoDB est en cours d'exécution. DynamoDB traite les demandes entrantes jusqu'à ce que vous l'arrêtiez. Pour arrêter DynamoDB, tapez Ctrl + C dans la fenêtre d'invite de commande. Options de ligne de commande DynamoDB en cours d'exécution sur votre ordinateur accepte les options de ligne de commande suivantes : • -corsvalue : activer la prise en charge CORS (cross-origin resource sharing) pour JavaScript. Vous devez fournir une liste « allow » séparée par des virgules de domaines spécifiques. Le paramètre par défaut de -cors est un astérisque (*), qui autorise l'accès public. • -dbPathvalue : répertoire où DynamoDB écrit son fichier de base de données. Si vous ne spécifiez pas cette option, le fichier est écrit sur le répertoire actuel. Notez que vous ne pouvez pas spécifier à la fois -dbPath et -inMemory. • -delayTransientStatuses : conduit DynamoDB à provoquer des retards pour certaines opérations. DynamoDB peut exécuter certaines tâches presque instantanément, telles que les opérations créer/mettre à jour/supprimer sur les tables et les index ; cependant, le service DynamoDB réel nécessite plus de temps pour ces tâches. La définition de ce paramètre permet à DynamoDB de simuler le comportement du service web Amazon DynamoDB plus étroitement. (Actuellement, ce paramètre provoque des retards uniquement pour les index secondaires globaux dont l'état est CREATING ou DELETING.) • -help : affiche le récapitulatif de l'utilisation et les options. • -inMemory : DynamoDB est exécuté en mémoire, au lieu d'utiliser un fichier de base de données. Lorsque vous arrêtez DynamoDB, aucune des données n'est enregistrée. Notez que vous ne pouvez pas spécifier à la fois -dbPath et -inMemory. API Version 2012-08-10 46 Amazon DynamoDB Manuel du développeur Définition du point de terminaison local • -optimizeDbBeforeStartup : optimise les tables de base de données sous-jacentes avant de démarrer DynamoDB sur votre ordinateur. Vous devez également spécifier -dbPath lorsque vous utilisez ce paramètre. • -portvalue : numéro de port que DynamoDB utilise pour communiquer avec votre application. Si vous ne spécifiez pas cette option, le port par défaut est 8000. Note DynamoDB utilise le port 8000 par défaut. Si le port 8000 n'est pas disponible, la commande lève une exception. Vous pouvez utiliser l'option -port pour spécifier un autre numéro de port. Pour obtenir la liste complète des options d'exécution de DynamoDB, y compris -port, entrez la commande suivante : java -Djava.library.path=./DynamoDBLocal_lib -jar DynamoDBLocal.jar help • -sharedDb : DynamoDB utilise un seul fichier de base de données, au lieu d'utiliser des fichiers séparés pour chaque région et chaque information d'identification. Si vous spécifiez -sharedDb, tous les clients DynamoDB interagissent avec le même ensemble de tables, quelles que soient leur région et leur configuration des informations d'identification. Définition du point de terminaison local Les kits SDK et les outils AWS utilisent par défaut les points de terminaison du service web Amazon DynamoDB. Pour utiliser les outils et les kits SDK AWS avec l'exécution locale de DynamoDB, vous devez spécifier le point de terminaison local : http://localhost:8000 AWS Command Line Interface Vous pouvez utiliser l'interface de ligne de commande avec DynamoDB en cours d'exécution sur votre ordinateur. Par exemple, vous pouvez exécuter toutes les étapes de Création de tables et chargement d'exemples de données (p. 167) à l'aide de l'interface de ligne de commande. Vous utilisez le paramètre --endpoint-url avec l'interface de ligne de commande pour accéder à DynamoDB en cours d'exécution locale. Voici un exemple d'utilisation de l'interface de ligne de commande pour afficher les tables de DynamoDB sur votre ordinateur : aws dynamodb list-tables --endpoint-url http://localhost:8000 Note L'interface de ligne de commande ne peut pas utiliser la version téléchargeable de DynamoDB comme point de terminaison par défaut ; par conséquent, vous devez spécifier --endpointurl avec chaque commande de l'interface de ligne de commande. Kits de développement logiciel (SDK) AWS La façon dont vous spécifiez un point de terminaison dépend du langage de programmation et du kit de développement logiciel (SDK) AWS que vous utilisez. Les sections suivantes expliquent comment procéder pour différents langages : • Java : définition de la région AWS et du point de terminaison (p. 174) • .NET : définition de la région AWS et du point de terminaison (p. 176) • PHP : définition de la région AWS et du point de terminaison (p. 178) API Version 2012-08-10 47 Amazon DynamoDB Manuel du développeur Notes d'utilisation Note Pour obtenir des exemples en d'autres langages de programmation, consultez le manuel Guide de démarrage de Amazon DynamoDB. Tous les exemples de code du Guide de mise en route utilisent la version téléchargeable de DynamoDB. Notes d'utilisation A l'exception du point de terminaison, les applications qui s'exécutent avec DynamoDB sur votre système doivent également utiliser le service web Amazon DynamoDB. Cependant, vous devez être conscient des points suivants : • Si vous utilisez l'option -sharedDb, DynamoDB crée un seul fichier de base de données nommé shared-local-instance.db. Tous les programmes qui se connectent à DynamoDB accèdent à ce fichier. Si vous supprimez le fichier, vous perdez toutes les données que vous y avez stockées. • Si vous omettez -sharedDb, le fichier de base de données est nommé myaccesskeyid_region.db, avec l'ID de clé d'accès et la région AWS tels qu'ils apparaissent dans la configuration de votre application. Si vous supprimez le fichier, vous perdez toutes les données que vous y avez stockées. • Si vous utilisez l'option -inMemory, DynamoDB n'écrit aucun fichier de base de données. Au lieu de cela, toutes les données sont écrites en mémoire et les données ne sont pas enregistrées lorsque vous mettez fin à DynamoDB. • Si vous utilisez l'option -optimizeDbBeforeStartup, vous devez également spécifier le paramètre -dbPath de telle sorte que DynamoDB soit en mesure de trouver son fichier de base de données. • Les kits SDK AWS pour DynamoDB nécessitent que la configuration de votre application spécifie une valeur de clé d'accès et une valeur de région AWS. Sauf si vous utilisez l'option -sharedDb ou -inMemory, DynamoDB utilise ces valeurs pour nommer le fichier de base de données local. Bien que ces valeurs n'aient pas à être des valeurs AWS valides pour s'exécuter localement, vous pouvez trouver utile de choisir des valeurs valides afin de pouvoir par la suite exécuter votre code dans le cloud en modifiant simplement le point de terminaison que vous utilisez. Différences entre l'exécution locale de DynamoDB et le service web Amazon DynamoDB La version téléchargeable de DynamoDB tente d'émuler le service web Amazon DynamoDB aussi étroitement que possible. Cependant, elle diffère du service Amazon DynamoDB sur les points suivants : • Les régions et les comptes AWS distincts ne sont pas pris en charge au niveau client. • Les paramètres de débit alloué sont ignorés, même si l'opération CreateTable les requiert. Pour CreateTable, vous pouvez spécifier les nombres de votre choix pour le débit alloué en lecture et en écriture, même si ces chiffres ne seront pas utilisés. Vous pouvez appeler UpdateTable autant de fois que vous le souhaitez par jour ; cependant, les modifications des valeurs du débit alloué sont ignorées. • La vitesse des opérations de lecture et d'écriture sur les données de la table sont limitées uniquement par la vitesse de votre ordinateur. Les opérations CreateTable, UpdateTable et DeleteTable se produisent immédiatement, et l'état de la table est toujours ACTIVE. Les opérations UpdateTable qui modifient uniquement les paramètres de débit alloué sur les tables et/ ou les index secondaires globaux se produisent immédiatement. Si une opération UpdateTable crée ou supprime un index secondaire global, ces index passent par les états normaux (tels que CREATING et DELETING, respectivement) avant d'acquérir l'état ACTIVE. La table demeure ACTIVE pendant ce temps. API Version 2012-08-10 48 Amazon DynamoDB Manuel du développeur Configuration de DynamoDB (service web) • Les opérations de lecture sont cohérentes à terme. Cependant, en raison de la vitesse de l'exécution de DynamoDB sur votre ordinateur, la plupart des lectures apparaissent réellement comme à cohérence forte. • Les unités de capacité consommées ne sont pas suivies. Dans les réponses des opérations, les valeurs null sont retournées à la place des unités de capacité. • Les métriques des collections d'élément ne sont pas suivies, ni leurs tailles. Dans les réponses des opérations, les valeurs null sont retournées à la place des métriques des collections d'élément. • Dans DynamoDB, il existe a une limite de 1 Mo sur les données retournées par jeu de résultats. Le service web DynamoDB applique cette limite, de même que la version téléchargeable de DynamoDB. Cependant, lorsque vous interrogez un index, le service DynamoDB calcule uniquement la taille de la clé et des attributs projetés. En revanche, la version téléchargeable de DynamoDB calcule la taille de l'élément entier. • Si vous exploitez Flux DynamoDB, la vitesse à laquelle les partitions sont créées peut varier : dans le service web DynamoDB, le comportement de création des partitions est partiellement influencé par l'activité de partition de la table ; cependant, lorsque vous exécutez DynamoDB localement, il n'existe aucun partitionnement de table. Dans les deux cas, comme les partitions sont éphémères, votre application ne doit pas être dépendante du comportement des partitions. Configuration de DynamoDB (service web) Pour utiliser le service web DynamoDB : 1. Inscrivez-vous à AWS (p. 49) 2. Obtenir votre ID de clé d'accès AWS et votre clé secrète (p. 49) (utilisé pour accéder à DynamoDB par programme). Note Si vous avez l'intention de n'interagir avec DynamoDB qu'avec la console DynamoDB, vous n'avez pas besoin d'ID de clé d'accès ou d'une clé d'accès secrète. Vous pouvez donc passer directement à la section Utilisation de la console (p. 51). Inscrivez-vous à AWS Pour utiliser DynamoDB, vous avez besoin d'un compte AWS. Si vous n'en avez pas déjà un, vous serez invité à en créer un lors de l'inscription. Les services AWS auxquels vous êtes inscrits ne vous sont pas facturés, à moins que vous ne les utilisiez. Pour s'inscrire sur AWS 1. Ouvrez https://aws.amazon.com/, puis choisissez Create an AWS Account. 2. Suivez les instructions en ligne. Dans le cadre de la procédure d'inscription, vous recevrez un appel téléphonique et vous saisirez un code PIN en utilisant le clavier numérique du téléphone. Obtenir votre ID de clé d'accès AWS et votre clé secrète Avant de pouvoir utiliser le service web DynamoDB, vous devrez obtenir votre clé d'accès et votre clé secrète AWS. API Version 2012-08-10 49 Amazon DynamoDB Manuel du développeur Obtenir votre ID de clé d'accès AWS et votre clé secrète Pour obtenir vos ID de clé d'accès et clé d'accès secrète Les clés d'accès se composent d'un ID de clé d'accès et d'une clé d'accès secrète, qui permettent de signer les demandes par programme auprès des services AWS. Si vous n'avez pas de clés d'accès, vous pouvez les créer en utilisant la AWS Management Console. Nous vous recommandons d'utiliser des clés d'accès IAM au lieu des clés d'accès du compte racine AWS. IAM vous permet de contrôler en toute sécurité l'accès aux services et ressources AWS dans votre compte AWS. Note Pour créer des clés d'accès, vous devez disposer des autorisations permettant d'effectuer les opérations IAM nécessaires. Pour plus d'informations, consultez Octroi de l'autorisation utilisateur pour gérer la politique de mot de passe et les informations d'identification dans le IAM Guide de l'utilisateur. 1. Ouvrez la console IAM. 2. Dans le volet de navigation, sélectionnez Users. 3. 4. Choisissez votre nom d'utilisateur IAM (pas la case à cocher). Choisissez l'onglet Informations d'identification de sécurité, puis Créer une clé d'accès. 5. Pour voir votre clé d'accès, choisissez Afficher les informations d'identification de sécurité utilisateur. Vos informations d'identification s'afficheront comme suit : • ID de clé d'accès : AKIAIOSFODNN7EXAMPLE • Clé d'accès secrète : wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY 6. Choisissez Télécharger les informations d'identification, puis stockez les clés à un emplacement sûr. Votre clé secrète ne sera plus disponible via la AWS Management Console ;vous ne disposerez que d'une copie. Préservez sa confidentialité afin de protéger votre compte et ne l'envoyez jamais par e-mail. Ne le divulguez à personne hors de votre entreprise, même si vous recevez une requête qui semble provenir de AWS ou de toute autre personne travaillant chez Amazon. Aucun véritable représentant d’Amazon ne vous demandera jamais de lui fournir votre clé secrète. Voir aussi • Qu'est-ce qu'IAM ? du manuel IAM Guide de l'utilisateur • Informations d'identification de sécurité AWS dans AWS General Reference API Version 2012-08-10 50 Amazon DynamoDB Manuel du développeur Utilisation de la console Accès à DynamoDB Vous pouvez accéder à DynamoDB à l'aide de la console, de l'interface de ligne de commande ou de l'API. Rubriques • Utilisation de la console (p. 51) • Utilisation de l'interface de ligne de commande (p. 59) • Utilisation de l'API (p. 62) Utilisation de la console Vous pouvez accéder à AWS Management Console DynamoDB ici : https://console.aws.amazon.com/ dynamodb/home. Elle vous permet d'effectuer les opérations suivantes : • Créer, mettre à jour et supprimer des tables. Le calculateur de débit vous fournit des estimations sur le nombre d'unités de capacité que vous devez demander en fonction des informations d'utilisation que vous fournissez. • Afficher les éléments stockés dans une table, et ajouter, mettre à jour et supprimer des éléments. • Interroger une table. • Définir des alarmes pour surveiller l'utilisation de la capacité de votre table. • Afficher les principales métriques de supervision de votre table sur les graphiques en temps réel de CloudWatch. • Afficher les alarmes configurées pour chaque table et créer des alarmes personnalisées. La console affiche un écran d'introduction qui vous invite à créer votre première table. API Version 2012-08-10 51 Amazon DynamoDB Manuel du développeur Utilisation de la console Vous pouvez trouver les étapes détaillées de la création d'une table dans la console dans Création de tables et chargement d'exemples de données (p. 167). Pour afficher les tables, dans le volet de navigation sur le côté gauche de la console, choisissez Tables. Pour utiliser les éléments, choisissez l'un des noms de table, puis l'onglet Items. Vous pouvez aussi interroger la table ici. Pour de plus amples informations, veuillez consulter Utilisation des éléments et des attributs (p. 53). API Version 2012-08-10 52 Amazon DynamoDB Manuel du développeur Utilisation des éléments et des attributs Utilisation des éléments et des attributs Rubriques • Ajout d'un élément (p. 53) • Suppression d'un élément (p. 55) • Mise à jour d'un élément (p. 56) • Copie d'un élément (p. 56) Vous pouvez utiliser la console DynamoDB pour ajouter, modifier et supprimer des éléments dans une table. Ajout d'un élément 1. Dans le volet de navigation sur le côté gauche de la console, choisissez Tables. 2. Choisissez le nom de table souhaité, puis sélectionnez l'onglet Items. Dans la capture d'écran suivante, la table Reply s'affiche. 3. Choisissez Create Item. La fenêtre Create item vous permet d'entrer les valeurs requises d'attribut de clé primaire. Si la table a des index secondaires, vous devez aussi entrer les valeurs de clé primaire des index. La capture d'écran suivante affiche les attributs de clé primaires de la table Reply (Id et ReplyDateTime). Comme il existe un index secondaire global sur la table (PostedBy-MessageIndex), ses attributs de clé primaire sont également requis (PostedBy et Message). API Version 2012-08-10 53 Amazon DynamoDB Manuel du développeur Utilisation des éléments et des attributs 4. Si vous souhaitez ajouter d'autres attributs, sélectionnez le menu Action à gauche de Message. Dans le menu Action, sélectionnez Append, puis choisissez le type de données que vous voulez. API Version 2012-08-10 54 Amazon DynamoDB Manuel du développeur Utilisation des éléments et des attributs Tapez le nouveau nom d'attribut et la valeur dans les champs fournis. Répétez cette étape aussi souvent que nécessaire si vous souhaitez ajouter davantage d'attributs. 5. Lorsque l'élément est tel que vous le souhaitez, cliquez sur Save pour ajouter le nouvel élément à la table. Suppression d'un élément 1. Dans le volet de navigation sur le côté gauche de la console, choisissez Tables. 2. Choisissez le nom de table souhaité, puis sélectionnez l'onglet Items. 3. Sélectionnez un ou plusieurs éléments que vous voulez supprimer, puis choisissez Actions | Delete. API Version 2012-08-10 55 Amazon DynamoDB Manuel du développeur Utilisation des éléments et des attributs 4. Dans la boîte de dialogue Delete Item?, choisissez Yes, Delete. Mise à jour d'un élément 1. Dans le volet de navigation sur le côté gauche de la console, choisissez Tables. 2. Choisissez le nom de table souhaité, puis sélectionnez l'onglet Items. 3. Sélectionnez l'élément que vous souhaitez mettre à jour, puis choisissez Actions | Edit. 4. Dans la fenêtre Edit Item, modifiez les attributs ou valeurs souhaités. 5. Lorsque l'élément est tel que vous le souhaitez, choisissez Save pour écrire l'élément dans la table. Copie d'un élément Vous pouvez prendre un élément existant, le copier et enregistrer l'élément copié avec une nouvelle clé primaire. 1. Dans le volet de navigation sur le côté gauche de la console, choisissez Tables. 2. Choisissez le nom de table souhaité, puis sélectionnez l'onglet Items. API Version 2012-08-10 56 Amazon DynamoDB Manuel du développeur Surveillance des tables 3. Sélectionnez l'élément que vous souhaitez copier, puis choisissez Actions | Duplicate. 4. Dans la fenêtre Copy Item, modifiez les attributs ou valeurs souhaités. Vous devez choisir des valeurs différentes pour les attributs de clé primaire des tables. S'il existe des index secondaires, vous devez choisir aussi les valeurs des attributs de clé primaire des index. 5. Lorsque l'élément est tel que vous le souhaitez, choisissez Save pour écrire l'élément dans la table. Surveillance des tables Pour afficher les métriques CloudWatch de la table sélectionnée, choisissez l'onglet Métriques . Vous pouvez choisir n'importe quel graphique pour explorer en détail la métrique de votre choix. La page Metrics fournit un résumé des performances de la table lisible en un coup d'œil. Si vous souhaitez afficher d'autres métriques associées à la table, choisissez View all CloudWatch metrics pour accéder à la console CloudWatch. API Version 2012-08-10 57 Amazon DynamoDB Manuel du développeur Configuration des alarmes CloudWatch Pour plus d'informations sur les métriques CloudWatch pour DynamoDB, consultez Supervision de Amazon DynamoDB (p. 501). Configuration des alarmes CloudWatch Vous pouvez utiliser la console DynamoDB pour créer et gérer les alarmes CloudWatch pour votre table. Les alarmes CloudWatch peuvent vous informer des événements qui peuvent nécessiter votre attention, telles qu'une table dépassant ses valeurs de débit provisionné pendant une période de temps continue. Pour utiliser les alarmes CloudWatch pour votre table, choisissez l'onglet Alarms. Sur cette page, vous pouvez modifier toute alarme CloudWatch de votre table, ou choisissez Create alarm pour créer une alarme CloudWatch. L'alarme CloudWatch est déclenchée quand une métrique CloudWatch spécifique atteint un seuil pendant une durée donnée. Pour plus d'informations sur la configuration des alarmes, consultez l'aide CloudWatch dans la console CloudWatch ou accédez à la documentation CloudWatch. Gestion de Flux DynamoDB et des déclencheurs Vous pouvez activer ou désactiver Flux DynamoDB sur une table. Pour ce faire, accédez à l'onglet Overview, puis choisissez Manage Stream. API Version 2012-08-10 58 Amazon DynamoDB Manuel du développeur Utilisation de l'interface de ligne de commande Note Pour plus d'informations sur Flux DynamoDB et les déclencheurs AWS Lambda, consultez Capture d'activité Table avec Flux DynamoDB (p. 430). La fenêtre Manage Stream vous permet d'activer un flux pour cette table. Elle vous permet aussi de choisir le niveau de détail sur les modifications de données qui s'affichent dans le flux. Si la table a déjà un flux activé, la fenêtre Manage Stream vous permet de le désactiver. L'onglet Triggers vous permet d'associer une fonction AWS Lambda au flux de votre table (s'il est activé). Utilisez cet onglet pour sélectionner une fonction Lambda existante (ou créer une nouvelle fonction) qui sera appelée chaque fois que des événements d'intérêt apparaissent dans le flux de la table. Utilisation de l'interface de ligne de commande Vous pouvez utiliser l'AWS Command Line Interface (AWS CLI) pour contrôler plusieurs services AWS à partir de la ligne de commande et les automatiser à l'aide de scripts. Vous pouvez utiliser le AWS API Version 2012-08-10 59 Amazon DynamoDB Manuel du développeur Téléchargement et configuration de la AWS CLI CLI pour les opérations ad hoc, telles que la création d'une table. Vous pouvez également l'utiliser pour intégrer les opérations DynamoDB au sein des scripts utilitaires. Avant de configurer l'interface de ligne de commande AWS sur votre ordinateur, veillez à obtenir en premier lieu l'ID de clé d'accès et la clé secrète AWS. Pour de plus amples informations, veuillez consulter Obtenir votre ID de clé d'accès AWS et votre clé secrète (p. 49). Pour obtenir une liste complète de toutes les commandes disponibles dans l'AWS CLI DynamoDB, accédez à http://docs.aws.amazon.com/cli/latest/reference/dynamodb/index.html. Rubriques • Téléchargement et configuration de la AWS CLI (p. 60) • Utilisation de la AWS CLI avec DynamoDB (p. 60) • Utilisation de la AWS CLI avec DynamoDB téléchargeable (p. 61) Téléchargement et configuration de la AWS CLI L'AWS CLI est disponible à l'adresse http://aws.amazon.com/cli et s'exécutera sur les ordinateurs Windows, Mac ou Linux. Après avoir téléchargé l'AWS CLI, pour l'installer et la configurer : 1. Accédez au AWS Command Line Interface Guide de l'utilisateur. 2. Suivez les instructions d'Installation de l'interface de ligne de commande AWS et de Configuration de l'interface de ligne de commande AWS. Utilisation de la AWS CLI avec DynamoDB Le format de ligne de commande se compose d'un nom d'opération DynamoDB, suivi des paramètres pour cette opération. La AWS CLI prend en charge une version raccourcie de la syntaxe pour les valeurs des paramètres, ainsi que JSON. Par exemple, la commande suivante créera une table nommée Music. La clé de partition est Artist et la clé de tri est SongTitle. (Pour une lecture plus facile, les commandes longues dans cette section sont divisées en plusieurs lignes). aws dynamodb create-table \ --table-name Music \ --attribute-definitions \ AttributeName=Artist,AttributeType=S \ AttributeName=SongTitle,AttributeType=S \ --key-schema AttributeName=Artist,KeyType=HASH AttributeName=SongTitle,KeyType=RANGE \ --provisioned-throughput ReadCapacityUnits=1,WriteCapacityUnits=1 Les commandes suivantes ajouteront de nouveaux éléments à la table. Ces exemples utilisent une combinaison de la syntaxe raccourcie et de JSON. aws dynamodb put-item \ --table-name Music \ --item \ '{"Artist": {"S": "No One You Know"}, "SongTitle": {"S": "Call Me Today"}, "AlbumTitle": {"S": "Somewhat Famous"}}' \ --return-consumed-capacity TOTAL aws dynamodb put-item \ API Version 2012-08-10 60 Amazon DynamoDB Manuel du développeur Utilisation de la AWS CLI avec DynamoDB téléchargeable --table-name Music \ --item \ '{"Artist": {"S": "Acme Band"}, "SongTitle": {"S": "Happy Day"}, "AlbumTitle": {"S": "Songs About Life"}}' \ --return-consumed-capacity TOTAL aws dynamodb put-item \ --table-name Music \ --item '{ \ "Artist": {"S": "Acme Band"}, \ "SongTitle": {"S": "Happy Day"}, \ "AlbumTitle": {"S": "Songs About Life"} }' \ --return-consumed-capacity TOTAL Sur la ligne de commande, il peut être difficile de composer un JSON valide ; toutefois, la AWS CLI peut lire des fichiers JSON. Par exemple, imaginons l'extrait JSON suivant qui est stocké dans un fichier nommé key-conditions.json : { "Artist": { "AttributeValueList": [ { "S": "No One You Know" } ], "ComparisonOperator": "EQ" }, "SongTitle": { "AttributeValueList": [ { "S": "Call Me Today" } ], "ComparisonOperator": "EQ" } } Vous pouvez désormais émettre une demande de Query à l'aide de la AWS CLI. Dans cet exemple, le contenu du fichier key-conditions.json est utilisé pour le paramètre --key-conditions : aws dynamodb query --table-name Music --key-conditions file://keyconditions.json Pour plus de documentation sur l'utilisation de la AWS CLI avec DynamoDB, accédez à http:// docs.aws.amazon.com/cli/latest/reference/dynamodb/index.html. Utilisation de la AWS CLI avec DynamoDB téléchargeable La AWS CLI peut interagir avec DynamoDB en cours d'exécution sur votre ordinateur. Pour ce faire, ajoutez le paramètre --endpoint-url pour chaque commande : --endpoint-url http://localhost:8000 Voici un exemple d'utilisation de la AWS CLI pour répertorier les tables dans une base de données locale : API Version 2012-08-10 61 Amazon DynamoDB Manuel du développeur Utilisation de l'API aws dynamodb list-tables --endpoint-url http://localhost:8000 Si DynamoDB utilise un numéro de port autre que la valeur par défaut (8000), vous devrez modifier la valeur --endpoint-url en conséquence. Note L'interface de ligne de commande ne peut pas utiliser la version téléchargeable de DynamoDB comme point de terminaison par défaut ; par conséquent, vous devez spécifier --endpointurl avec chaque commande. Utilisation de l'API Vous pouvez utiliser AWS Management Console et l'interface de ligne de commande AWS pour utiliser DynamoDB interactivement. Cependant, pour tirer le meilleur parti de DynamoDB, vous pouvez écrire le code de l'application à l'aide du kit SDK AWS. Pour plus d'informations, consultez Programmation avec DynamoDB et les kits SDK AWS (p. 63). API Version 2012-08-10 62 Amazon DynamoDB Manuel du développeur Présentation de la prise en charge du kit SDK AWS pour DynamoDB Programmation avec DynamoDB et les kits SDK AWS Ce chapitre couvre les rubriques associées aux développeurs. Si vous souhaitez plutôt exécuter des exemples de code, consultez Exécution des exemples de code du Guide du développeur (p. 167). Rubriques • Présentation de la prise en charge du kit SDK AWS pour DynamoDB (p. 63) • Interfaces par programmation (p. 65) • API DynamoDB de bas niveau (p. 69) • Gestion des erreurs (p. 73) • Interfaces de programmation de niveau supérieur pour DynamoDB (p. 79) • Exécution des exemples de code du Guide du développeur (p. 167) Présentation de la prise en charge du kit SDK AWS pour DynamoDB Le schéma suivant fournit une présentation de haut niveau de la programmation d'applications DynamoDB avec les kits SDK AWS. API Version 2012-08-10 63 Amazon DynamoDB Manuel du développeur Présentation de la prise en charge du kit SDK AWS pour DynamoDB 1. Vous écrivez une application à l'aide d'un kit SDK AWS pour votre langage de programmation. Les kits SDK AWS sont disponibles pour une grande variété de langues. Pour obtenir la liste complète, consultez Outils d'Amazon Web Services. 2. Chaque kit SDK AWS fournit une ou plusieurs interfaces de programmation pour utiliser DynamoDB. Les interfaces spécifiques disponibles dépendent du langage de programmation et du kit SDK AWS que vous utilisez. 3. Le kit SDK AWS construit les requêtes HTTP(S) à utiliser avec l'API de bas niveau DynamoDB. 4. Le kit SDK AWS envoie la demande au point de terminaison DynamoDB. 5. DynamoDB exécute la demande. Si la demande est réussie, DynamoDB retourne un code de réponse HTTP 200 (OK). Si la demande a échoué, DynamoDB retourne un code d'erreur HTTP et un message d'erreur. 6. Le kit SDK AWS traite la réponse et la répercute sur votre application. Chacun des kits SDK AWS fournit des services importants à votre application, y compris les éléments suivants : • Mise en forme des requêtes HTTP(S) et sérialisation des paramètres de la demande. • Génération d'une signature de chiffrement pour chaque demande. • Transmission de la demande à un point de terminaison DynamoDB et réception des réponses à partir de DynamoDB. • Extraction des résultats à partir de ces réponses. • Mise en œuvre de la logique de base de nouvelle tentative en cas d'erreur. API Version 2012-08-10 64 Amazon DynamoDB Manuel du développeur Interfaces par programmation Vous n'avez pas besoin d'écrire le code pour aucune de ces tâches. Note Pour plus d'informations sur les kits SDK AWS, y compris les instructions d'installation et la documentation, consultez Outils d'Amazon Web Services. Interfaces par programmation Chaque kit SDK AWS fournit une ou plusieurs interfaces de programmation à utiliser avec DynamoDB. Ces interfaces s'étendent de wrappers DynamoDB simples de bas niveau aux couches de persistance orientées objet. Les interfaces disponibles varient selon le kit SDK AWS et le langage de programmation que vous utilisez. La section suivante met en évidence certaines interfaces disponibles, en utilisant le kit SDK AWS pour Java à titre d'exemple. (Toutes les interfaces ne sont pas disponibles dans tous les kits SDK AWS). Rubriques • Interfaces de bas niveau (p. 66) • Interfaces de document (p. 67) • Interface de persistance des objets (p. 67) API Version 2012-08-10 65 Amazon DynamoDB Manuel du développeur Interfaces de bas niveau Interfaces de bas niveau Chaque kit SDK AWS spécifique à un langage fournit une interface de bas niveau pour DynamoDB, avec des méthodes qui ressemblent étroitement aux demandes API DynamoDB de bas niveau. Dans certains cas, vous aurez besoin identifier les types de données des attributs à l'aide de data type descriptors (p. 72), tels que S pour string (chaîne) ou N pour number (nombre). Note Une interface de bas niveau est disponible dans chaque kit SDK AWS spécifique à un langage. Le programme Java suivant utilise l'interface de bas niveau du AWS SDK for Java. Le programme émet une demande GetItem pour une chanson de la table Music, puis affiche l'année où la chanson a paru. La classe com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient implémente l'interface de bas niveau DynamoDB. package com.amazonaws.codesamples; import java.util.HashMap; import import import import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient; com.amazonaws.services.dynamodbv2.model.AttributeValue; com.amazonaws.services.dynamodbv2.model.GetItemRequest; com.amazonaws.services.dynamodbv2.model.GetItemResult; public class MusicLowLevelDemo { public static void main(String[] args) { AmazonDynamoDBClient client = new AmazonDynamoDBClient(); HashMap<String, AttributeValue> key = new HashMap<String, AttributeValue>(); key.put("Artist", new AttributeValue().withS("No One You Know")); key.put("SongTitle", new AttributeValue().withS("Call Me Today")); GetItemRequest request = new GetItemRequest() .withTableName("Music") .withKey(key); try { GetItemResult result = client.getItem(request); if (result != null) { AttributeValue year = result.getItem().get("Year"); System.out.println("The song was released in " + year.getN()); } else { System.out.println("No matching song was found"); } } catch (Exception e) { System.err.println("Unable to retrieve data: "); System.err.println(e.getMessage()); } } API Version 2012-08-10 66 Amazon DynamoDB Manuel du développeur Interfaces de document } Interfaces de document De nombreux kits SDK AWS fournissent une interface de document, qui vous permet d'effectuer des opérations de plan de données (créer, lire, mettre à jour, supprimer) sur les tables et les index. Avec une interface de document, vous n'avez pas besoin de spécifier data type descriptors (p. 72) ; les types de données sont impliqués par la sémantique des données elles-mêmes. Les kits SDK AWS fournissent aussi des méthodes pour convertir facilement les documents JSON vers et depuis les types de données DynamoDB natifs. Note Les interfaces de document sont disponibles dans les kits SDK AWS pour Java, .NET, Node.js et JavaScript dans le navigateur. Le programme Java suivant utilise l'interface de document du AWS SDK for Java. Le programme crée un objet Table qui représente la table Music, puis demande ensuite à cet objet d'utiliser GetItem pour récupérer une chanson. Le programme affiche ensuite l'année où la chanson est sortie. La classe com.amazonaws.services.dynamodbv2.document.DynamoDB implémente l'interface de document DynamoDB. Remarquez comment DynamoDB agit comme wrapper autour du client de bas niveau (AmazonDynamoDBClient). package com.amazonaws.codesamples.gsg; import import import import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient; com.amazonaws.services.dynamodbv2.document.DynamoDB; com.amazonaws.services.dynamodbv2.document.GetItemOutcome; com.amazonaws.services.dynamodbv2.document.Table; public class MusicDocumentDemo { public static void main(String[] args) { AmazonDynamoDBClient client = new AmazonDynamoDBClient(); DynamoDB docClient = new DynamoDB(client); Table table = docClient.getTable("Music"); GetItemOutcome outcome = table.getItemOutcome( "Artist", "No One You Know", "SongTitle", "Call Me Today"); int year = outcome.getItem().getInt("Year"); System.out.println("The song was released in " + year); } } Interface de persistance des objets Certains kits SDK AWS offrent une interface de persistance des objets où vous n'effectuez pas directement les opérations du plan de données. A la place, vous créez les objets qui représentent les éléments des tables et des index DynamoDB, et interagissent uniquement avec ces objets. Cela vous permet d'écrire du code orienté objet, au lieu de code orienté base de données. API Version 2012-08-10 67 Amazon DynamoDB Manuel du développeur Interface de persistance des objets Note Les interfaces de persistance des objets sont disponibles dans les kits SDK AWS pour Java et .NET. Pour de plus amples informations, veuillez consulter Interfaces de programmation de niveau supérieur pour DynamoDB (p. 79). Le programme Java suivant utilise DynamoDBMapper, l'interface de persistance des objets du AWS SDK for Java. La classe MusicItem représente un élément de la table Music. package com.amazonaws.codesamples; import import import import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBAttribute; com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBHashKey; com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBRangeKey; com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTable; @DynamoDBTable(tableName="Music") public class MusicItem { private String artist; private String songTitle; private String albumTitle; private int year; @DynamoDBHashKey(attributeName="Artist") public String getArtist() { return artist;} public void setArtist(String artist) {this.artist = artist;} @DynamoDBRangeKey(attributeName="SongTitle") public String getSongTitle() { return songTitle;} public void setSongTitle(String songTitle) {this.songTitle = songTitle;} @DynamoDBAttribute(attributeName = "AlbumTitle") public String getAlbumTitle() { return albumTitle;} public void setAlbumTitle(String albumTitle) {this.albumTitle = albumTitle;} @DynamoDBAttribute(attributeName = "Year") public int getYear() { return year; } public void setYear(int year) { this.year = year; } } Vous pouvez ensuite instancier un objet MusicItem et récupérer une chanson à l'aide de la méthode load() de DynamoDBMapper. Le programme affiche ensuite l'année où la chanson est sortie. La classe com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper implémente l'interface de persistance des objets DynamoDB. Remarquez comment DynamoDBMapper agit comme wrapper autour du client de bas niveau (AmazonDynamoDBClient). package com.amazonaws.codesamples; import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient; import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper; public class MusicMapperDemo { public static void main(String[] args) { API Version 2012-08-10 68 Amazon DynamoDB Manuel du développeur API DynamoDB de bas niveau AmazonDynamoDBClient client = new AmazonDynamoDBClient(); DynamoDBMapper mapper = new DynamoDBMapper(client); MusicItem keySchema = new MusicItem(); keySchema.setArtist("No One You Know"); keySchema.setSongTitle("Call Me Today"); try { MusicItem result = mapper.load(keySchema); if (result != null) { System.out.println( "The song was released in "+ result.getYear()); } else { System.out.println("No matching song was found"); } } catch (Exception e) { System.err.println("Unable to retrieve data: "); System.err.println(e.getMessage()); } } } API DynamoDB de bas niveau Rubriques • Format des demandes (p. 71) • Format de la réponse (p. 71) • Descripteurs de type de données (p. 72) • Données numériques (p. 73) • Données binaires (p. 73) API Version 2012-08-10 69 Amazon DynamoDB Manuel du développeur API DynamoDB de bas niveau L'API de bas niveau DynamoDB est l'interface au niveau du protocole pour Amazon DynamoDB. A ce niveau, chaque requête HTTPs doit être correctement mise en forme et présenter une signature numérique valide. Les kits de développement logiciel (SDK) AWS construisent des demandes d'API DynamoDB de bas niveau en votre nom et traitent les réponses de DynamoDB. Vous pouvez ainsi vous concentrer sur la logique de votre application, et non sur les détails de bas niveau. Cependant, vous pouvez continuer à bénéficier de connaissances de base quant au fonctionnement de l'API DynamoDB de bas niveau. Pour plus d'informations sur l'API DynamoDB de bas niveau, consultez le manuel Amazon DynamoDB API Reference. Note Flux DynamoDB a sa propre API de bas niveau, distincte de celle de DynamoDB et entièrement prise en charge par les kits de développement logiciel (SDK) AWS. Pour de plus amples informations, veuillez consulter Capture d'activité Table avec Flux DynamoDB (p. 430). Pour les API Flux DynamoDB de bas niveau, consultez le manuel Référence de l'API Amazon DynamoDB Flux L'API DynamoDB de bas niveau utilise JSON (JavaScript Objet Notation) comme format de protocole filaire. JSON présentant les données selon une hiérarchie, les valeurs des données et la structure des données sont transmises en même temps. Les paires nom-valeur sont définies au format name:value. La hiérarchie des données est définie par les crochets imbriqués des paires nom-valeur. API Version 2012-08-10 70 Amazon DynamoDB Manuel du développeur Format des demandes DynamoDB utilise JSON uniquement comme protocole de transport, pas comme format de stockage. Les kits de développement logiciel (SDK) AWS utilisent JSON pour envoyer les données à DynamoDB et DynamoDB répond avec JSON, mais ne stocke pas les données de façon permanente au format JSON. Note Pour plus d'informations sur JSON, consultez Présentation de JSON sur le site web JSON.org. Format des demandes L'API DynamoDB de bas niveau accepte les requêtes HTTP(S) POST comme entrées. Les kits de développement logiciel (SDK) AWS construisent ces demandes pour vous. Supposons que vous ayez une table nommée Pets, avec un schéma de clé composé de AnimalType (clé de partition) et Name (clé de tri). Les deux attributs sont de type string (chaîne). Pour extraire un élément de Pets, le kit de développement logiciel (SDK) AWS construit une demande comme illustré ci-après : POST / HTTP/1.1 Host: dynamodb.<region>.<domain>; Accept-Encoding: identity Content-Length: <PayloadSizeBytes> User-Agent: <UserAgentString> Content-Type: application/x-amz-json-1.0 Authorization: AWS4-HMAC-SHA256 Credential=<Credential>, SignedHeaders=<Headers>, Signature=<Signature> X-Amz-Date: <Date> X-Amz-Target: DynamoDB_20120810.GetItem { "TableName": "Pets", "Key": { "AnimalType": {"S": "Dog"}, "Name": {"S": "Fido"} } } Notez ce qui suit à propos de cette demande : • L'en-tête Authorization contient les informations requises pour que DynamoDB authentifie la demande. Pour plus d'informations, consultez Signature de demandes d'API AWS et Processus de signature Signature version 4 dans le manuel Référence générale d'Amazon Web Services. • L'en-tête X-Amz-Target contient le nom d'une opération DynamoDB : GetItem. (On y trouve aussi la version de l'API de bas niveau, dans ce cas 20120810.) • La charge utile (corps) de la demande contient les paramètres de l'opération, au format JSON. Pour l'opération GetItem, les paramètres sont TableName et Key. Format de la réponse A la réception de la demande, DynamoDB la traite et renvoie une réponse. Pour la demande illustrée ci-dessus, la charge utile de la réponse HTTP(S) contient les résultats de l'opération, comme dans cet exemple : HTTP/1.1 200 OK API Version 2012-08-10 71 Amazon DynamoDB Manuel du développeur Descripteurs de type de données x-amzn-RequestId: <RequestId> x-amz-crc32: <Checksum> Content-Type: application/x-amz-json-1.0 Content-Length: <PayloadSizeBytes> Date: <Date> { "Item": { "Age": {"N": "8"}, "Colors": { "L": [ {"S": "White"}, {"S": "Brown"}, {"S": "Black"} ] }, "Name": {"S": "Fido"}, "Vaccinations": { "M": { "Rabies": { "L": [ {"S": "2009-03-17"}, {"S": "2011-09-21"}, {"S": "2014-07-08"} ] }, "Distemper": {"S": "2015-10-13"} } }, "Breed": {"S": "Beagle"}, "AnimalType": {"S": "Dog"} } } A ce stade, le kit de développement logiciel SDK AWS retourne les données de la réponse à votre application en vue de leur traitement. Note Si DynamoDB ne peut pas traiter une demande, il retourne un code d'erreur HTTP et un message. Le kit de développement logiciel (SDK) AWS les transmet à votre application, sous la forme d'exceptions. Pour de plus amples informations, veuillez consulter Gestion des erreurs (p. 73). Descripteurs de type de données Le protocole de l'API DynamoDB de bas niveau nécessite que chaque attribut soit accompagné d'un descripteur de type de données. Les descripteurs de type de données sont des jetons qui indiquent à DynamoDB comment interpréter chaque attribut. Les exemples de Format des demandes (p. 71)et Format de la réponse (p. 71) expliquent comment les descripteurs de type de données sont utilisés. La demande GetItem spécifie S pour les attributs du schéma de clé Pets (AnimalType et Name), qui sont de type string (chaîne). La réponse GetItem contient un élément Pets avec les attributs de type string (S), number (N), map (M) et list (L). La liste suivante est la liste complète des descripteurs de type de données DynamoDB : • S – String API Version 2012-08-10 72 Amazon DynamoDB Manuel du développeur Données numériques • N – Number • • • • • B – Binary BOOL – Boolean NULL – Null M – Map L – List • SS – String Set • NN – Number Set • BB – Binary Set Note Pour une description détaillée des types de données DynamoDB, consultez Type de données (p. 12). Données numériques Les différents langages de programmation offrent différents niveaux de prise en charge de JSON. Dans certains cas, vous pouvez décider d'utiliser une bibliothèque tierce pour la validation et l'analyse des documents JSON. Certaines bibliothèques tierces reposent sur le type de numéro JSON et fournissent leurs propres types, tels que int, long ou double. Toutefois, le type de données « number » natif dans DynamoDB ne correspondant pas exactement à ces autres types de données, ces distinctions de type peuvent entraîner des conflits. En outre, de nombreuses bibliothèques JSON ne gèrent pas les valeurs numériques de précision fixe et en déduisent automatiquement un type de données double pour les séquences numériques contenant une virgule. Pour résoudre ce problème, DynamoDB propose un seul type numérique sans perte de données. Pour éviter les conversions implicites non souhaitées en valeur double, DynamoDB utilise des chaînes pour le transfert de données de valeurs numériques. Cette approche offre une flexibilité pour la mise à jour des valeurs d'attribut tout en assurant la sémantique de tri appropriée, comme le placement des valeurs « 01 », « 2 » et « 03 » dans le bon ordre. Si la précision numérique est importante pour votre application, vous devez convertir des valeurs numériques en chaînes avant de les passer à DynamoDB. Données binaires DynamoDB prend en charge les attributs binaires. Cependant, JSON ne prend pas en charge en mode natif le codage binaire. Pour envoyer les données binaires dans une demande, vous devez les encoder au format Base64. A la réception de la demande, DynamoDB décode les données Base64 en binaire. Le schéma de codage Base64 utilisé par DynamoDB est décrit sur la page RFC 4648 du site web IETF (Internet Engineering Task Force). Gestion des erreurs Cette section décrit les erreurs d'exécution et la façon de les traiter. Elle décrit aussi les messages d'erreur et les codes spécifiques à DynamoDB. Rubriques • Composants erreur (p. 74) API Version 2012-08-10 73 Amazon DynamoDB Manuel du développeur Composants erreur • Codes et messages d'erreur (p. 74) • Gestion des erreurs dans votre application (p. 77) • Nouvelles tentatives après erreur et interruptions exponentielles (p. 77) • Opérations par lot et gestion des erreurs (p. 78) Composants erreur Lorsque votre programme envoie une demande, DynamoDB tente de la traiter. Si la demande aboutit, DynamoDB retourne un code d'état HTTP de succès (200 OK), ainsi que les résultats de l'opération demandée. Si la demande échoue, DynamoDB retourne une erreur. Chaque erreur possède trois composants : • Un code d'état HTTP (400, par exemple). • Un nom d'exception (ResourceNotFoundException, par exemple). • Un message d'erreur (Requested resource not found: Table: tablename not found, par exemple). Les kits SDK AWS prennent soin de répercuter les erreurs dans votre application, afin que vous puissiez prendre les mesures appropriées. Par exemple, dans un programme Java, vous pouvez écrire une logique try-catch de façon à gérer un ResourceNotFoundException. Si vous n'utilisez pas un SDK AWS, vous devez analyser le contenu de la réponse de bas niveau à partir de DynamoDB. Voici un exemple de réponse : HTTP/1.1 400 Bad Request x-amzn-RequestId: LDM6CJP8RMQ1FHKSC1RBVJFPNVV4KQNSO5AEMF66Q9ASUAAJG Content-Type: application/x-amz-json-1.0 Content-Length: 240 Date: Thu, 15 Mar 2012 23:56:23 GMT {"__type":"com.amazonaws.dynamodb.v20120810#ResourceNotFoundException", "message":"Requested resource not found: Table: tablename not found"} Codes et messages d'erreur Voici une liste des exceptions retournées par DynamoDB et regroupées par code d'état HTTP. Si OK to retry? a pour réponse Yes, vous pouvez soumettre à nouveau la même demande. Si OK to retry? a pour réponse No, vous devez résoudre le problème côté client avant de soumettre une nouvelle demande. Code d'état HTTP 400 Un code d'état HTTP 400 indique un problème avec votre demande, tel qu'un échec d'authentification, l'absence de paramètres requis ou le dépassement du débit provisionné d'une table. Vous devez corriger le problème dans votre application avant de soumettre à nouveau la demande. AccessDeniedException Message : Accès refusé. Le client n'a pas signé correctement la demande. Si vous utilisez un kit SDK AWS, les demandes sont signées automatiquement ; sinon, accédez au Processus de signature Signature Version 4 dans le AWS General Reference. OK pour réessayer ? Non API Version 2012-08-10 74 Amazon DynamoDB Manuel du développeur Codes et messages d'erreur ConditionalCheckFailedException Message : Echec de la demande conditionnelle. Vous avez spécifié une condition qui a été analysée comme false. Par exemple, il se peut que vous avez essayé d'effectuer une mise à jour conditionnelle sur un élément, mais que la valeur réelle de l'attribut ne corresponde pas à la valeur attendue de la condition. OK pour réessayer ? Non IncompleteSignatureException Message : La signature de la demande n'est pas conforme aux normes AWS. La signature de la demande ne comprenait pas tous les composants requis. Si vous utilisez un kit SDK AWS, les demandes sont signées automatiquement ; sinon, accédez au Processus de signature Signature Version 4 dans le AWS General Reference. OK pour réessayer ? Non ItemCollectionSizeLimitExceededException Message : Dépassement de taille de la collection. Pour une table avec un index secondaire local, un groupe d'éléments avec la même valeur de clé de partition a dépassé la limite de taille maximale de 10 Go. Pour plus d'informations sur les collections d'éléments, consultez Collections d'éléments (p. 395). OK pour réessayer ? Oui LimitExceededException Message : Beaucoup trop d'opérations pour un abonné donné. Il y a beaucoup trop d'opérations de contrôle simultanées. Le nombre cumulé de tables et d'index de l'état CREATING, DELETING ou UPDATING ne peut pas dépasser 10. OK pour réessayer ? Oui MissingAuthenticationTokenException Message : La demande doit comporter un ID de clé d'accès AWS valide (inscrit). La demande n'incluait pas l'en-tête d'autorisation obligatoire ou n'était pas correctement formée. Voir API DynamoDB de bas niveau (p. 69). OK pour réessayer ? Non ProvisionedThroughputExceededException Message : Vous avez dépassé le débit provisionné autorisé maximal pour une table ou pour un ou plusieurs index secondaires globaux. Pour afficher les métriques de performance du débit provisionné par rapport au débit consommé, ouvrez la console Amazon CloudWatch. Exemple : votre taux de demandes est trop élevé. Les kits SDK AWS pour DynamoDB réessaient automatiquement les demandes qui reçoivent cette exception. Votre demande finit par aboutir, à moins que la file d'attente des nouvelles tentatives soit trop grande pour être terminée. Réduisez la fréquence des demandes avec exponential backoff (p. 77). OK pour réessayer ? Oui ResourceInUseException Message : La ressource que vous essayez de modifier est en cours d'utilisation. API Version 2012-08-10 75 Amazon DynamoDB Manuel du développeur Codes et messages d'erreur Exemple : vous avez essayé de recréer une table existante ou de supprimer une table qui possède l'état CREATING. OK pour réessayer ? Non ResourceNotFoundException Message : La ressource demandée est introuvable. Exemple : la table demandée n'existe pas ou se trouve trop tôt dans l'état CREATING. OK pour réessayer ? Non ThrottlingException Message : Le taux de demandes dépasse le débit autorisé. Cette exception peut être retournée si vous effectuez l'une des opérations suivantes trop rapidement : CreateTable ; UpdateTable ; DeleteTable. OK pour réessayer ? Oui UnrecognizedClientException Message : L'ID de la clé d'accès ou le jeton de sécurité n'est pas valide. La signature de la demande est incorrecte. La cause la plus probable est une clé secrète ou un ID de clé d'accès AWS non valide. OK pour réessayer ? Oui ValidationException Message : variable selon les erreurs spécifiques rencontrées Cette erreur peut se produire pour différentes raisons, telles qu'un paramètre obligatoire absent, une valeur en dehors des limites ou une incompatibilité des données. Le message d'erreur contient des détails sur la partie spécifique de la demande qui a provoqué l'erreur. OK pour réessayer ? Non Code d'état HTTP 5xx Un code d'état HTTP 5xx indique un problème qui doit être résolu par Amazon Web Services. Il peut s'agir d'une erreur temporaire, auquel cas, vous pouvez retenter votre demande jusqu'à ce qu'elle aboutisse. Sinon, accédez au tableau de bord de l'état des services AWS pour voir si le service présente des problèmes de fonctionnement. Erreur de serveur interne (HTTP 500) DynamoDB n'a pas pu traiter votre demande. OK pour réessayer ? Oui Note Vous pouvez rencontrer des erreurs de serveur internes lorsque vous travaillez avec des éléments. Celles-ci sont attendues pendant la durée de vie d'une table. Toute demande en échec peut être relancée immédiatement. Service indisponible (HTTP 503) DynamoDB n'est pas disponible actuellement. (Il doit s'agir d'un état temporaire.) API Version 2012-08-10 76 Amazon DynamoDB Manuel du développeur Gestion des erreurs dans votre application OK pour réessayer ? Oui Gestion des erreurs dans votre application Pour que votre application fonctionne correctement, vous devez ajouter une logique destinée à capturer les erreurs et à y répondre. Les approches classiques incluent l'utilisation de blocs trycatch ou d'instructions if-then. Les kits SDK AWS effectuent leurs propres tentatives et contrôles d'erreur. Si vous rencontrez une erreur tout en utilisant l'un des kits SDK AWS, le code d'erreur et la description peuvent vous aider à la résoudre. Vous devez également voir un Request ID dans la réponse. L'Request ID peut être utile si vous devez utiliser le support AWS pour diagnostiquer un problème. L'extrait de code Java suivant tente de supprimer un élément d'une table DynamoDB et exécute une gestion rudimentaire des erreurs. (Dans ce cas, il suffit d'informer l'utilisateur que la demande a échoué). Table table = dynamoDB.getTable("Movies"); try { Item item = table.getItem("year", 1978, "title", "Superman"); if (item != null) { System.out.println("Result: " + item); } else { //No such item exists in the table System.out.println("Item not found"); } } catch (AmazonServiceException ase) { System.err.println("Could not complete operation"); System.err.println("Error Message: " + ase.getMessage()); System.err.println("HTTP Status: " + ase.getStatusCode()); System.err.println("AWS Error Code: " + ase.getErrorCode()); System.err.println("Error Type: " + ase.getErrorType()); System.err.println("Request ID: " + ase.getRequestId()); } catch (AmazonClientException ace) { System.err.println("Internal error occured communicating with DynamoDB"); System.out.println("Error Message: " + ace.getMessage()); } Dans cet extrait de code, la construction try-catch gère deux types différents d'exceptions : • AmazonServiceException : exception levée si la demande du client a été transmise correctement à DynamoDB, mais que ce dernier n'a pas pu la traiter et a renvoyé une réponse d'erreur à la place. • AmazonClientException : exception levée si le client n'a pas pu obtenir de réponse de la part d'un service ou s'il n'a pas pu analyser la réponse envoyée par un service. Nouvelles tentatives après erreur et interruptions exponentielles Un grand nombre de composants d'un réseau, tels que serveurs DNS, commutateurs, répartiteurs de charge ou autres, peuvent générer des erreurs à n'importe quel moment de la vie d'une requête API Version 2012-08-10 77 Amazon DynamoDB Manuel du développeur Opérations par lot et gestion des erreurs donnée. La technique habituelle pour traiter ces réponses erronées dans un environnement réseau consiste à implémenter les nouvelles tentatives dans l'application cliente. Cette technique augmente la fiabilité de l'application et réduit les coûts de fonctionnement pour le développeur. Chaque kit SDK AWS implémente automatiquement la logique des nouvelles tentatives. Vous pouvez modifier les paramètres de nouvelle tentative en fonction de vos besoins. Par exemple, imaginons une application Java nécessitant une stratégie d'interruption immédiate, sans autorisation de nouvelle tentative en cas d'erreur. Avec le AWS SDK for Java, vous pouvez utiliser la classe ClientConfiguration et fournir une valeur maxErrorRetry égale à 0 pour désactiver les nouvelles tentatives. Pour plus d'informations, consultez la documentation du kit SDK AWS de votre langage de programmation Si vous n'utilisez pas un kit SDK AWS, vous devez retenter les demandes originales qui reçoivent les erreurs serveur (5xx). Cependant, les erreurs client (4xx, autres qu'une exception ThrottlingException ou ProvisionedThroughputExceededException) indiquent que vous avez besoin de réviser la demande elle-même pour résoudre le problème avant de recommencer. Outre les nouvelles tentatives simples, chaque kit AWS SDK implémente un algorithme d'interruption exponentielle pour un meilleur contrôle des flux. Le concept sous-jacent vise à utiliser des temps d'attente progressivement plus longs entre les tentatives en cas de réponses d'erreur consécutives. Par exemple, jusqu'à 50 millisecondes avant la première nouvelle tentative, jusqu'à 100 millisecondes avant la deuxième, jusqu'à 200 millisecondes avant la troisième, et ainsi de suite. Cependant, après une minute, si la demande a échoué, le problème peut être que la taille de la demande entraîne un dépassement du débit provisionné, et ne pas être lié au taux de demandes. Définir le nombre maximal de nouvelles tentatives pour qu'elles s'arrêtent au bout d'une minute environ. Si la demande n'aboutit pas, vérifiez vos options de débit provisionné. Pour de plus amples informations, veuillez consulter Instructions pour l'utilisation des tables (p. 572). Note Les kits AWS SDK implémentent une logique de nouvelle tentative et une interruption exponentielle automatiques. La plupart des algorithmes d'interruption exponentielle utilisent l'instabilité (retard aléatoire) pour éviter les conflits successifs. Comme vous ne cherchez pas à éviter de tels conflits dans ces cas-là, vous n'avez pas besoin d'utiliser ce nombre aléatoire. Cependant, si vous utilisez les clients simultanés, l'instabilité peut aider à ce que vos demandes réussissent plus rapidement. Pour plus d'informations, consultez la publication de blog Interruption exponentielle et instabilité. Opérations par lot et gestion des erreurs L'API de bas niveau DynamoDB prend en charge les opérations par lot pour les lectures et les écritures. BatchGetItem lit les éléments d'une ou de plusieurs tables, et BatchWriteItem insère ou supprime des éléments dans une ou plusieurs tables. Ces opérations par lot sont implémentées comme wrappers autour des opérations DynamoDB autres que les opérations par lot. En d'autres termes, BatchGetItem appelle GetItem une fois pour chaque élément du lot. De même, BatchWriteItem appelle DeleteItem ou PutItem, le cas échéant, pour chaque élément du lot. Une opération par lot peut supporter la défaillance de requêtes individuelles dans le lot. Par exemple, imaginons une demande BatchGetItem de lecture de cinq éléments. Même si certaines demandes GetItem sous-jacentes échouent, il ne s'ensuit pas que l'ensemble de l'opération BatchGetItem échoue. En revanche, si toutes les cinq opérations de lecture échouent, la totalité de BatchGetItem échoue. Les opérations par lot retournent les informations sur les demandes individuelles qui échouent, de telle sorte que vous puissiez diagnostiquer le problème et réessayer l'opération. Pour BatchGetItem, les tables et les clés primaires en question sont retournés dans le paramètre UnprocessedKeys de la demande. Pour BatchWriteItem, les informations similaires sont retournées dans UnprocessedItems. API Version 2012-08-10 78 Amazon DynamoDB Manuel du développeur Interfaces de programmation de niveau supérieur pour DynamoDB La cause la plus probable d'un échec en lecture ou en écriture est la limitation. Pour BatchGetItem, une ou plusieurs tables de la demande par lot n'ont pas une capacité en lecture suffisamment provisionnée pour prendre en charge l'opération. Pour BatchWriteItem, une ou plusieurs des tables n'ont pas une capacité en écriture suffisamment provisionnée. Si DynamoDB retourne tous les éléments non traités, vous devez recommencer l'opération par lot sur ces éléments. Cependant, nous vous recommandons vivement d'utiliser un algorithme d'interruption exponentielle. Si vous recommencez immédiatement l'opération par lot, les demandes en lecture ou en écriture sous-jacentes peuvent continuer à échouer en raison de la limitation sur les tables individuelles. Si vous retardez l'opération par lot à l'aide d'une interruption exponentielle, il est très vraisemblable que les demandes du lot réussiront. Interfaces de programmation de niveau supérieur pour DynamoDB Les AWS SDK offrent des applications avec des interfaces de bas niveau à utiliser avec Amazon DynamoDB. Ces méthodes et classes côté client correspondent directement à l'API DynamoDB de bas niveau. Cependant, de nombreux développeurs expérimentent un sentiment de déconnexion, ou de « discordance d'impédance », lorsqu'ils ont besoin mapper des types de données complexes avec des éléments dans une table de base de données. Avec une interface de base de données de bas niveau, les développeurs doivent écrire des méthodes pour la lecture ou l'écriture de données d'objet sur des tables de base de données, et inversement. La quantité de code supplémentaire nécessaire pour chaque combinaison de table de base de données et de type d'objet peut sembler insurmontable. Pour simplifier le développement, les AWS SDK pour Java et .NET fournissent des interfaces supplémentaires avec des niveaux plus élevés d'abstraction. Les interfaces de niveau supérieur pour DynamoDB vous permettent de définir les relations entre les objets de votre programme et les tables de base de données qui stockent les données de ces objets. Une fois que vous avez défini ce mappage, vous appelez les méthodes d'objet simple comme save, load ou delete, et les opérations DynamoDB de bas niveau sous-jacentes sont automatiquement appelées en votre nom. Cela vous permet d'écrire du code orienté objet, au lieu de code orienté base de données. Les interfaces de programmation de niveau supérieur pour DynamoDB sont disponibles dans les AWS SDK pour Java et .NET. Java • Java : DynamoDBMapper (p. 79) .NET • .NET : Modèle de document (p. 117) • .NET : modèle de persistance des objets (p. 140) Java : DynamoDBMapper Rubriques • Types de données pris en charge (p. 82) • Annotations Java pour DynamoDB (p. 83) • La classe DynamoDBMapper (p. 88) • Paramètres de configuration facultatifs pour DynamoDBMapper (p. 95) • Exemple : opérations CRUD (p. 96) API Version 2012-08-10 79 Amazon DynamoDB Manuel du développeur Java : DynamoDBMapper • Exemple : Opérations d'écriture par lots (p. 99) • Exemple : Interroger et analyser (p. 104) • Verrouillage optimiste avec numéro de version (p. 112) • Mappage des données arbitraires (p. 113) Le AWS SDK for Java fournit une classe DynamoDBMapper, ce qui vous permet de mapper vos classes côté client avec les tables DynamoDB. Pour utiliser DynamoDBMapper, vous définissez la relation entre des éléments d'une table DynamoDB et leurs instances d'objet correspondantes dans votre code. La classe DynamoDBMapper vous permet d'accéder à vos tables, d'effectuer diverses opérations de création, de lecture, de mise à jour et de suppression des opérations (CRUD) et d'exécuter des requêtes. Note La classe DynamoDBMapper ne vous permet pas de créer, de mettre à jour ou de supprimer des tables. Pour effectuer ces tâches, utilisez à la place l'interface SDK pour Java de bas niveau. Pour de plus amples informations, veuillez consulter Utilisation des tables : Java (p. 187). Le SDK pour Java fournit un ensemble de types d'annotations, afin que vous puissiez mapper vos classes avec des tables. Par exemple, imaginons une table ProductCatalog ayant Id en tant que clé de partition. ProductCatalog(Id, ...) Vous pouvez mapper une classe de votre application client avec la table ProductCatalog, comme illustré dans le code Java suivant. Cet extrait de code définit un objet Java ancien brut (POJO) nommé CatalogItem, qui utilise des annotations pour mapper des champs d'objet avec des noms d'attributs DynamoDB : package com.amazonaws.codesamples; import java.util.Set; import import import import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBAttribute; com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBHashKey; com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBIgnore; com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTable; @DynamoDBTable(tableName="ProductCatalog") public class CatalogItem { private private private private private Integer id; String title; String ISBN; Set<String> bookAuthors; String someProp; @DynamoDBHashKey(attributeName="Id") public Integer getId() { return id;} public void setId(Integer id) {this.id = id;} @DynamoDBAttribute(attributeName="Title") public String getTitle() {return title; } public void setTitle(String title) { this.title = title; } API Version 2012-08-10 80 Amazon DynamoDB Manuel du développeur Java : DynamoDBMapper @DynamoDBAttribute(attributeName="ISBN") public String getISBN() { return ISBN; } public void setISBN(String ISBN) { this.ISBN = ISBN; } @DynamoDBAttribute(attributeName = "Authors") public Set<String> getBookAuthors() { return bookAuthors; } public void setBookAuthors(Set<String> bookAuthors) { this.bookAuthors = bookAuthors; } @DynamoDBIgnore public String getSomeProp() { return someProp;} public void setSomeProp(String someProp) {this.someProp = someProp;} } Dans le code précédent, l'annotation @DynamoDBTable mappe la classe CatalogItem avec la table ProductCatalog. Vous pouvez stocker des instances de classe individuelles en tant qu'éléments dans la table. Dans la définition de classe, l'annotation @DynamoDBHashKey mappe l'Id de propriété avec la clé primaire. Par défaut, les propriétés de classe mappent avec les mêmes attributs de nom dans la table. Les propriétés Title et ISBN mappent avec les mêmes attributs de nom dans la table. Si vous définissez un nom de propriété de classe qui ne correspond pas à un nom d'attribut d'élément correspondant, vous devez alors ajouter explicitement l'annotation @DynamoDBAttribute pour spécifier le mappage. Dans l'exemple précédent, l'annotation @DynamoDBAttribute est ajoutée à chaque propriété afin de garantir que les noms de propriété correspondent exactement aux tables créées dans Création de tables et chargement d'exemples de données (p. 167) et d'assurer la cohérence avec les noms d'attributs utilisés dans d'autres exemples de code dans ce guide. Votre définition de classe peut avoir des propriétés qui ne mappent avec aucun attribut de la table. Vous identifiez ces propriétés en ajoutant l'annotation @DynamoDBIgnore. Dans l'exemple précédent, la propriété SomeProp est marquée avec l'annotation @DynamoDBIgnore. Lorsque vous téléchargez une instance CatalogItem vers la table, votre instance DynamoDBMapper n'inclut pas de propriété SomeProp. En outre, l'outil de mappage ne retourne pas cet attribut lorsque vous récupérez un élément de la table. Une fois que vous avez défini votre classe de mappage, vous pouvez utiliser des méthodes DynamoDBMapper pour écrire une instance de cette classe d'un élément correspondant dans la table Catalog. L'extrait de code suivant illustre cette technique : AmazonDynamoDBClient client = new AmazonDynamoDBClient(new ProfileCredentialsProvider()); DynamoDBMapper mapper = new DynamoDBMapper(client); CatalogItem item = new CatalogItem(); item.setId(102); item.setTitle("Book 102 Title"); item.setISBN("222-2222222222"); item.setBookAuthors(new HashSet<String>(Arrays.asList("Author 1", "Author 2"))); item.setSomeProp("Test"); mapper.save(item); L'extrait de code suivant montre comment récupérer l'élément et accéder à certains de ses attributs : CatalogItem partitionKey = new CatalogItem(); API Version 2012-08-10 81 Amazon DynamoDB Manuel du développeur Java : DynamoDBMapper partitionKey.setId(102); DynamoDBQueryExpression<CatalogItem> queryExpression = new DynamoDBQueryExpression<CatalogItem>() .withHashKeyValues(partitionKey); List<CatalogItem> itemList = mapper.query(CatalogItem.class, queryExpression); for (int i = 0; i < itemList.size(); i++) { System.out.println(itemList.get(i).getTitle()); System.out.println(itemList.get(i).getBookAuthors()); } DynamoDBMapper offre un moyen intuitif, naturel de travailler avec des données DynamoDB au sein de Java. Il offre aussi un certain nombre de fonctionnalités intégrées telles que le verrouillage optimiste, les valeurs de clé de tri et de clé de partition générées automatiquement et la version d'objet. Types de données pris en charge Cette section décrit les types de données arbitraires, les collections et les types de données Java primitifs pris en charge. DynamoDB prend en charge les classes wrapper primitives et les types de données primitifs suivants. • String • Boolean, boolean • Byte, byte • Date (en tant que chaîne de précision à la milliseconde ISO8601, passée sur UTC) • Calendar (en tant que chaîne de précision à la milliseconde ISO8601, passée sur UTC) • Long, long • Integer, int • Double, double • Float, float • BigDecimal • BigInteger DynamoDB prend en charge les types de collection Set Java. Si votre propriété de collection mappée n'est pas un Set, une exception est alors levée. La table suivante résume comment les types Java précédents mappent avec les types DynamoDB. Type Java Type DynamoDB Tous les types de numéro N (type Number) Chaînes S (type String) Booléen N (type Number), 0 ou 1. Sinon, vous pouvez utiliser @DynamoDBNativeBooleanType pour mapper un Boolean Java avec le type de données BOOL DynamoDB. Pour de plus amples informations, veuillez consulter Annotations Java pour DynamoDB (p. 83).) API Version 2012-08-10 82 Amazon DynamoDB Manuel du développeur Java : DynamoDBMapper Type Java Type DynamoDB ByteBuffer B (type Binary) Date S (type String). Les valeurs Date sont stockées comme chaînes formatées ISO-8601. Types de collections Set Type SS (string set), type NS (number set) ou type BS (binary set). Le SDK pour Java prend également en charge le mappage de type de données arbitraires pour DynamoDB. Par exemple, vous pouvez définir vos propres types complexes sur le client. Vous utilisez l'interface DynamoDBMarshaller et l'annotation @DynamoDBMarshalling pour le type complexe pour décrire le mappage (Mappage des données arbitraires (p. 113)). Annotations Java pour DynamoDB Cette section décrit les annotations qui sont disponibles pour le mappage de vos classes et de vos propriétés avec des tables et des attributs. Pour la documentation Javadoc correspondante, consultez Annotation Types Summary dans AWS SDK for Java API Reference. Note Dans les annotations suivantes, seules DynamoDBTable et DynamoDBHashKey sont obligatoires. Rubriques • DynamoDBAttribute (p. 83) • DynamoDBAutoGeneratedKey (p. 84) • DynamoDBDocument (p. 84) • DynamoDBHashKey (p. 86) • DynamoDBIgnore (p. 86) • DynamoDBIndexHashKey (p. 86) • DynamoDBIndexRangeKey (p. 86) • DynamoDBMarshalling (p. 86) • DynamoDBNativeBoolean (p. 86) • DynamoDBRangeKey (p. 87) • DynamoDBTable (p. 88) • DynamoDBVersionAttribute (p. 88) DynamoDBAttribute Mappe une propriété avec un attribut de table. Par défaut, chaque propriété de classe mappe un attribut d'élément avec le même nom. Toutefois, si les noms ne sont pas les mêmes, vous pouvez utiliser cette annotation pour mapper une propriété avec l'attribut. Dans l'extrait Java suivant, l'DynamoDBAttribute mappe la propriété BookAuthors avec le nom d'attribut Authors de la table. @DynamoDBAttribute(attributeName = "Authors") API Version 2012-08-10 83 Amazon DynamoDB Manuel du développeur Java : DynamoDBMapper public List<String> getBookAuthors() { return BookAuthors; } public void setBookAuthors(List<String> BookAuthors) { this.BookAuthors = BookAuthors; } Le DynamoDBMapper utilise Authors en tant que nom d'attribut lors de l'enregistrement de l'objet vers la table. DynamoDBAutoGeneratedKey Marque une propriété de clé de tri ou de clé de partition comme étant générée automatiquement. DynamoDBMapper va générer un UUID aléatoire lors de l'enregistrement de ces attributs. Seules les propriétés String peuvent être marquées en tant que clés générées automatiquement. L'extrait suivant illustre l'utilisation de clés générées automatiquement. @DynamoDBTable(tableName="AutoGeneratedKeysExample") public class AutoGeneratedKeys { private String id; private String payload; @DynamoDBHashKey(attributeName = "Id") @DynamoDBAutoGeneratedKey public String getId() { return id; } public void setId(String id) { this.id = id; } @DynamoDBAttribute(attributeName="payload") public String getPayload() { return this.payload; } public void setPayload(String payload) { this.payload = payload; } public static void saveItem() { AutoGeneratedKeys obj = new AutoGeneratedKeys(); obj.setPayload("abc123"); // id field is null at this point DynamoDBMapper mapper = new DynamoDBMapper(dynamoDBClient); mapper.save(obj); System.out.println("Object was saved with id " + obj.getId()); } } DynamoDBDocument Indique qu'une classe peut être sérialisée sous forme de document DynamoDB. Par exemple, supposons que vous vouliez mapper un document JSON avec un attribut DynamoDB de type Map (M). L'extrait de code suivant définit un élément contenant un attribut imbriqué de type de Map. public class ProductCatalogItem { private Integer id; //partition key private Pictures pictures; /* ...other attributes omitted... */ @DynamoDBHashKey(attributeName="Id") public Integer getId() { return id;} API Version 2012-08-10 84 Amazon DynamoDB Manuel du développeur Java : DynamoDBMapper public void setId(Integer id) {this.id = id;} @DynamoDBAttribute(attributeName="Pictures") public Pictures getPictures() { return pictures;} public void setPictures(Pictures pictures) {this.pictures = pictures;} // Additional properties go here. @DynamoDBDocument public static class Pictures { private String frontView; private String rearView; private String sideView; @DynamoDBAttribute(attributeName = "FrontView") public String getFrontView() { return frontView; } public void setFrontView(String frontView) { this.frontView = frontView; } @DynamoDBAttribute(attributeName = "RearView") public String getRearView() { return rearView; } public void setRearView(String rearView) { this.rearView = rearView; } @DynamoDBAttribute(attributeName = "SideView") public String getSideView() { return sideView; } public void setSideView(String sideView) { this.sideView = sideView; } } } Vous pouvez alors enregistrer un nouvel élément ProductCatalog, avec Pictures, comme illustré dans l'extrait suivant : ProductCatalogItem item = new ProductCatalogItem(); Pictures pix = new Pictures(); pix.setFrontView("http://example.com/products/206_front.jpg"); pix.setRearView("http://example.com/products/206_rear.jpg"); pix.setSideView("http://example.com/products/206_left_side.jpg"); item.setPictures(pix); item.setId(123); mapper.save(item); L'élément ProductCatalog qui en résulte se présente comme suit (au format JSON) : { "Id" : 123 "Pictures" : { "SideView" : "http://example.com/products/206_left_side.jpg", "RearView" : "http://example.com/products/206_rear.jpg", "FrontView" : "http://example.com/products/206_front.jpg" } } API Version 2012-08-10 85 Amazon DynamoDB Manuel du développeur Java : DynamoDBMapper DynamoDBHashKey Mappe une propriété de classe avec la clé de partition de la table. La propriété doit être un des types binaire, numéro ou chaîne scalaire ; elle ne peut pas être un type collection. Supposons que vous ayez une table, ProductCatalog, qui a un Id en tant que clé primaire. L'extrait de code Java suivant définit une classe CatalogItem et mappe sa propriété Id avec la clé primaire de la table ProductCatalog à l'aide de la balise @DynamoDBHashKey. @DynamoDBTable(tableName="ProductCatalog") public class CatalogItem { private Integer Id; @DynamoDBHashKey(attributeName="Id") public Integer getId() { return Id; } public void setId(Integer Id) { this.Id = Id; } // Additional properties go here. } DynamoDBIgnore Indique à l'instance DynamoDBMapper que la propriété associée doit être ignorée. Lors de l'enregistrement de données dans la table, DynamoDBMapper ne sauvegarde pas cette propriété dans la table. DynamoDBIndexHashKey Mappe une propriété de classe avec la clé de partition d'un index secondaire global. La propriété doit être un des types binaire, numéro ou chaîne scalaire ; elle ne peut pas être un type collection. Utilisez cette annotation si vous devez Query un index secondaire global. Vous devez spécifier le nom d'index (globalSecondaryIndexName). Si le nom de la propriété de classe est différent de la clé de partition d'index, vous devez également spécifier le nom de cet attribut d'index (attributeName). DynamoDBIndexRangeKey Mappe une propriété de classe avec la clé de tri d'un index secondaire global ou d'un local secondary index. La propriété doit être un des types binaire, numéro ou chaîne scalaire ; elle ne peut pas être un type collection. Utilisez cette annotation si vous avez besoin de Query un local secondary index ou un index secondaire global et que vous souhaitez affiner vos résultats à l'aide de la clé de tri d'index. Vous devez spécifier le nom d'index (soit globalSecondaryIndexName, soit localSecondaryIndexName). Si le nom de la propriété de classe est différent de la clé de tri d'index, vous devez également spécifier le nom de cet attribut d'index (attributeName). DynamoDBMarshalling Identifie une propriété de classe qui utilise un marshaleur personnalisé. Lorsqu'elle est utilisée avec la classe DynamoDBMarshaller, cette annotation vous permet de mapper vos propres types de données arbitraires avec un type de données pris en charge en mode natif par DynamoDB. Pour de plus amples informations, veuillez consulter Mappage des données arbitraires (p. 113). DynamoDBNativeBoolean Indique qu'un attribut boolean (ou Boolean) d'une classe doit être géré en tant que type de données BOOL DynamoDB natif. API Version 2012-08-10 86 Amazon DynamoDB Manuel du développeur Java : DynamoDBMapper Par exemple, un CatalogItem pourrait être utilisé pour mapper des éléments avec la table ProductCatalog. Pour affecter un modèle booléen à un de ses attributs (InStock), vous pouvez utiliser l'annotation DynamoDBNativeBoolean comme suit : @DynamoDBTable(tableName="ProductCatalog") public class CatalogItem { private String Id; private Boolean inStock; @DynamoDBHashKey(attributeName="Id") // Getters and setters for Id go here @DynamoDBNativeBoolean @DynamoDBAttribute(attributeName = "InStock") public boolean getInStock() { return inStock; } public void setInStock(boolean inStock) { this.inStock = inStock; } // Additional properties go here. } Note Dans des versions précédentes de DynamoDBMapper, les attributs booléens étaient représentés par le type de données Number DynamoDB (N), où 1 était interprété comme true et 0 comme false. N'utilisez l'annotation DynamoDBNativeBoolean que si toutes les applications qui lisent des données depuis votre table utilisent une version mise à jour de DynamoDBMapper. DynamoDBRangeKey Mappe une propriété de classe avec la clé de tri de la table. La propriété doit être un des types binaire, numéro ou chaîne scalaire ; elle ne peut pas être un type collection. Si la clé primaire est composite (clé de partition et clé de tri), vous pouvez utiliser cette balise pour mapper votre champ de classe avec la clé de tri. Par exemple, supposons que vous ayez une table Reply qui stocke les réponses pour les threads de forum. Chaque thread peut avoir plusieurs réponses. Ainsi, la clé primaire de cette table est à la fois ThreadId et ReplyDateTime. Le ThreadId est la clé de partition et ReplyDateTime est la clé de tri. L'extrait de code Java suivant définit une classe Reply et la mappe avec la table Reply. Il utilise les deux balises, @DynamoDBHashKey et @DynamoDBRangeKey, pour identifier les propriétés de classe qui sont mappées avec la clé primaire. @DynamoDBTable(tableName="Reply") public class Reply { private Integer id; private String replyDateTime; @DynamoDBHashKey(attributeName="Id") public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } @DynamoDBRangeKey(attributeName="ReplyDateTime") public String getReplyDateTime() { return replyDateTime; } public void setReplyDateTime(String replyDateTime) { this.replyDateTime = replyDateTime; } // Additional properties go here. API Version 2012-08-10 87 Amazon DynamoDB Manuel du développeur Java : DynamoDBMapper } DynamoDBTable Identifie la table cible dans DynamoDB. Par exemple, l'extrait de code Java suivant définit une classe Developer et la mappe avec la table People dans DynamoDB. @DynamoDBTable(tableName="People") public class Developer { ...} L'annotation @DynamoDBTable peut être héritée. Toute nouvelle classe qui hérite de la classe Developer mappe également avec la table People. Par exemple, supposons que vous génériez une classe Lead qui hérite de la classe Developer. Etant donné que vous avez mappé la classe Developer avec la table People, les objets de la classe Lead sont également stockés dans la même table. La @DynamoDBTable peut également être remplacée. Toute nouvelle classe qui hérite de la classe Developer par défaut mappe avec la même table People. Toutefois, vous pouvez substituer ce mappage par défaut. Par exemple, si vous créez une classe qui hérite de la classe Developer, vous pouvez explicitement la mapper avec une autre table en ajoutant l'annotation @DynamoDBTable comme illustré dans l'extrait de code Java suivant. @DynamoDBTable(tableName="Managers") public class Manager extends Developer { ...} DynamoDBVersionAttribute Identifie une propriété de classe pour stocker un numéro de version de verrouillage optimiste. DynamoDBMapper affecte un numéro de version à cette propriété lorsqu'il enregistre un nouvel élément et l'augmente chaque fois que vous mettez à jour l'élément. Seuls les types scalaires de numéros sont pris en charge. Pour plus d'informations sur le type de données, consultez Type de données (p. 12). Pour plus d'informations sur la gestion des versions, consultez Verrouillage optimiste avec numéro de version (p. 112). La classe DynamoDBMapper La classe DynamoDBMapper est le point d'entrée pour DynamoDB. Elle fournit un accès à un point de terminaison DynamoDB et vous permet d'accéder à vos données dans différentes tables, d'effectuer diverses opérations CRUD sur des éléments et d'exécuter des requêtes et des analyses sur des tables. Cette classe fournit les méthodes suivantes pour travailler avec DynamoDB. Pour la documentation Javadoc correspondante, consultez DynamoDBMapper dans le manuel AWS SDK for Java API Reference. Rubriques • save (p. 89) • load (p. 89) • • • • • delete (p. 89) query (p. 90) queryPage (p. 91) scan (p. 91) scanPage (p. 92) • parallelScan (p. 92) • batchSave (p. 93) API Version 2012-08-10 88 Amazon DynamoDB Manuel du développeur Java : DynamoDBMapper • batchLoad (p. 93) • • • • • batchDelete (p. 93) batchWrite (p. 94) count (p. 94) generateCreateTableRequest (p. 94) createS3Link (p. 94) • getS3ClientCache (p. 95) save Enregistre l'objet spécifié dans la table. L'objet que vous souhaitez enregistrer est le seul paramètre requis pour cette méthode. Vous pouvez fournir des paramètres de configuration facultatifs en utilisant l'objet DynamoDBMapperConfig. Si un élément qui a la même clé primaire n'existe pas, cette méthode crée un nouvel élément dans la table. Si un élément qui a la même clé primaire existe, elle met à jour l'élément existant. Si la clé de partition et la clé de tri sont de type String, et annotées avec @DynamoDBAutoGeneratedKey, alors elles reçoivent un identificateur unique universel (UUID) aléatoire en cas de défaut d'initialisation. Les champs de version annotés avec @DynamoDBVersionAttribute seront incrémentés d'un niveau. En outre, si un champ de version est mis à jour ou généré par une clé, l'objet adopté est mis à jour à la suite de l'opération. Par défaut, seuls les attributs correspondant aux propriétés de classe mappée sont mis à jour ; tous les attributs existants supplémentaires sur un élément ne sont pas affectés. Toutefois, si vous spécifiez SaveBehavior.CLOBBER, vous pouvez forcer le remplacement complet de l'élément. mapper.save(obj, new DynamoDBMapperConfig(DynamoDBMapperConfig.SaveBehavior.CLOBBER)); Si vous avez activé le contrôle de version, alors les versions d'élément côté client et côté serveur doivent correspondre. Toutefois, la version n'a pas besoin de correspondre si l'option SaveBehavior.CLOBBER est utilisée. Pour plus d'informations sur la gestion des versions, consultez Verrouillage optimiste avec numéro de version (p. 112). load Récupère un élément dans une table. Vous devez fournir la clé primaire de l'élément que vous souhaitez récupérer. Vous pouvez fournir des paramètres de configuration facultatifs en utilisant l'objet DynamoDBMapperConfig. Par exemple, vous pouvez demander le cas échéant des lectures fortement cohérentes afin de garantir que cette méthode récupère uniquement les dernières valeurs d'élément comme indiqué dans l'instruction Java suivante. CatalogItem item = mapper.load(CatalogItem.class, item.getId(), new DynamoDBMapperConfig(DynamoDBMapperConfig.ConsistentReads.CONSISTENT)); Par défaut, DynamoDB renvoie l'élément qui a des valeurs cohérentes à terme. Pour plus d'informations sur le modèle de cohérence à terme de DynamoDB, consultez Cohérence en lecture (p. 16). delete Supprime un élément de la table. Vous devez communiquer une instance d'objet de la classe mappée. Si vous avez activé le contrôle de version, alors les versions d'élément côté client et côté serveur doivent correspondre. Toutefois, la version n'a pas besoin de correspondre si l'option API Version 2012-08-10 89 Amazon DynamoDB Manuel du développeur Java : DynamoDBMapper SaveBehavior.CLOBBER est utilisée. Pour plus d'informations sur la gestion des versions, consultez Verrouillage optimiste avec numéro de version (p. 112). query Interroge une table ou un index secondaire. Vous pouvez interroger une table ou un index uniquement si elle comporte une clé primaire composite (clé de partition et clé de tri). Cette méthode nécessite que vous fournissiez une valeur de clé de partition et un filtre de requête qui est appliqué sur la clé de tri. Une expression de filtre inclut une condition et une valeur. Supposons que vous ayez une table, Reply, qui stocke des réponses de threads de forum. Chaque objet thread peut avoir 0 ou plusieurs réponses. La clé primaire de la table Reply se compose des champs Id et ReplyDateTime, où Id est la clé de partition et ReplyDateTime est la clé de tri de la clé primaire. Reply ( Id, ReplyDateTime, ... ) Supposons à présent que vous ayez créé un mappage entre une classe Reply et la table Reply correspondante dans DynamoDB. L'extrait de code Java suivant utilise DynamoDBMapper pour trouver toutes les réponses au cours des deux dernières semaines pour un objet thread spécifique. String forumName = "DynamoDB"; String forumSubject = "DynamoDB Thread 1"; String partitionKey = forumName + "#" + forumSubject; long twoWeeksAgoMilli = (new Date()).getTime() - (14L*24L*60L*60L*1000L); Date twoWeeksAgo = new Date(); twoWeeksAgo.setTime(twoWeeksAgoMilli); SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); String twoWeeksAgoStr = df.format(twoWeeksAgo); Map<String, AttributeValue> eav = new HashMap<String, AttributeValue>(); eav.put(":v1", new AttributeValue().withS(partitionKey)); eav.put(":v2",new AttributeValue().withS(twoWeeksAgoStr.toString())); DynamoDBQueryExpression<Reply> queryExpression = new DynamoDBQueryExpression<Reply>() .withKeyConditionExpression("Id = :v1 and ReplyDateTime > :v2") .withExpressionAttributeValues(eav); List<Reply> latestReplies = mapper.query(Reply.class, queryExpression); La requête renvoie un ensemble d'objets Reply. Par défaut, la méthode query renvoie une collection « avec chargement différé ». Elle ne renvoie initialement qu'une seule page de résultats puis effectue un appel de service pour la page suivante si nécessaire. Pour obtenir tous les éléments correspondants, il vous suffit d'itérer sur la collection latestReplies. Pour interroger un index, vous devez tout d'abord affecter un modèle à l'index en tant que classe d'outil de mappage. Supposons que la table Reply ait un index secondaire global nommé PostedByMessage-Index. La clé de partition de cet index est PostedBy, et la clé de tri est Message. La définition de classe d'un élément dans l'index se présenterait comme suit : @DynamoDBTable(tableName="Reply") public class PostedByMessage { private String postedBy; API Version 2012-08-10 90 Amazon DynamoDB Manuel du développeur Java : DynamoDBMapper private String message; @DynamoDBIndexHashKey(globalSecondaryIndexName = "PostedBy-MessageIndex", attributeName = "PostedBy") public String getPostedBy() { return postedBy; } public void setPostedBy(String postedBy) { this.postedBy = postedBy; } @DynamoDBIndexRangeKey(globalSecondaryIndexName = "PostedBy-MessageIndex", attributeName = "Message") public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } // Additional properties go here. } L'annotation @DynamoDBTable indique que cet index est associé à la table Reply. L'annotation @DynamoDBIndexHashKey désigne la clé de partition (PostedBy) de l'index, et @DynamoDBIndexRangeKey désigne la clé de tri (Message) de l'index. Vous pouvez maintenant utiliser DynamoDBMapper pour interroger l'index, en récupérant un sousensemble de messages qui ont été publiés par un utilisateur particulier. Vous devez spécifier withIndexName afin que DynamoDB sache quel index interroger. Dans l'extrait de code suivant, nous interrogeons un index secondaire global. Etant donné que les index secondaire global prennent en charge de lectures cohérentes à terme, mais pas des lectures fortement cohérentes, nous devons spécifier withConsistentRead(false). HashMap<String, AttributeValue> eav = new HashMap<String, AttributeValue>(); eav.put(":v1", new AttributeValue().withS("User A")); eav.put(":v2", new AttributeValue().withS("DynamoDB")); DynamoDBQueryExpression<PostedByMessage> queryExpression = new DynamoDBQueryExpression<PostedByMessage>() .withIndexName("PostedBy-Message-Index") .withConsistentRead(false) .withKeyConditionExpression("PostedBy = :v1 and begins_with(Message, :v2)") .withExpressionAttributeValues(eav); List<PostedByMessage> iList = queryExpression); mapper.query(PostedByMessage.class, La requête renvoie un ensemble d'objets PostedByMessage. queryPage Interroge une table ou un index secondaire et renvoie une seule page de résultats correspondants. Comme avec la méthode query, vous devez spécifier une valeur de clé de partition et un filtre de requête qui est appliqué à l'attribut de clé de tri. Toutefois, queryPage renverra uniquement la première « page » de données, à savoir, le volume de données qui tiendra dans 1 MB scan Analyse une table entière ou un index secondaire. Vous pouvez spécifier le cas échéant un FilterExpression pour filtrer l'ensemble de résultats. Supposons que vous ayez une table, Reply, qui stocke des réponses de threads de forum. Chaque objet thread peut avoir 0 ou plusieurs réponses. La clé primaire de la table Reply se compose des champs Id et ReplyDateTime, où Id est la clé de partition et ReplyDateTime est la clé de tri de la clé primaire. API Version 2012-08-10 91 Amazon DynamoDB Manuel du développeur Java : DynamoDBMapper Reply ( Id, ReplyDateTime, ... ) Si vous avez mappé une classe Java vers la table Reply, vous pouvez utiliser le DynamoDBMapper pour analyser la table. Par exemple, l'extrait de code Java suivant analyse l'ensemble de la table Reply, en renvoyant uniquement les réponses pour une année donnée. HashMap<String, AttributeValue> eav = new HashMap<String, AttributeValue>(); eav.put(":v1", new AttributeValue().withS("2015")); DynamoDBScanExpression scanExpression = new DynamoDBScanExpression() .withFilterExpression("begins_with(ReplyDateTime,:v1)") .withExpressionAttributeValues(eav); List<Reply> replies = mapper.scan(Reply.class, scanExpression); Par défaut, la méthode scan renvoie une collection « avec chargement différé ». Elle ne renvoie initialement qu'une seule page de résultats puis effectue un appel de service pour la page suivante si nécessaire. Pour obtenir tous les éléments correspondants, il vous suffit d'itérer sur la collection replies. Pour analyser un index, vous devez tout d'abord affecter un modèle à l'index en tant que classe d'outil de mappage. Supposons que la table Reply ait un index secondaire global nommé PostedByMessage-Index. La clé de partition de cet index est PostedBy, et la clé de tri est Message. Une classe d'outil de mappage pour cet index est affichée dans la section query (p. 90), où nous utilisons les annotations @DynamoDBIndexHashKey et @DynamoDBIndexRangeKey pour spécifier la clé de partition et la clé de tri de l'index. L'extrait de code suivant analyse PostedBy-Message-Index. Il n'utilise pas un filtre d'analyse. Ainsi, tous les éléments dans l'index vous sont renvoyés. DynamoDBScanExpression scanExpression = new DynamoDBScanExpression() .withIndexName("PostedBy-Message-Index") .withConsistentRead(false); List<PostedByMessage> indexItems = mapper.scan(PostedByMessage.class, scanExpression); Iterator<PostedByMessage> indexItems = iList.iterator(); scanPage Analyse une table ou un index secondaire et renvoie une seule page de résultats correspondants. Comme avec la méthode scan, vous pouvez spécifier le cas échéant un FilterExpression pour filtrer le jeu de résultats. Toutefois, scanPage renverra uniquement la première « page » de données, à savoir, le volume de données qui tiendra dans 1 MB parallelScan Effectue une analyse parallèle d'une table entière ou index secondaire. Vous spécifiez un certain nombre de segments logiques pour la table, avec une expression d'analyse pour filtrer les résultats. Le parallelScan répartit la tâche d'analyse entre plusieurs instances de travail, une pour chaque segment logique ; les instances de travail traitent les données en parallèle et renvoient les résultats. L'extrait de code Java suivant effectue une analyse parallèle sur la table Product. int numberOfThreads = 4; Map<String, AttributeValue> eav = new HashMap<String, AttributeValue> (); API Version 2012-08-10 92 Amazon DynamoDB Manuel du développeur Java : DynamoDBMapper eav.put(":n", new AttributeValue().withN("100")); DynamoDBScanExpression scanExpression = new DynamoDBScanExpression() .withFilterExpression("Price >= :n") .withExpressionAttributeValues(eav); List<Product> scanResult = mapper.parallelScan(Product.class, scanExpression, numberOfThreads); Pour un exemple de code Java illustrant l'utilisation de parallelScan, consultez Exemple : Interroger et analyser (p. 104). batchSave Enregistre des objets dans une ou plusieurs tables à l'aide d'un ou de plusieurs appels à la méthode AmazonDynamoDB.batchWriteItem. Cette méthode n'offre pas de garanties de transaction. L'extrait de code Java enregistre deux éléments (livres) dans la table ProductCatalog. Book book1 = new Book(); book1.id = 901; book1.productCategory = "Book"; book1.title = "Book 901 Title"; Book book2 = new Book(); book2.id = 902; book2.productCategory = "Book"; book2.title = "Book 902 Title"; mapper.batchSave(Arrays.asList(book1, book2)); batchLoad Récupère plusieurs éléments d'une ou de plusieurs tables en utilisant leurs clés primaires. L'extrait de code Java suivant récupère deux éléments dans deux tables différentes. ArrayList<Object> itemsToGet = new ArrayList<Object>(); ForumItem forumItem = new ForumItem(); forumItem.setForumName("Amazon DynamoDB"); itemsToGet.add(forumItem); ThreadItem threadItem = new ThreadItem(); threadItem.setForumName("Amazon DynamoDB"); threadItem.setSubject("Amazon DynamoDB thread 1 message text"); itemsToGet.add(threadItem); Map<String, List<Object>> items = mapper.batchLoad(itemsToGet); batchDelete Supprime des objets d'une ou de plusieurs tables à l'aide d'un ou de plusieurs appels à la méthode AmazonDynamoDB.batchWriteItem. Cette méthode n'offre pas de garanties de transaction. L'extrait de code Java suivant supprime deux éléments (livres) de la table ProductCatalog. Book book1 = mapper.load(Book.class, 901); API Version 2012-08-10 93 Amazon DynamoDB Manuel du développeur Java : DynamoDBMapper Book book2 = mapper.load(Book.class, 902); mapper.batchDelete(Arrays.asList(book1, book2)); batchWrite Enregistre et supprime des objets dans une ou plusieurs des tables à l'aide d'un ou de plusieurs appels à la méthode AmazonDynamoDB.batchWriteItem. Cette méthode ne fournit pas des garanties de transactions et ne prend pas en charge le contrôle de version (suppressions ou insertions conditionnelles). L'extrait de code Java suivant écrit un nouvel élément dans la table Forum, écrit un nouvel élément dans la table Thread et supprime un élément de la table ProductCatalog. // Create a Forum item to save Forum forumItem = new Forum(); forumItem.name = "Test BatchWrite Forum"; // Create a Thread item to save Thread threadItem = new Thread(); threadItem.forumName = "AmazonDynamoDB"; threadItem.subject = "My sample question"; // Load a ProductCatalog item to delete Book book3 = mapper.load(Book.class, 903); List<Object> objectsToWrite = Arrays.asList(forumItem, threadItem); List<Book> objectsToDelete = Arrays.asList(book3); mapper.batchWrite(objectsToWrite, objectsToDelete); count Evalue l'expression d'analyse spécifiée et renvoie le nombre d'éléments correspondants. Aucun élément de données n'est renvoyé. generateCreateTableRequest Analyse une classe POJO qui représente une table DynamoDB et renvoie une CreateTableRequest pour cette table. createS3Link Crée un lien vers un objet dans Amazon S3. Vous devez spécifier un nom de compartiment et un nom de clé identifiant l'objet de manière unique dans le compartiment. Pour utiliser createS3Link, votre classe d'outil de mappage doit définir des méthodes getter et setter. L'extrait de code suivant illustre cela en ajoutant un nouvel attribut et des méthodes getter/setter à la classe CatalogItem : @DynamoDBTable(tableName="ProductCatalog") public class CatalogItem { ... public S3Link productImage; .... @DynamoDBAttribute(attributeName = "ProductImage") API Version 2012-08-10 94 Amazon DynamoDB Manuel du développeur Java : DynamoDBMapper public S3Link getProductImage() { return productImage; } public void setProductImage(S3Link productImage) { this.productImage = productImage; } ... } Le code Java suivant définit un nouvel élément à écrire dans la table Product. L'élément inclut un lien vers une image de produit ; les données d'image sont chargées dans Amazon S3. CatalogItem item = new CatalogItem(); item.id = 150; item.title = "Book 150 Title"; String myS3Bucket = "myS3bucket"; String myS3Key = "productImages/book_150_cover.jpg"; item.setProductImage(mapper.createS3Link(myS3Bucket, myS3Key)); item.getProductImage().uploadFrom(new File("/file/path/book_150_cover.jpg")); mapper.save(item); La classe S3Link fournit de nombreuses autres méthodes pour la manipulation des objets dans Amazon S3. Pour plus d'informations, consultez Javadocs pour S3Link. getS3ClientCache Renvoie le S3ClientCache sous-jacent pour l'accès à Amazon S3. Un S3ClientCache est une carte intelligente pour des objets AmazonS3Client. Si vous avez plusieurs clients, alors un S3ClientCache peut vous aider à organiser les clients par région et peut créer de nouveaux clients Amazon S3 à la demande. Paramètres de configuration facultatifs pour DynamoDBMapper Lorsque vous créez une instance de DynamoDBMapper, elle a certains comportements par défaut ; vous pouvez remplacer ces valeurs par défaut en utilisant la classe DynamoDBMapperConfig. L'extrait de code suivant crée un DynamoDBMapper avec des paramètres personnalisés : ClasspathPropertiesFileCredentialsProvider cp = new ClasspathPropertiesFileCredentialsProvider(); AmazonDynamoDBClient client = new AmazonDynamoDBClient(cp); DynamoDBMapperConfig mapperConfig = new DynamoDBMapperConfig( DynamoDBMapperConfig.SaveBehavior.CLOBBER, DynamoDBMapperConfig.ConsistentReads.CONSISTENT, null, //TableNameOverride - leaving this at default setting DynamoDBMapperConfig.PaginationLoadingStrategy.EAGER_LOADING ); API Version 2012-08-10 95 Amazon DynamoDB Manuel du développeur Java : DynamoDBMapper DynamoDBMapper mapper = new DynamoDBMapper(client, mapperConfig, cp); Pour plus d'informations, consultez DynamoDBMapperConfig dans AWS SDK for Java API Reference. Vous pouvez utiliser les arguments suivants pour une instance de DynamoDBMapperConfig : • Une valeur d'énumération DynamoDBMapperConfig.ConsistentReads : • EVENTUAL—l'instance d'outil de mappage utilise une demande de lecture cohérente à terme. • CONSISTENT— l'instance d'outil de mappage utilise une demande de lecture fortement cohérente. Vous pouvez utiliser ce paramètre facultatif avec des opérations load, query ou scan. Les lectures fortement cohérentes ont des implications sur la performance et la facturation ; consultez la page de détails du produit DynamoDB pour plus d'informations. Si vous ne spécifiez pas un paramètre de cohérence de lecture pour votre instance d'outil de mappage, la valeur par défaut est EVENTUAL. • Une valeur d'énumération DynamoDBMapperConfig.PaginationLoadingStrategy— Contrôle la manière dont l'instance d'outil de mappage traite une liste paginée de données, tels que les résultats d'une query ou d'une scan : • LAZY_LOADING— l'instance d'outil de mappage charge des données lorsque c'est possible et conserve tous les résultats chargés dans la mémoire. • EAGER_LOADING—l'instance d'outil de mappage charge les données dès que la liste est initialisée. • ITERATION_ONLY—vous ne pouvez utiliser un itérateur que pour lire dans la liste. Pendant l'itération, la liste efface tous les résultats précédents avant de charger la page suivante, pour que la liste conserve en mémoire au maximum une page des résultats chargés. Cela signifie également que la liste ne peut être itérée qu'à une seule reprise. Cette stratégie est recommandée lors de la gestion d'éléments importants, afin de réduire les frais généraux de mémoire. Si vous ne spécifiez pas une stratégie de chargement de pagination pour votre instance d'outil de mappage, la valeur par défaut est LAZY_LOADING. • Une valeur d'énumération DynamoDBMapperConfig.SaveBehavior - Spécifie comment l'instance d'outil de mappage devrait traiter les attributs lors des opérations d'enregistrement : • UPDATE— pendant une opération de sauvegarde, tous les attributs modélisés sont mis à jour et les attributs non modélisés ne sont pas affectés. Les types de numéros primitifs (octets, int, long) sont définis sur 0. Les types d'objets sont définis sur null. • CLOBBER—efface et remplace tous les attributs, y compris les non modélisés, pendant une opération de sauvegarde. Pour cela, il faut supprimer l'élément et le recréer. Les contraintes de champ avec version sont également ignorées. Si vous ne spécifiez pas le comportement de sauvegarde pour votre instance d'outil de mappage, la valeur par défaut est UPDATE. • Un objet DynamoDBMapperConfig.TableNameOverride—Demande à l'instance d'outil de mappage d'ignorer le nom de la table spécifié par une annotation DynamoDBTable de classe et utilise à la place un nom de table différent que vous fournissez. Cela est utile lors du partitionnement de vos données dans plusieurs tables au moment de l'exécution. Vous pouvez remplacer l'objet de configuration par défaut pour DynamoDBMapper par opération, en fonction des besoins. Exemple : opérations CRUD L'exemple de code Java suivant déclare une classe CatalogItem qui possède des propriétés Id, titre, ISBN et auteurs. Il utilise les annotations pour mapper ces propriétés vers la table ProductCatalog dans DynamoDB. L'exemple de code utilise ensuite le DynamoDBMapper pour enregistrer un objet livre, le récupérer, le mettre à jour et supprimer l'élément livre. API Version 2012-08-10 96 Amazon DynamoDB Manuel du développeur Java : DynamoDBMapper Note Cet exemple de code suppose que vous ayez déjà chargé des données dans DynamoDB pour votre compte en suivant les instructions de la section Création de tables et chargement d'exemples de données (p. 167). Pour obtenir les instructions pas à pas afin d'exécuter l'exemple suivant, consultez Exemples de Code Java (p. 173). // Copyright 2012-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. // Licensed under the Apache License, Version 2.0. package com.amazonaws.codesamples.datamodeling; import import import import java.io.IOException; java.util.Arrays; java.util.HashSet; java.util.Set; import import import import import import import com.amazonaws.auth.profile.ProfileCredentialsProvider; com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient; com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBAttribute; com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBHashKey; com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper; com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperConfig; com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTable; public class DynamoDBMapperCRUDExample { static AmazonDynamoDBClient client = new AmazonDynamoDBClient(new ProfileCredentialsProvider()); public static void main(String[] args) throws IOException { testCRUDOperations(); System.out.println("Example complete!"); } @DynamoDBTable(tableName="ProductCatalog") public static class CatalogItem { private Integer id; private String title; private String ISBN; private Set<String> bookAuthors; //Partition key @DynamoDBHashKey(attributeName="Id") public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } @DynamoDBAttribute(attributeName="Title") public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } @DynamoDBAttribute(attributeName="ISBN") public String getISBN() { return ISBN; } public void setISBN(String ISBN) { this.ISBN = ISBN;} @DynamoDBAttribute(attributeName = "Authors") API Version 2012-08-10 97 Amazon DynamoDB Manuel du développeur Java : DynamoDBMapper public Set<String> getBookAuthors() { return bookAuthors; } public void setBookAuthors(Set<String> bookAuthors) { this.bookAuthors = bookAuthors; } @Override public String toString() { return "Book [ISBN=" + ISBN + ", bookAuthors=" + bookAuthors + ", id=" + id + ", title=" + title + "]"; } } private static void testCRUDOperations() { CatalogItem item = new CatalogItem(); item.setId(601); item.setTitle("Book 601"); item.setISBN("611-1111111111"); item.setBookAuthors(new HashSet<String>(Arrays.asList("Author1", "Author2"))); // Save the item (book). DynamoDBMapper mapper = new DynamoDBMapper(client); mapper.save(item); // Retrieve the item. CatalogItem itemRetrieved = mapper.load(CatalogItem.class, 601); System.out.println("Item retrieved:"); System.out.println(itemRetrieved); // Update the item. itemRetrieved.setISBN("622-2222222222"); itemRetrieved.setBookAuthors(new HashSet<String>(Arrays.asList("Author1", "Author3"))); mapper.save(itemRetrieved); System.out.println("Item updated:"); System.out.println(itemRetrieved); // Retrieve the updated item. DynamoDBMapperConfig config = new DynamoDBMapperConfig(DynamoDBMapperConfig.ConsistentReads.CONSISTENT); CatalogItem updatedItem = mapper.load(CatalogItem.class, 601, config); System.out.println("Retrieved the previously updated item:"); System.out.println(updatedItem); // Delete the item. mapper.delete(updatedItem); // Try to retrieve deleted item. CatalogItem deletedItem = mapper.load(CatalogItem.class, updatedItem.getId(), config); if (deletedItem == null) { System.out.println("Done - Sample item is deleted."); } } } API Version 2012-08-10 98 Amazon DynamoDB Manuel du développeur Java : DynamoDBMapper Exemple : Opérations d'écriture par lots L'exemple de code Java suivant déclare les classes Book, Forum, Thread et Reply et les mappe aux tables DynamoDB à l'aide de la classe DynamoDBMapper. Le code illustre les opérations d'écriture par lots suivantes : • batchSave pour placer les éléments « book » de le table ProductCatalog. • batchDelete pour supprimer les éléments de la table ProductCatalog. • batchWrite pour placer et supprimer les éléments des tables Forum et Thread. Pour plus d'informations sur les tables utilisées dans cet exemple, consultez Création de tables et chargement d'exemples de données (p. 167). Pour obtenir les instructions pas à pas afin de tester l'exemple suivant, consultez Exemples de Code Java (p. 173). // Copyright 2012-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. // Licensed under the Apache License, Version 2.0. package com.amazonaws.codesamples.datamodeling; import import import import import import java.text.SimpleDateFormat; java.util.ArrayList; java.util.Arrays; java.util.HashSet; java.util.List; java.util.Set; import import import import import import import import com.amazonaws.auth.profile.ProfileCredentialsProvider; com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient; com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBAttribute; com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBHashKey; com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper; com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperConfig; com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBRangeKey; com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTable; public class DynamoDBMapperBatchWriteExample { static AmazonDynamoDBClient client = new AmazonDynamoDBClient(new ProfileCredentialsProvider()); static SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MMdd'T'HH:mm:ss.SSS'Z'"); public static void main(String[] args) throws Exception { try { DynamoDBMapper mapper = new DynamoDBMapper(client); testBatchSave(mapper); testBatchDelete(mapper); testBatchWrite(mapper); System.out.println("Example complete!"); } catch (Throwable t) { System.err.println("Error running the DynamoDBMapperBatchWriteExample: " + t); t.printStackTrace(); API Version 2012-08-10 99 Amazon DynamoDB Manuel du développeur Java : DynamoDBMapper } } private static void testBatchSave(DynamoDBMapper mapper) { Book book1 = new Book(); book1.id = 901; book1.inPublication = true; book1.ISBN = "902-11-11-1111"; book1.pageCount = 100; book1.price = 10; book1.productCategory = "Book"; book1.title = "My book created in batch write"; Book book2 = new Book(); book2.id = 902; book2.inPublication = true; book2.ISBN = "902-11-12-1111"; book2.pageCount = 200; book2.price = 20; book2.productCategory = "Book"; book2.title = "My second book created in batch write"; Book book3 = new Book(); book3.id = 903; book3.inPublication = false; book3.ISBN = "902-11-13-1111"; book3.pageCount = 300; book3.price = 25; book3.productCategory = "Book"; book3.title = "My third book created in batch write"; System.out.println("Adding three books to ProductCatalog table."); mapper.batchSave(Arrays.asList(book1, book2, book3)); } private static void testBatchDelete(DynamoDBMapper mapper) { Book book1 = mapper.load(Book.class, 901); Book book2 = mapper.load(Book.class, 902); System.out.println("Deleting two books from the ProductCatalog table."); mapper.batchDelete(Arrays.asList(book1, book2)); } private static void testBatchWrite(DynamoDBMapper mapper) { // Create Forum item to save Forum forumItem = new Forum(); forumItem.name = "Test BatchWrite Forum"; forumItem.threads = 0; forumItem.category = "Amazon Web Services"; // Create Thread item to save Thread threadItem = new Thread(); threadItem.forumName = "AmazonDynamoDB"; threadItem.subject = "My sample question"; threadItem.message = "BatchWrite message"; List<String> tags = new ArrayList<String>(); API Version 2012-08-10 100 Amazon DynamoDB Manuel du développeur Java : DynamoDBMapper tags.add("batch operations"); tags.add("write"); threadItem.tags = new HashSet<String>(tags); // Load ProductCatalog item to delete Book book3 = mapper.load(Book.class, 903); List<Object> objectsToWrite = Arrays.asList(forumItem, threadItem); List<Book> objectsToDelete = Arrays.asList(book3); DynamoDBMapperConfig config = new DynamoDBMapperConfig(DynamoDBMapperConfig.SaveBehavior.CLOBBER); mapper.batchWrite(objectsToWrite, objectsToDelete, config); } @DynamoDBTable(tableName="ProductCatalog") public static class Book { private int id; private String title; private String ISBN; private int price; private int pageCount; private String productCategory; private boolean inPublication; //Partition key @DynamoDBHashKey(attributeName="Id") public int getId() { return id; } public void setId(int id) { this.id = id; } @DynamoDBAttribute(attributeName="Title") public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } @DynamoDBAttribute(attributeName="ISBN") public String getISBN() { return ISBN; } public void setISBN(String ISBN) { this.ISBN = ISBN; } @DynamoDBAttribute(attributeName="Price") public int getPrice() { return price; } public void setPrice(int price) { this.price = price; } @DynamoDBAttribute(attributeName="PageCount") public int getPageCount() { return pageCount; } public void setPageCount(int pageCount) { this.pageCount = pageCount;} @DynamoDBAttribute(attributeName="ProductCategory") public String getProductCategory() { return productCategory; } public void setProductCategory(String productCategory) { this.productCategory = productCategory; } @DynamoDBAttribute(attributeName="InPublication") public boolean getInPublication() { return inPublication; } public void setInPublication(boolean inPublication) { this.inPublication = inPublication; } @Override public String toString() { API Version 2012-08-10 101 Amazon DynamoDB Manuel du développeur Java : DynamoDBMapper return "Book [ISBN=" + ISBN + ", price=" + price + ", product category=" + productCategory + ", id=" + id + ", title=" + title + "]"; } } @DynamoDBTable(tableName="Reply") public static class Reply { private String id; private String replyDateTime; private String message; private String postedBy; //Partition key @DynamoDBHashKey(attributeName="Id") public String getId() { return id; } public void setId(String id) { this.id = id; } //Sort key @DynamoDBRangeKey(attributeName="ReplyDateTime") public String getReplyDateTime() { return replyDateTime; } public void setReplyDateTime(String replyDateTime) { this.replyDateTime = replyDateTime; } @DynamoDBAttribute(attributeName="Message") public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } @DynamoDBAttribute(attributeName="PostedBy") public String getPostedBy() { return postedBy; } public void setPostedBy(String postedBy) { this.postedBy = postedBy;} } @DynamoDBTable(tableName="Thread") public static class Thread { private String forumName; private String subject; private String message; private String lastPostedDateTime; private String lastPostedBy; private Set<String> tags; private int answered; private int views; private int replies; //Partition key @DynamoDBHashKey(attributeName="ForumName") public String getForumName() { return forumName; } public void setForumName(String forumName) { this.forumName = forumName; } //Sort key @DynamoDBRangeKey(attributeName="Subject") public String getSubject() { return subject; } public void setSubject(String subject) { this.subject = subject; } @DynamoDBAttribute(attributeName="Message") API Version 2012-08-10 102 Amazon DynamoDB Manuel du développeur Java : DynamoDBMapper public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } @DynamoDBAttribute(attributeName="LastPostedDateTime") public String getLastPostedDateTime() { return lastPostedDateTime; } public void setLastPostedDateTime(String lastPostedDateTime) { this.lastPostedDateTime = lastPostedDateTime; } @DynamoDBAttribute(attributeName="LastPostedBy") public String getLastPostedBy() { return lastPostedBy; } public void setLastPostedBy(String lastPostedBy) { this.lastPostedBy = lastPostedBy;} @DynamoDBAttribute(attributeName="Tags") public Set<String> getTags() { return tags; } public void setTags(Set<String> tags) { this.tags = tags; } @DynamoDBAttribute(attributeName="Answered") public int getAnswered() { return answered; } public void setAnswered(int answered) { this.answered = answered; } @DynamoDBAttribute(attributeName="Views") public int getViews() { return views; } public void setViews(int views) { this.views = views; } @DynamoDBAttribute(attributeName="Replies") public int getReplies() { return replies; } public void setReplies(int replies) { this.replies = replies; } } @DynamoDBTable(tableName="Forum") public static class Forum { private String name; private String category; private int threads; //Partition key @DynamoDBHashKey(attributeName="Name") public String getName() { return name; } public void setName(String name) { this.name = name; } @DynamoDBAttribute(attributeName="Category") public String getCategory() { return category; } public void setCategory(String category) { this.category = category; } @DynamoDBAttribute(attributeName="Threads") public int getThreads() { return threads; } public void setThreads(int threads) { this.threads = threads;} } } API Version 2012-08-10 103 Amazon DynamoDB Manuel du développeur Java : DynamoDBMapper Exemple : Interroger et analyser L'exemple Java de cette section définit les classes suivantes et les mappe avec les tables de DynamoDB. Pour plus d'informations sur la création des exemples de table, consultez Création de tables et chargement d'exemples de données (p. 167). • Classe Book mappée avec la table ProductCatalog • Classes Forum, Thread et Reply mappées avec les tables de même nom. L'exemple exécute ensuite les opérations d'interrogation et d'analyse suivantes à l'aide d'une instance DynamoDBMapper. • Obtenez un livre par ID. La table ProductCatalog a un Id comme clé primaire. Il n'a pas de clé de tri dans le cadre de sa clé primaire. Par conséquent, vous ne pouvez pas interroger la table. Vous pouvez obtenir un élément à l'aide de sa valeur Id. • Exécutez les requêtes suivantes sur la table Reply. La clé primaire de la table Reply est composée d'attributs Id et ReplyDateTime. ReplyDateTime est une clé de tri. Vous pouvez donc interroger cette table. • Rechercher des réponses à un thread de forum publié au cours des 15 derniers jours • Rechercher des réponses à un thread de forum publié dans une plage de dates spécifique • Analysez la table ProductCatalog pour trouver des livres dont le prix est inférieur à une valeur spécifiée. Pour des raisons de performance, vous devez utiliser une opération de requête au lieu de l'opération d'analyse. Cependant, il y a des fois où vous pourrez avoir besoin d'analyser une table. Imaginons qu'il y ait eu une erreur d'entrée de données et qu'un des prix de livre ait été défini sur une valeur inférieure à 0. Cet exemple analyse la table ProductCategory pour rechercher des éléments de livre (ProductCategory a la valeur « book ») dont le prix est inférieur à 0. • Effectuez une analyse parallèle de la table ProductCatalog pour trouver des bicyclettes d'un type spécifique. Note Cet exemple de code suppose que vous ayez déjà chargé des données dans DynamoDB pour votre compte en suivant les instructions de la section Création de tables et chargement d'exemples de données (p. 167). Pour obtenir les instructions pas à pas afin d'exécuter l'exemple suivant, consultez Exemples de Code Java (p. 173). // Copyright 2012-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. // Licensed under the Apache License, Version 2.0. package com.amazonaws.codesamples.datamodeling; import import import import import import java.text.SimpleDateFormat; java.util.Date; java.util.HashMap; java.util.List; java.util.Map; java.util.Set; API Version 2012-08-10 104 Amazon DynamoDB Manuel du développeur Java : DynamoDBMapper import java.util.TimeZone; import com.amazonaws.auth.profile.ProfileCredentialsProvider; import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient; import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBAttribute; import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBHashKey; import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper; import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBQueryExpression; import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBRangeKey; import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBScanExpression; import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTable; import com.amazonaws.services.dynamodbv2.model.AttributeValue; public class DynamoDBMapperQueryScanExample { static AmazonDynamoDBClient client = new AmazonDynamoDBClient(new ProfileCredentialsProvider()); public static void main(String[] args) throws Exception { try { DynamoDBMapper mapper = new DynamoDBMapper(client); // Get a book - Id=101 GetBook(mapper, 101); // Sample forum and thread to test queries. String forumName = "Amazon DynamoDB"; String threadSubject = "DynamoDB Thread 1"; // Sample queries. FindRepliesInLast15Days(mapper, forumName, threadSubject); FindRepliesPostedWithinTimePeriod(mapper, forumName, threadSubject); // Scan a table and find book items priced less than specified value. FindBooksPricedLessThanSpecifiedValue(mapper, "20"); // Scan a table with multiple threads and find bicycle items with a specified bicycle type int numberOfThreads = 16; FindBicyclesOfSpecificTypeWithMultipleThreads(mapper, numberOfThreads, "Road"); System.out.println("Example complete!"); } catch (Throwable t) { System.err.println("Error running the DynamoDBMapperQueryScanExample: " + t); t.printStackTrace(); } } private static void GetBook(DynamoDBMapper mapper, int id) throws Exception { System.out.println("GetBook: Get book Id='101' "); System.out.println("Book table has no sort key. You can do GetItem, but not Query."); Book book = mapper.load(Book.class, 101); API Version 2012-08-10 105 Amazon DynamoDB Manuel du développeur Java : DynamoDBMapper System.out.format("Id = %s Title = %s, ISBN = %s %n", book.getId(), book.getTitle(), book.getISBN() ); } private static void FindRepliesInLast15Days(DynamoDBMapper mapper, String forumName, String threadSubject) throws Exception { System.out.println("FindRepliesInLast15Days: Replies within last 15 days."); String partitionKey = forumName + "#" + threadSubject; long twoWeeksAgoMilli = (new Date()).getTime() (15L*24L*60L*60L*1000L); Date twoWeeksAgo = new Date(); twoWeeksAgo.setTime(twoWeeksAgoMilli); SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MMdd'T'HH:mm:ss.SSS'Z'"); dateFormatter.setTimeZone(TimeZone.getTimeZone("UTC")); String twoWeeksAgoStr = dateFormatter.format(twoWeeksAgo); Map<String, AttributeValue> eav = new HashMap<String, AttributeValue>(); eav.put(":val1", new AttributeValue().withS(partitionKey)); eav.put(":val2", new AttributeValue().withS(twoWeeksAgoStr.toString())); DynamoDBQueryExpression<Reply> queryExpression = new DynamoDBQueryExpression<Reply>() .withKeyConditionExpression("Id = :val1 and ReplyDateTime > :val2") .withExpressionAttributeValues(eav); List<Reply> latestReplies = mapper.query(Reply.class, queryExpression); for (Reply reply : latestReplies) { System.out.format("Id=%s, Message=%s, PostedBy=%s %n, ReplyDateTime=%s %n", reply.getId(), reply.getMessage(), reply.getPostedBy(), reply.getReplyDateTime() ); } } private static void FindRepliesPostedWithinTimePeriod( DynamoDBMapper mapper, String forumName, String threadSubject) throws Exception { String partitionKey = forumName + "#" + threadSubject; System.out.println("FindRepliesPostedWithinTimePeriod: Find replies for thread Message = 'DynamoDB Thread 2' posted within a period."); long startDateMilli = (new Date()).getTime() (14L*24L*60L*60L*1000L); // Two weeks ago. long endDateMilli = (new Date()).getTime() - (7L*24L*60L*60L*1000L); // One week ago. API Version 2012-08-10 106 Amazon DynamoDB Manuel du développeur Java : DynamoDBMapper SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MMdd'T'HH:mm:ss.SSS'Z'"); dateFormatter.setTimeZone(TimeZone.getTimeZone("UTC")); String startDate = dateFormatter.format(startDateMilli); String endDate = dateFormatter.format(endDateMilli); Map<String, AttributeValue> eav = new HashMap<String, AttributeValue>(); eav.put(":val1", new AttributeValue().withS(partitionKey)); eav.put(":val2", new AttributeValue().withS(startDate)); eav.put(":val3", new AttributeValue().withS(endDate)); DynamoDBQueryExpression<Reply> queryExpression = new DynamoDBQueryExpression<Reply>() .withKeyConditionExpression("Id = :val1 and ReplyDateTime between :val2 and :val3") .withExpressionAttributeValues(eav); List<Reply> betweenReplies = mapper.query(Reply.class, queryExpression); for (Reply reply : betweenReplies) { System.out.format("Id=%s, Message=%s, PostedBy=%s %n, PostedDateTime=%s %n", reply.getId(), reply.getMessage(), reply.getPostedBy(), reply.getReplyDateTime() ); } } private static void FindBooksPricedLessThanSpecifiedValue( DynamoDBMapper mapper, String value) throws Exception { System.out.println("FindBooksPricedLessThanSpecifiedValue: Scan ProductCatalog."); Map<String, AttributeValue> eav = new HashMap<String, AttributeValue>(); eav.put(":val1", new AttributeValue().withN(value)); eav.put(":val2", new AttributeValue().withS("Book")); DynamoDBScanExpression scanExpression = new DynamoDBScanExpression() .withFilterExpression("Price < :val1 and ProductCategory = :val2") .withExpressionAttributeValues(eav); List<Book> scanResult = mapper.scan(Book.class, scanExpression); for (Book book : scanResult) { System.out.println(book); } } private static void FindBicyclesOfSpecificTypeWithMultipleThreads( DynamoDBMapper mapper, int numberOfThreads, String bicycleType) throws Exception { API Version 2012-08-10 107 Amazon DynamoDB Manuel du développeur Java : DynamoDBMapper System.out.println("FindBicyclesOfSpecificTypeWithMultipleThreads: Scan ProductCatalog With Multiple Threads."); Map<String, AttributeValue> eav = new HashMap<String, AttributeValue> (); eav.put(":val1", new AttributeValue().withS("Bicycle")); eav.put(":val2", new AttributeValue().withS(bicycleType)); DynamoDBScanExpression scanExpression = new DynamoDBScanExpression() .withFilterExpression("ProductCategory = :val1 and BicycleType = :val2") .withExpressionAttributeValues(eav); List<Bicycle> scanResult = mapper.parallelScan(Bicycle.class, scanExpression, numberOfThreads); for (Bicycle bicycle : scanResult) { System.out.println(bicycle); } } @DynamoDBTable(tableName="ProductCatalog") public static class Book { private int id; private String title; private String ISBN; private int price; private int pageCount; private String productCategory; private boolean inPublication; @DynamoDBHashKey(attributeName="Id") public int getId() { return id; } public void setId(int id) { this.id = id; } @DynamoDBAttribute(attributeName="Title") public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } @DynamoDBAttribute(attributeName="ISBN") public String getISBN() { return ISBN; } public void setISBN(String ISBN) { this.ISBN = ISBN; } @DynamoDBAttribute(attributeName="Price") public int getPrice() { return price; } public void setPrice(int price) { this.price = price; } @DynamoDBAttribute(attributeName="PageCount") public int getPageCount() { return pageCount; } public void setPageCount(int pageCount) { this.pageCount = pageCount;} @DynamoDBAttribute(attributeName="ProductCategory") public String getProductCategory() { return productCategory; } public void setProductCategory(String productCategory) { this.productCategory = productCategory; } @DynamoDBAttribute(attributeName="InPublication") public boolean getInPublication() { return inPublication; } public void setInPublication(boolean inPublication) { this.inPublication = inPublication; } API Version 2012-08-10 108 Amazon DynamoDB Manuel du développeur Java : DynamoDBMapper @Override public String toString() { return "Book [ISBN=" + ISBN + ", price=" + price + ", product category=" + productCategory + ", id=" + id + ", title=" + title + "]"; } } @DynamoDBTable(tableName="ProductCatalog") public static class Bicycle { private int id; private String title; private String description; private String bicycleType; private String brand; private int price; private List<String> color; private String productCategory; @DynamoDBHashKey(attributeName="Id") public int getId() { return id; } public void setId(int id) { this.id = id; } @DynamoDBAttribute(attributeName="Title") public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } @DynamoDBAttribute(attributeName="Description") public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } @DynamoDBAttribute(attributeName="BicycleType") public String getBicycleType() { return bicycleType; } public void setBicycleType(String bicycleType) { this.bicycleType = bicycleType; } @DynamoDBAttribute(attributeName="Brand") public String getBrand() { return brand; } public void setBrand(String brand) { this.brand = brand; } @DynamoDBAttribute(attributeName="Price") public int getPrice() { return price; } public void setPrice(int price) { this.price = price; } @DynamoDBAttribute(attributeName="Color") public List<String> getColor() { return color; } public void setColor(List<String> color) { this.color = color; } @DynamoDBAttribute(attributeName="ProductCategory") public String getProductCategory() { return productCategory; } public void setProductCategory(String productCategory) { this.productCategory = productCategory; } @Override public String toString() { API Version 2012-08-10 109 Amazon DynamoDB Manuel du développeur Java : DynamoDBMapper return "Bicycle [Type=" + bicycleType + ", color=" + color + ", price=" + price + ", product category=" + productCategory + ", id=" + id + ", title=" + title + "]"; } } @DynamoDBTable(tableName="Reply") public static class Reply { private String id; private String replyDateTime; private String message; private String postedBy; //Partition key @DynamoDBHashKey(attributeName="Id") public String getId() { return id; } public void setId(String id) { this.id = id; } //Range key @DynamoDBRangeKey(attributeName="ReplyDateTime") public String getReplyDateTime() { return replyDateTime; } public void setReplyDateTime(String replyDateTime) { this.replyDateTime = replyDateTime; } @DynamoDBAttribute(attributeName="Message") public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } @DynamoDBAttribute(attributeName="PostedBy") public String getPostedBy() { return postedBy; } public void setPostedBy(String postedBy) { this.postedBy = postedBy;} } @DynamoDBTable(tableName="Thread") public static class Thread { private String forumName; private String subject; private String message; private String lastPostedDateTime; private String lastPostedBy; private Set<String> tags; private int answered; private int views; private int replies; //Partition key @DynamoDBHashKey(attributeName="ForumName") public String getForumName() { return forumName; } public void setForumName(String forumName) { this.forumName = forumName; } //Range key @DynamoDBRangeKey(attributeName="Subject") public String getSubject() { return subject; } public void setSubject(String subject) { this.subject = subject; } API Version 2012-08-10 110 Amazon DynamoDB Manuel du développeur Java : DynamoDBMapper @DynamoDBAttribute(attributeName="Message") public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } @DynamoDBAttribute(attributeName="LastPostedDateTime") public String getLastPostedDateTime() { return lastPostedDateTime; } public void setLastPostedDateTime(String lastPostedDateTime) { this.lastPostedDateTime = lastPostedDateTime; } @DynamoDBAttribute(attributeName="LastPostedBy") public String getLastPostedBy() { return lastPostedBy; } public void setLastPostedBy(String lastPostedBy) { this.lastPostedBy = lastPostedBy;} @DynamoDBAttribute(attributeName="Tags") public Set<String> getTags() { return tags; } public void setTags(Set<String> tags) { this.tags = tags; } @DynamoDBAttribute(attributeName="Answered") public int getAnswered() { return answered; } public void setAnswered(int answered) { this.answered = answered; } @DynamoDBAttribute(attributeName="Views") public int getViews() { return views; } public void setViews(int views) { this.views = views; } @DynamoDBAttribute(attributeName="Replies") public int getReplies() { return replies; } public void setReplies(int replies) { this.replies = replies; } } @DynamoDBTable(tableName="Forum") public static class Forum { private String name; private String category; private int threads; @DynamoDBHashKey(attributeName="Name") public String getName() { return name; } public void setName(String name) { this.name = name; } @DynamoDBAttribute(attributeName="Category") public String getCategory() { return category; } public void setCategory(String category) { this.category = category; } @DynamoDBAttribute(attributeName="Threads") public int getThreads() { return threads; } public void setThreads(int threads) { this.threads = threads;} } } API Version 2012-08-10 111 Amazon DynamoDB Manuel du développeur Java : DynamoDBMapper Verrouillage optimiste avec numéro de version Le verrouillage optimiste est une stratégie pour garantir que l'élément côté client que vous mettez à jour (ou supprimez) soit identique à l'élément dans DynamoDB. Si vous utilisez cette stratégie, alors les écritures de votre base de données ne peuvent pas être remplacées par les écritures d'autres, et vice versa. Avec le verrouillage optimiste, chaque élément possède un attribut qui agit comme un numéro de version. Si vous récupérez un élément à partir d'une table, l'application enregistre le numéro de version de cet élément. Vous pouvez mettre à jour l'élément, mais uniquement si le numéro de version sur le côté serveur n'a pas changé. S'il y a une incompatibilité de version, cela signifie qu'une autre personne a modifié l'élément avant vous. La tentative de mise à jour échoue parce que vous avez une version obsolète de l'élément. Si cela se produit, vous essayez simplement à nouveau en récupérant de l'élément puis en essayant de le mettre à jour. Le verrouillage optimiste vous empêche de remplacer accidentellement des modifications apportées par d'autres. Il empêche également les autres de remplacer vos modifications. Pour prendre en charge le verrouillage optimiste, le AWS SDK for Java fournit l'annotation @DynamoDBVersionAttribute. Dans la classe de mappage pour votre table, vous indiquez une propriété pour stocker le numéro de version et vous la marquez à l'aide de cette annotation. Lorsque vous enregistrez un objet, l'élément correspondant dans la table DynamoDB aura un attribut qui stocke le numéro de version. Le DynamoDBMapper attribue un numéro de version lors de l'enregistrement initial de l'objet, et il augmente automatiquement le numéro de version chaque fois que vous mettez à jour l'élément. Vos demandes de mise à jour ou de suppression aboutiront uniquement si le numéro de version d'objet côté client correspond au numéro de version de l'élément correspondant dans la table DynamoDB. Par exemple, l'extrait de code Java suivant définit une classe CatalogItem qui possède plusieurs propriétés. La propriété Version est balisée avec l'annotation @DynamoDBVersionAttribute. @DynamoDBTable(tableName="ProductCatalog") public class CatalogItem { private private private private private private Integer id; String title; String ISBN; Set<String> bookAuthors; String someProp; Long version; @DynamoDBHashKey(attributeName="Id") public Integer getId() { return id; } public void setId(Integer Id) { this.id = Id; } @DynamoDBAttribute(attributeName="Title") public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } @DynamoDBAttribute(attributeName="ISBN") public String getISBN() { return ISBN; } public void setISBN(String ISBN) { this.ISBN = ISBN;} @DynamoDBAttribute(attributeName = "Authors") public Set<String> getBookAuthors() { return bookAuthors; } public void setBookAuthors(Set<String> bookAuthors) { this.bookAuthors = bookAuthors; } @DynamoDBIgnore public String getSomeProp() { return someProp;} API Version 2012-08-10 112 Amazon DynamoDB Manuel du développeur Java : DynamoDBMapper public void setSomeProp(String someProp) {this.someProp = someProp;} @DynamoDBVersionAttribute public Long getVersion() { return version; } public void setVersion(Long version) { this.version = version;} } Vous pouvez appliquer l'annotation @DynamoDBVersionAttribute aux types Nullable proposés par les classes de wrappers primitifs qui fournissent un type Nullable, par exemple Long et Integer. Le verrouillage optimiste a l'impact suivant sur ces méthodes DynamoDBMapper : • save – Pour un nouvel élément, le DynamoDBMapper attribue un numéro de version initiale 1. Si vous récupérez un élément, que vous mettez à jour une ou plusieurs de ses propriétés et que vous tentez d'enregistrer les modifications, l'opération de sauvegarde n'aboutit que si les numéros de version côté client et côté serveur correspondent. Le DynamoDBMapper augmente le numéro de version automatiquement. • delete – La méthode delete prend un objet comme paramètre et le DynamoDBMapper effectue un contrôle de version avant de supprimer l'élément. Le contrôle de version peut être désactivé si DynamoDBMapperConfig.SaveBehavior.CLOBBER est spécifié dans la demande. L'implémentation interne de verrouillage optimiste au sein de DynamoDBMapper utilise la prise en charge de suppression et de mise à jour conditionnelles fournie par DynamoDB. Désactivation du verrouillage optimiste Pour désactiver le verrouillage optimiste, vous pouvez changer la valeur d'énumération DynamoDBMapperConfig.SaveBehavior de UPDATE à CLOBBER. Vous pouvez le faire en créant une instance DynamoDBMapperConfig qui ignore la vérification de version et utilise cette instance pour toutes vos demandes. Pour plus d'informations sur les paramètres DynamoDBMapperConfig.SaveBehavior et autres paramètres facultatifs DynamoDBMapper, consultez Paramètres de configuration facultatifs pour DynamoDBMapper (p. 95). Vous pouvez également définir le comportement de verrouillage pour une opération spécifique uniquement. Par exemple, l'extrait de Java suivant utilise le DynamoDBMapper pour enregistrer un élément de catalogue. Il spécifie DynamoDBMapperConfig.SaveBehavior en ajoutant le paramètre DynamoDBMapperConfig facultatif à la méthode save. DynamoDBMapper mapper = new DynamoDBMapper(client); // Load a catalog item. CatalogItem item = mapper.load(CatalogItem.class, 101); item.setTitle("This is a new title for the item"); ... // Save the item. mapper.save(item, new DynamoDBMapperConfig( DynamoDBMapperConfig.SaveBehavior.CLOBBER)); Mappage des données arbitraires En plus des types Java pris en charge (voir Types de données pris en charge (p. 82)), vous pouvez utiliser des types dans votre application pour lesquels il n'y a pas de mappage direct avec les types DynamoDB. Pour mapper ces types, vous devez fournir une implémentation qui convertisse votre type complexe en une instance de String et vice versa et annoter la méthode accesseur de type complexe en utilisant l'annotation @DynamoDBTypeConverted. Le code de convertisseur transforme les données lorsque des objets sont enregistrés ou chargés. Il est également utilisé pour toutes les API Version 2012-08-10 113 Amazon DynamoDB Manuel du développeur Java : DynamoDBMapper opérations qui utilisent des types complexes. Veuillez noter que lors de la comparaison de données pendant des opérations d'interrogation et d'analyse, les comparaisons sont faites par rapport aux données stockées dans DynamoDB. Par exemple, envisagez la classe CatalogItem suivante qui définit une propriété, Dimension, qui est de DimensionType. Cette propriété stocke les dimensions de l'élément, telles que la hauteur, la largeur et l'épaisseur. Supposons que vous décidiez de stocker ces dimensions d'élément sous forme de chaîne (par exemple, 8,5x11x0,05) dans DynamoDB. L'exemple suivant fournit un code de convertisseur qui convertit l'objet DimensionType en une chaîne et une chaîne en DimensionType. Note Cet exemple de code suppose que vous ayez déjà chargé des données dans DynamoDB pour votre compte en suivant les instructions de la section Création de tables et chargement d'exemples de données (p. 167). Pour obtenir les instructions pas à pas afin d'exécuter l'exemple suivant, consultez Exemples de Code Java (p. 173). package com.amazonaws.codesamples.datamodeling; import import import import java.io.IOException; java.util.Arrays; java.util.HashSet; java.util.Set; import import import import import import import import import import import com.amazonaws.AmazonClientException; com.amazonaws.auth.AWSCredentials; com.amazonaws.auth.profile.ProfileCredentialsProvider; com.amazonaws.regions.Regions; com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient; com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBAttribute; com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBHashKey; com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper; com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTypeConverted; com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTypeConverter; com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBTable; public class DynamoDBMapperExample { static AmazonDynamoDBClient client; public static void main(String[] args) throws IOException { AWSCredentials credentials = null; try { credentials = new ProfileCredentialsProvider("default").getCredentials(); } catch (Exception e) { throw new AmazonClientException( "Cannot load the credentials from the credential profiles file. " + "Please make sure that your credentials file is at the correct " + "location, and is in valid format.", e); } API Version 2012-08-10 114 Amazon DynamoDB Manuel du développeur Java : DynamoDBMapper // Set the AWS region you want to access. Regions usWest2 = Regions.US_WEST_2; client = new AmazonDynamoDBClient(credentials).withRegion(usWest2); DimensionType dimType = new DimensionType(); dimType.setHeight("8.00"); dimType.setLength("11.0"); dimType.setThickness("1.0"); Book book = new Book(); book.setId(502); book.setTitle("Book 502"); book.setISBN("555-5555555555"); book.setBookAuthors(new HashSet<String>(Arrays.asList("Author1", "Author2"))); book.setDimensions(dimType); DynamoDBMapper mapper = new DynamoDBMapper(client); mapper.save(book); Book bookRetrieved = mapper.load(Book.class, 502); System.out.println("Book info: " + "\n" + bookRetrieved); bookRetrieved.getDimensions().setHeight("9.0"); bookRetrieved.getDimensions().setLength("12.0"); bookRetrieved.getDimensions().setThickness("2.0"); mapper.save(bookRetrieved); bookRetrieved = mapper.load(Book.class, 502); System.out.println("Updated book info: " + "\n" + bookRetrieved); } @DynamoDBTable(tableName="ProductCatalog") public static class Book { private int id; private String title; private String ISBN; private Set<String> bookAuthors; private DimensionType dimensionType; //Partition key @DynamoDBHashKey(attributeName = "Id") public int getId() { return id; } public void setId(int id) { this.id = id; } @DynamoDBAttribute(attributeName = "Title") public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } @DynamoDBAttribute(attributeName="ISBN") public String getISBN() { return ISBN; } public void setISBN(String ISBN) { this.ISBN = ISBN;} @DynamoDBAttribute(attributeName = "Authors") public Set<String> getBookAuthors() { return bookAuthors; } public void setBookAuthors(Set<String> bookAuthors) { this.bookAuthors = bookAuthors; } API Version 2012-08-10 115 Amazon DynamoDB Manuel du développeur Java : DynamoDBMapper @DynamoDBTypeConverted(converter = DimensionTypeConverter.class) @DynamoDBAttribute(attributeName = "Dimensions") public DimensionType getDimensions() { return dimensionType; } @DynamoDBAttribute(attributeName = "Dimensions") public void setDimensions(DimensionType dimensionType) { this.dimensionType = dimensionType; } @Override public String toString() { return "Book [ISBN=" + ISBN + ", bookAuthors=" + bookAuthors + ", dimensionType= " + dimensionType.getHeight() + " X " + dimensionType.getLength() + " X " + dimensionType.getThickness() + ", Id=" + id + ", Title=" + title + "]"; } } static public class DimensionType { private String length; private String height; private String thickness; public String getLength() { return length; } public void setLength(String length) { this.length = length; } public String getHeight() { return height; } public void setHeight(String height) { this.height = height; } public String getThickness() { return thickness; } public void setThickness(String thickness) { this.thickness = thickness; } } // Converts the complex type DimensionType to a string and vice-versa. static public class DimensionTypeConverter implements DynamoDBTypeConverter<String,DimensionType> { @Override public String convert(DimensionType object) { DimensionType itemDimensions = (DimensionType)object; String dimension = null; try { if (itemDimensions != null) { dimension = String.format("%s x %s x %s", itemDimensions.getLength(), itemDimensions.getHeight(), itemDimensions.getThickness()); } } catch (Exception e) { e.printStackTrace(); } return dimension; } @Override public DimensionType unconvert(String s) { API Version 2012-08-10 116 Amazon DynamoDB Manuel du développeur .NET : Modèle de document DimensionType itemDimension = new DimensionType(); try { if (s != null && s.length() !=0 ) { String[] data = s.split("x"); itemDimension.setLength(data[0].trim()); itemDimension.setHeight(data[1].trim()); itemDimension.setThickness(data[2].trim()); } } catch (Exception e) { e.printStackTrace(); } return itemDimension; } } } .NET : Modèle de document Rubriques • Opérations non prises en charge par le modèle de document (p. 117) • Utilisation des éléments dans DynamoDB à l'aide du modèle de document du kit SDK AWS pour .NET (p. 117) • Obtention d'un élément - Table.GetItem (p. 121) • Suppression d'un élément - Table.DeleteItem (p. 122) • Mise à jour d'un élément - Table.UpdateItem (p. 123) • Ecriture par lots - Insertion et suppression de plusieurs éléments (p. 125) • Exemple : Opérations CRUD à l'aide du modèle de document du kit SDK AWS pour .NET (p. 126) • Exemple : Opérations par lots à l'aide de l'API du modèle de document du kit SDK AWS pour .NET (p. 130) • Interrogation des tables dans DynamoDB à l'aide du modèle de document du kit SDK AWS pour .NET (p. 132) Le kit SDK AWS pour .NET fournit des classes de modèle de document qui enveloppent certaines opérations DynamoDB de bas niveau pour simplifier davantage votre codage. Dans le modèle de document, les classes principales sont Table et Document. La classe Table fournit des méthodes d'opération de données telles que PutItem, GetItem et DeleteItem. Elle fournit aussi les méthodes Query et Scan. La classe Document représente un seul élément d'une table. Les classes de modèle de document précédentes sont disponibles dans l'espace de noms Amazon.DynamoDBv2.DocumentModel. Opérations non prises en charge par le modèle de document Vous ne pouvez pas utiliser les classes de modèle de document pour créer, mettre à jour et supprimer des tables. Cependant, le modèle de document ne prend pas en charge les opérations de données les plus courantes. Utilisation des éléments dans DynamoDB à l'aide du modèle de document du kit SDK AWS pour .NET Rubriques API Version 2012-08-10 117 Amazon DynamoDB Manuel du développeur .NET : Modèle de document • Insertion d'un élément - Méthode Table.PutItem (p. 119) • Spécification de paramètres facultatifs (p. 120) Pour effectuer les opérations de données à l'aide du modèle de document, vous devez d'abord appeler la méthode Table.LoadTable, qui crée une instance de la classe Table qui représente une table spécifique. L'extrait de code C# suivant crée un objet Table qui représente la table ProductCatalog dans DynamoDB. Table table = Table.LoadTable(client, "ProductCatalog"); Note En général, vous utilisez la méthode LoadTable une fois au début de votre application, car elle exécute un appel DescribeTable qui s'ajoute à l'aller-retour vers DynamoDB. Vous pouvez ensuite utiliser l'objet table pour exécuter différentes opérations de données. Chacune de ces opérations de données ont deux types de surcharge : l'un qui prend les paramètres requis minimum et un autre qui prend également les informations de configuration facultatives propres à l'opération. Par exemple, pour récupérer un élément, vous devez fournir la valeur de clé primaire de la table, auquel cas, vous pouvez utiliser la surcharge GetItem suivante : // Get the item from a table that has a primary key that is composed of only a partition key. Table.GetItem(Primitive partitionKey); // Get the item from a table whose primary key is composed of both a partition key and sort key. Table.GetItem(Primitive partitionKey, Primitive sortKey); Vous pouvez aussi passer des paramètres facultatifs à ces méthodes. Par exemple, le GetItem précédent retourne l'élément entier, y compris tous ses attributs. Vous pouvez spécifier le cas échéant une liste d'attributs à extraire. Dans ce cas, vous utilisez la surcharge GetItem suivante qui accepte le paramètre d'objet de configuration spécifique à l'opération : // Configuration object that specifies optional parameters. GetItemOperationConfig config = new GetItemOperationConfig() { AttributesToGet = new List<string>() { "Id", "Title" }, }; // Pass in the configuration to the GetItem method. // 1. Table that has only a partition key as primary key. Table.GetItem(Primitive partitionKey, GetItemOperationConfig config); // 2. Table that has both a partition key and a sort key. Table.GetItem(Primitive partitionKey, Primitive sortKey, GetItemOperationConfig config); Vous pouvez utiliser l'objet de configuration pour spécifier plusieurs paramètres facultatifs, tels que la demande d'une liste spécifique d'attributs ou la spécification de la taille de la page (nombre d'éléments par page). Chaque méthode d'opération de données a sa propre classe de configuration. Par exemple, la classe GetItemOperationConfig vous permet de fournir des options pour l'opération GetItem et la classe PutItemOperationConfig vous permet de fournir des paramètres facultatifs pour l'opération PutItem. API Version 2012-08-10 118 Amazon DynamoDB Manuel du développeur .NET : Modèle de document Les sections suivantes décrivent chacune des opérations de données qui sont prises en charge par la classe Table. Insertion d'un élément - Méthode Table.PutItem La méthode PutItem charge l'instance Document en entrée sur la table. Si un élément ayant une clé primaire spécifiée dans l'instance Document en entrée existe dans la table, l'opération PutItem remplace la totalité de l'élément existant. Le nouvel élément est identique à l'objet Document que vous fournissez à la méthode PutItem. Notez que cela signifie que si votre élément d'origine a des attributs supplémentaires, ceux-ci ne sont plus présents dans le nouvel élément. Voici les étapes à suivre pour insérer un nouvel élément dans une table à l'aide du modèle de document du kit SDK AWS pour .NET. 1. Exécutez la méthode Table.LoadTable qui fournit le nom de la table dans laquelle vous voulez insérer un élément. 2. Créez un objet Document qui a une liste de noms d'attribut et de leurs valeurs. 3. Exécutez Table.PutItem en fournissant l'instance Document comme paramètre. L'exemple de code C# suivant illustre les tâches précédentes. L'exemple charge un élément sur la table ProductCatalog. Table table = Table.LoadTable(client, "ProductCatalog"); var book = new Document(); book["Id"] = 101; book["Title"] = "Book 101 Title"; book["ISBN"] = "11-11-11-11"; book["Authors"] = new List<string> { "Author 1", "Author 2" }; book["InStock"] = new DynamoDBBool(true); book["QuantityOnHand"] = new DynamoDBNull(); table.PutItem(book); Dans l'exemple précédent, l'instance Document crée un élément qui comporte les attributs Number, String, String Set, Boolean et Null. (Null est utilisé pour indiquer que la QuantityOnHand de ce produit est inconnue.) Pour Boolean et Null, utilisez les méthodes constructeur DynamoDBBool et DynamoDBNull. Dans DynamoDB, les types de données List et Map peuvent contenir des éléments composés d'autres types de données. Voici comment mapper ces types de données à l'API du modèle de document : • List : utilisez le constructeur DynamoDBList. • Map : utilisez le constructeur Document. Vous pouvez modifier l'exemple précédent pour ajouter un attribut List à l'élément. Pour ce faire, utilisez un constructeur DynamoDBList, comme illustré dans l'extrait de code suivant : Table table = Table.LoadTable(client, "ProductCatalog"); var book = new Document(); book["Id"] = 101; /*other attributes omitted for brevity...*/ API Version 2012-08-10 119 Amazon DynamoDB Manuel du développeur .NET : Modèle de document var relatedItems = new DynamoDBList(); relatedItems.Add(341); relatedItems.Add(472); relatedItems.Add(649); item.Add("RelatedItems", relatedItems); table.PutItem(book); Pour ajouter un attribut Map à l'élément « book », vous définissez un autre Document. L'extrait de code suivant montre comment procéder. Table table = Table.LoadTable(client, "ProductCatalog"); var book = new Document(); book["Id"] = 101; /*other attributes omitted for brevity...*/ var pictures = new Document(); pictures.Add("FrontView", "http://example.com/products/101_front.jpg" ); pictures.Add("RearView", "http://example.com/products/101_rear.jpg" ); item.Add("Pictures", pictures); table.PutItem(book); Ces exemples sont basés sur l'élément affiché dans Etude de cas : Un élément ProductCatalog (p. 212). Le modèle de document vous permet de créer des attributs imbriqués, tels que l'attribut ProductReviews illustré dans l'étude de cas. Spécification de paramètres facultatifs Vous pouvez configurer des paramètres facultatifs pour l'opération PutItem en ajoutant le paramètre PutItemOperationConfig. Pour obtenir une liste complète des paramètres facultatifs, consultez PutItem. L'extrait de code C# suivant insère un élément dans la table ProductCatalog. Il spécifie le paramètre facultatif suivant : • Le paramètre ConditionalExpression pour en faire une demande d'insertion conditionnelle. L'exemple crée une expression spécifiant que l'attribut ISBN doit avoir une valeur spécifique, présente dans l'élément que vous remplacez. Table table = Table.LoadTable(client, "ProductCatalog"); var book = new Document(); book["Id"] = 555; book["Title"] = "Book 555 Title"; book["Price"] = "25.00"; book["ISBN"] = "55-55-55-55"; book["Name"] = "Item 1 updated"; book["Authors"] = new List<string> { "Author x", "Author y" }; book["InStock"] = new DynamoDBBool(true); book["QuantityOnHand"] = new DynamoDBNull(); // Create a condition expression for the optional conditional put operation. API Version 2012-08-10 120 Amazon DynamoDB Manuel du développeur .NET : Modèle de document Expression expr = new Expression(); expr.ExpressionStatement = "ISBN = :val"; expr.ExpressionAttributeValues[":val"] = "55-55-55-55"; PutItemOperationConfig config = new PutItemOperationConfig() { // Optional parameter. ConditionalExpression = expr }; table.PutItem(book, config); Obtention d'un élément - Table.GetItem L'opération GetItem récupère un élément comme instance Document. Vous devez fournir la clé primaire de l'élément que vous souhaitez récupérer, comme illustré dans l'extrait de code C# suivant : Table table = Table.LoadTable(client, "ProductCatalog"); Document document = table.GetItem(101); // Primary key 101. L'opération GetItem retourne tous les attributs de l'élément et effectue une lecture cohérente à terme (voir Cohérence en lecture (p. 16)) par défaut. Spécification de paramètres facultatifs Vous pouvez configurer des options supplémentaires pour l'opération GetItem en ajoutant le paramètre GetItemOperationConfig. Pour obtenir la liste complète des paramètres facultatifs, consultez GetItem. L'extrait de code C# suivant récupère un élément de la table ProductCatalog. Il spécifie le paramètre GetItemOperationConfig pour fournir les paramètres facultatifs suivants : • Le paramètre AttributesToGet pour récupérer uniquement les attributs spécifiés. • Le paramètre ConsistentRead pour demander les dernières valeurs de tous les attributs spécifiés. Pour en savoir plus sur la cohérence des données, consultez Cohérence en lecture (p. 16). Table table = Table.LoadTable(client, "ProductCatalog"); GetItemOperationConfig config = new GetItemOperationConfig() { AttributesToGet = new List<string>() { "Id", "Title", "Authors", "InStock", "QuantityOnHand" }, ConsistentRead = true }; Document doc = table.GetItem(101, config); Lorsque vous récupérez un élément à l'aide de l'API de modèle de document, vous pouvez accéder aux éléments individuels de l'objet Document retourné : int id = doc["Id"].AsInt(); string title = doc["Title"].AsString(); List<string> authors = doc["Authors"].AsListOfString(); bool inStock = doc["InStock"].AsBoolean(); API Version 2012-08-10 121 Amazon DynamoDB Manuel du développeur .NET : Modèle de document DynamoDBNull quantityOnHand = doc["QuantityOnHand"].AsDynamoDBNull(); Pour les attributs qui sont de type List ou Map, voici comment mapper ces attributs à l'API de modèle de document : • List : utilisez la méthode AsDynamoDBList. • Map : utilisez la méthode AsDocument. L'extrait de code suivant montre comment récupérer une List (RelatedItems) et une Map (Pictures) à partir de l'objet Document : DynamoDBList relatedItems = doc["RelatedItems"].AsDynamoDBList(); Document pictures = doc["Pictures"].AsDocument(); Suppression d'un élément - Table.DeleteItem L'opération DeleteItem supprime un élément d'une table. Vous pouvez passer la clé primaire de l'élément comme paramètre ou si vous avez lu déjà un élément et que vous avez l'objet Document correspondant, vous pouvez le passer comme paramètre à la méthode DeleteItem, tel qu'illustré dans l'extrait de code C# suivant. Table table = Table.LoadTable(client, "ProductCatalog"); // Retrieve a book (a Document instance) Document document = table.GetItem(111); // 1) Delete using the Document instance. table.DeleteItem(document); // 2) Delete using the primary key. int partitionKey = 222; table.DeleteItem(partitionKey) Spécification de paramètres facultatifs Vous pouvez configurer des options supplémentaires pour l'opération Delete en ajoutant le paramètre DeleteItemOperationConfig. Pour obtenir la liste complète des paramètres facultatifs, consultez DeleteTable. L'extrait de code C# suivant spécifie les deux paramètres facultatifs suivants : • Le paramètre ConditionalExpression pour s'assurer que l'élément « book » en cours de suppression possède une valeur spécifique pour l'attribut ISBN. • Le paramètre ReturnValuespour demander que la méthode Delete retourne l'élément qu'elle a supprimé. Table table = Table.LoadTable(client, "ProductCatalog"); int partitionKey = 111; Expression expr = new Expression(); expr.ExpressionStatement = "ISBN = :val"; API Version 2012-08-10 122 Amazon DynamoDB Manuel du développeur .NET : Modèle de document expr.ExpressionAttributeValues[":val"] = "11-11-11-11"; // Specify optional parameters for Delete operation. DeleteItemOperationConfig config = new DeleteItemOperationConfig { ConditionalExpression = expr, ReturnValues = ReturnValues.AllOldAttributes // This is the only supported value when using the document model. }; // Delete the book. Document d = table.DeleteItem(partitionKey, config); Mise à jour d'un élément - Table.UpdateItem L'opération UpdateItem met à jour un élément existant s'il est présent. Si l'élément qui possède la clé primaire spécifiée est introuvable, l'opération UpdateItem ajoute un nouvel élément. Vous pouvez utiliser l'opération UpdateItem pour mettre à jour les valeurs d'attribut existantes, ajouter de nouveaux attributs à la collection existante ou supprimer des attributs de la collection existante. Vous fournissez ces mises à jour en créant une instance Document qui décrit les mises à jour que vous souhaitez effectuer. L'action UpdateItem utilise les directives suivantes : • Si l'élément n'existe pas, UpdateItem ajoute un nouvel élément à l'aide de la clé primaire spécifiée dans l'entrée. • Si l'élément existe, UpdateItem applique les mises à jour comme suit : • Remplace les valeurs d'attribut existantes par les valeurs de la mise à jour. • Si un attribut que vous fournissez en entrée n'existe pas, un nouvel attribut est ajouté à l'élément. • Si l'attribut en entrée a la valeur null, il est supprimé s'il est présent. Note Cette opération UpdateItem de niveau intermédiaire ne prend pas en charge l'action Add (voir UpdateItem) prise en charge par l'opération DynamoDB sous-jacente. Note L'opération PutItem (Insertion d'un élément - Méthode Table.PutItem (p. 119)) peut aussi exécuter une mise à jour. Si vous appelez PutItem pour charger un élément et que la clé primaire existe, l'opération PutItem remplace la totalité de l'élément. Notez que, s'il existe des attributs dans l'élément existant et qu'ils ne sont pas spécifiés sur l'élément Document en cours d'insertion, l'opération PutItem supprime ces attributs. Toutefois, UpdateItem ne met à jour que les attributs spécifiés en entrée. Tous les autres attributs de cet élément demeurent inchangés. Voici les étapes pour mettre à jour un élément à l'aide du modèle de document du kit SDK AWS pour .NET. 1. Exécutez la méthode Table.LoadTable en fournissant le nom de la table dans laquelle vous souhaitez effectuer l'opération de mise à jour. API Version 2012-08-10 123 Amazon DynamoDB Manuel du développeur .NET : Modèle de document 2. Créez une instance Document en fournissant toutes les mises à jour que vous souhaitez effectuer. Pour supprimer un attribut existant, spécifiez la valeur d'attribut comme null. 3. Appelez la méthode Table.UpdateItem et fournissez l'instance Document comme paramètre d'entrée. Vous devez fournir la clé primaire dans l'instance Document ou explicitement comme paramètre. L'exemple de code C# suivant illustre les tâches précédentes. L'exemple de code met à jour un élément de la table Book. L'opération UpdateItem met à jour l'attribut Authors existant, supprime l'attribut PageCount et ajoute un nouvel attribut XYZ. L'instance Document inclut la clé primaire de l'élément « book » à mettre à jour. Table table = Table.LoadTable(client, "ProductCatalog"); var book = new Document(); // Set the attributes that you wish to update. book["Id"] = 111; // Primary key. // Replace the authors attribute. book["Authors"] = new List<string> { "Author x", "Author y" }; // Add a new attribute. book["XYZ"] = 12345; // Delete the existing PageCount attribute. book["PageCount"] = null; table.Update(book); Spécification de paramètres facultatifs Vous pouvez configurer des options supplémentaires pour l'opération UpdateItem en ajoutant le paramètre UpdateItemOperationConfig. Pour obtenir la liste complète des paramètres facultatifs, consultez UpdateItem. L'extrait de code C# suivant met à jour le prix d'un élément « book » avec la valeur 25. Il spécifie les deux paramètres facultatifs suivants : • Le paramètre ConditionalExpression qui identifie l'attribut Price avec la valeur 20 dont vous attendez la présence. • Le paramètre ReturnValues pour demander que l'opération UpdateItem retourne l'élément qui est mis à jour. Table table = Table.LoadTable(client, "ProductCatalog"); string partitionKey = "111"; var book = new Document(); book["Id"] = partitionKey; book["Price"] = 25; Expression expr = new Expression(); expr.ExpressionStatement = "Price = :val"; expr.ExpressionAttributeValues[":val"] = 20"; UpdateOperationConfig config = new UpdateOperationConfig() { API Version 2012-08-10 124 Amazon DynamoDB Manuel du développeur .NET : Modèle de document ConditionalExpression = expr, ReturnValues = ReturnValues.AllOldAttributes }; Document d1 = table.Update(book, config); Ecriture par lots - Insertion et suppression de plusieurs éléments L'écriture par lots fait référence à l'insertion et la suppression de plusieurs éléments dans un lot. L'opération vous permet d'insérer et de supprimer plusieurs éléments d'une ou de plusieurs tables en un seul appel. Voici les étapes pour insérer ou supprimer plusieurs éléments d'une table à l'aide de l'API de modèle de document du kit SDK AWS pour .NET. 1. Créez un objet Table en exécutant la méthode Table.LoadTable en fournissant le nom de la table dans laquelle vous souhaitez effectuer l'opération de traitement par lots. 2. Exécutez la méthode CreateBatchWrite sur l'instance de table que vous avez créée à l'étape précédente et créez l'objet DocumentBatchWrite. 3. Utilisez les méthodes de l'objet DocumentBatchWrite pour spécifier les documents que vous souhaitez charger ou supprimer. 4. Appelez la méthode DocumentBatchWrite.Execute pour exécuter l'opération de traitement par lots. Lorsque vous utilisez l'API de modèle de document, vous pouvez spécifier un nombre quelconque d'opérations dans un lot. Cependant, notez que DynamoDB limite le nombre d'opérations d'un lot et la taille totale du lot dans une opération de traitement par lots. Pour plus d'informations sur les limites spécifiques, consultez BatchWriteItem. Si l'API de modèle de document détecte que votre demande d'écriture par lots a dépassé le nombre de requêtes d'écriture autorisé ou que la taille de charge utile HTTP d'un traitement par lots a dépassé la limite autorisée par BatchWriteItem, il scinde le lot en plusieurs lots plus petits. En outre, si une réponse à une écriture par lots retourne des éléments non traités, l'API de modèle de document envoie automatiquement une autre demande par lots avec les éléments non traités. L'extrait de code C# suivant illustre les étapes précédentes. L'extrait de code utilise l'opération d'écriture par lots afin d'effectuer deux écritures ; charger un élément « book » et supprimer un autre élément « book ». Table productCatalog = Table.LoadTable(client, "ProductCatalog"); var batchWrite = productCatalog.CreateBatchWrite(); var book1 = new Document(); book1["Id"] = 902; book1["Title"] = "My book1 in batch write using .NET document model"; book1["Price"] = 10; book1["Authors"] = new List<string> { "Author 1", "Author 2", "Author 3" }; book1["InStock"] = new DynamoDBBool(true); book1["QuantityOnHand"] = 5; batchWrite.AddDocumentToPut(book1); // specify delete item using overload that takes PK. batchWrite.AddKeyToDelete(12345); batchWrite.Execute(); API Version 2012-08-10 125 Amazon DynamoDB Manuel du développeur .NET : Modèle de document Pour obtenir un exemple pratique, consultez Exemple : Opérations par lots à l'aide de l'API du modèle de document du kit SDK AWS pour .NET (p. 130). Vous pouvez utiliser l'opération d'écriture par lots pour effectuer des opérations d'insertion et de suppression sur plusieurs tables. Voici les étapes pour insérer ou supprimer plusieurs éléments de différentes table à l'aide du modèle de document du kit SDK AWS pour .NET. 1. Vous créez une instance DocumentBatchWrite pour chaque table dans laquelle vous voulez insérer ou supprimer plusieurs éléments, comme décrit dans la procédure précédente. 2. Créez une instance de l'élément MultiTableDocumentBatchWrite et ajoutez-y les objets DocumentBatchWrite. 3. Exécutez la méthode MultiTableDocumentBatchWrite.Execute. L'extrait de code C# suivant illustre les étapes précédentes. L'extrait de code utilise l'opération d'écriture par lots pour effectuer les opérations d'écriture suivantes : • Placer un nouvel élément dans l'élément de table Forum • Placer un élément dans la table Thread et supprimer un élément de la même table. // 1. Specify item to add in the Forum table. Table forum = Table.LoadTable(client, "Forum"); var forumBatchWrite = forum.CreateBatchWrite(); var forum1 = new Document(); forum1["Name"] = "Test BatchWrite Forum"; forum1["Threads"] = 0; forumBatchWrite.AddDocumentToPut(forum1); // 2a. Specify item to add in the Thread table. Table thread = Table.LoadTable(client, "Thread"); var threadBatchWrite = thread.CreateBatchWrite(); var thread1 = new Document(); thread1["ForumName"] = "Amazon S3 forum"; thread1["Subject"] = "My sample question"; thread1["Message"] = "Message text"; thread1["KeywordTags"] = new List<string>{ "Amazon S3", "Bucket" }; threadBatchWrite.AddDocumentToPut(thread1); // 2b. Specify item to delete from the Thread table. threadBatchWrite.AddKeyToDelete("someForumName", "someSubject"); // 3. Create multi-table batch. var superBatch = new MultiTableDocumentBatchWrite(); superBatch.AddBatch(forumBatchWrite); superBatch.AddBatch(threadBatchWrite); superBatch.Execute(); Exemple : Opérations CRUD à l'aide du modèle de document du kit SDK AWS pour .NET L'exemple de code C# suivant exécute les actions suivantes : API Version 2012-08-10 126 Amazon DynamoDB Manuel du développeur .NET : Modèle de document • Créer un élément book dans la table ProductCatalog. • Récupérer l'élément book. • Mettre à jour l'élément book. L'exemple de code présente une mise à jour normale qui ajoute les nouveaux attributs et met à jour les attributs existants. Il présente également une mise à jour conditionnelle qui ne met à jour le prix de l'élément « book » que si la valeur de prix existante est telle que spécifiée dans le code. • Supprimer l'élément book. Pour obtenir les instructions pas à pas afin de tester l'exemple suivant, consultez Exemples de code .NET (p. 175). using using using using using using System; System.Collections.Generic; System.Linq; Amazon.DynamoDBv2; Amazon.DynamoDBv2.DocumentModel; Amazon.Runtime; namespace com.amazonaws.codesamples { class MidlevelItemCRUD { private static AmazonDynamoDBClient client = new AmazonDynamoDBClient(); private static string tableName = "ProductCatalog"; // The sample uses the following id PK value to add book item. private static int sampleBookId = 555; static void Main(string[] args) { try { Table productCatalog = Table.LoadTable(client, tableName); CreateBookItem(productCatalog); RetrieveBook(productCatalog); // Couple of sample updates. UpdateMultipleAttributes(productCatalog); UpdateBookPriceConditionally(productCatalog); // Delete. DeleteBook(productCatalog); Console.WriteLine("To continue, press Enter"); Console.ReadLine(); } catch (AmazonDynamoDBException e) { Console.WriteLine(e.Message); } catch (AmazonServiceException e) { Console.WriteLine(e.Message); } catch (Exception e) { Console.WriteLine(e.Message); } } // Creates a sample book item. private static void CreateBookItem(Table productCatalog) { Console.WriteLine("\n*** Executing CreateBookItem() ***"); var book = new Document(); book["Id"] = sampleBookId; API Version 2012-08-10 127 Amazon DynamoDB Manuel du développeur .NET : Modèle de document book["Title"] = "Book " + sampleBookId; book["Price"] = 19.99; book["ISBN"] = "111-1111111111"; book["Authors"] = new List<string> { "Author 1", "Author 2", "Author 3" }; book["PageCount"] = 500; book["Dimensions"] = "8.5x11x.5"; book["InPublication"] = new DynamoDBBool(true); book["InStock"] = new DynamoDBBool(false); book["QuantityOnHand"] = 0; productCatalog.PutItem(book); } private static void RetrieveBook(Table productCatalog) { Console.WriteLine("\n*** Executing RetrieveBook() ***"); // Optional configuration. GetItemOperationConfig config = new GetItemOperationConfig { AttributesToGet = new List<string> { "Id", "ISBN", "Title", "Authors", "Price" }, ConsistentRead = true }; Document document = productCatalog.GetItem(sampleBookId, config); Console.WriteLine("RetrieveBook: Printing book retrieved..."); PrintDocument(document); } private static void UpdateMultipleAttributes(Table productCatalog) { Console.WriteLine("\n*** Executing UpdateMultipleAttributes() ***"); Console.WriteLine("\nUpdating multiple attributes...."); int partitionKey = sampleBookId; var book = new Document(); book["Id"] = partitionKey; // List of attribute updates. // The following replaces the existing authors list. book["Authors"] = new List<string> { "Author x", "Author y" }; book["newAttribute"] = "New Value"; book["ISBN"] = null; // Remove it. // Optional parameters. UpdateItemOperationConfig config = new UpdateItemOperationConfig { // Get updated item in response. ReturnValues = ReturnValues.AllNewAttributes }; Document updatedBook = productCatalog.UpdateItem(book, config); Console.WriteLine("UpdateMultipleAttributes: Printing item after updates ..."); PrintDocument(updatedBook); } private static void UpdateBookPriceConditionally(Table productCatalog) { API Version 2012-08-10 128 Amazon DynamoDB Manuel du développeur .NET : Modèle de document Console.WriteLine("\n*** Executing UpdateBookPriceConditionally() ***"); int partitionKey = sampleBookId; var book = new Document(); book["Id"] = partitionKey; book["Price"] = 29.99; // For conditional price update, creating a condition expression. Expression expr = new Expression(); expr.ExpressionStatement = "Price = :val"; expr.ExpressionAttributeValues[":val"] = 19.00; // Optional parameters. UpdateItemOperationConfig config = new UpdateItemOperationConfig { ConditionalExpression = expr, ReturnValues = ReturnValues.AllNewAttributes }; Document updatedBook = productCatalog.UpdateItem(book, config); Console.WriteLine("UpdateBookPriceConditionally: Printing item whose price was conditionally updated"); PrintDocument(updatedBook); } private static void DeleteBook(Table productCatalog) { Console.WriteLine("\n*** Executing DeleteBook() ***"); // Optional configuration. DeleteItemOperationConfig config = new DeleteItemOperationConfig { // Return the deleted item. ReturnValues = ReturnValues.AllOldAttributes }; Document document = productCatalog.DeleteItem(sampleBookId, config); Console.WriteLine("DeleteBook: Printing deleted just deleted..."); PrintDocument(document); } private static void PrintDocument(Document updatedDocument) { foreach (var attribute in updatedDocument.GetAttributeNames()) { string stringValue = null; var value = updatedDocument[attribute]; if (value is Primitive) stringValue = value.AsPrimitive().Value.ToString(); else if (value is PrimitiveList) stringValue = string.Join(",", (from primitive in value.AsPrimitiveList().Entries select primitive.Value).ToArray()); Console.WriteLine("{0} - {1}", attribute, stringValue); } API Version 2012-08-10 129 Amazon DynamoDB Manuel du développeur .NET : Modèle de document } } } Exemple : Opérations par lots à l'aide de l'API du modèle de document du kit SDK AWS pour .NET Rubriques • Exemple : Ecriture par lots à l'aide du modèle de document du kit SDK AWS pour .NET (p. 130) Exemple : Ecriture par lots à l'aide du modèle de document du kit SDK AWS pour .NET L'exemple de code C# suivant illustre les opérations d'écriture par lots sur une seule table et sur plusieurs tables. L'exemple exécute les tâches suivantes : • Pour illustrer une écriture par lots sur une seule table, il ajoute deux éléments à la table ProductCatalog. • Pour illustrer une écriture par lots sur plusieurs tables, il ajoute un élément aux tables Forum et Thread, et supprime un élément de la table Thread. Si vous avez suivi les étapes de Création de tables et chargement d'exemples de données (p. 167), les tables ProductCatalog, Forum et Thread sont déjà créées. Vous pouvez aussi créer ces exemples de table par programmation. Pour de plus amples informations, veuillez consulter Création d'exemples de table et de chargement de données à l'aide du kit de développement (SDK) AWS pour .NET (p. 615). Pour obtenir les instructions pas à pas afin de tester l'exemple suivant, consultez Exemples de code .NET (p. 175). using using using using using System; System.Collections.Generic; Amazon.DynamoDBv2; Amazon.DynamoDBv2.DocumentModel; Amazon.Runtime; namespace com.amazonaws.codesamples { class MidLevelBatchWriteItem { private static AmazonDynamoDBClient client = new AmazonDynamoDBClient(); static void Main(string[] args) { try { SingleTableBatchWrite(); MultiTableBatchWrite(); } catch (AmazonDynamoDBException e) { Console.WriteLine(e.Message); } catch (AmazonServiceException e) { Console.WriteLine(e.Message); } catch (Exception e) { Console.WriteLine(e.Message); } Console.WriteLine("To continue, press Enter"); Console.ReadLine(); API Version 2012-08-10 130 Amazon DynamoDB Manuel du développeur .NET : Modèle de document } private static void SingleTableBatchWrite() { Table productCatalog = Table.LoadTable(client, "ProductCatalog"); var batchWrite = productCatalog.CreateBatchWrite(); var book1 = new Document(); book1["Id"] = 902; book1["Title"] = "My book1 in batch write using .NET helper classes"; book1["ISBN"] = "902-11-11-1111"; book1["Price"] = 10; book1["ProductCategory"] = "Book"; book1["Authors"] = new List<string> { "Author 1", "Author 2", "Author 3" }; book1["Dimensions"] = "8.5x11x.5"; book1["InStock"] = new DynamoDBBool(true); book1["QuantityOnHand"] = new DynamoDBNull(); //Quantity is unknown at this time batchWrite.AddDocumentToPut(book1); // Specify delete item using overload that takes PK. batchWrite.AddKeyToDelete(12345); Console.WriteLine("Performing batch write in SingleTableBatchWrite()"); batchWrite.Execute(); } private static void MultiTableBatchWrite() { // 1. Specify item to add in the Forum table. Table forum = Table.LoadTable(client, "Forum"); var forumBatchWrite = forum.CreateBatchWrite(); var forum1 = new Document(); forum1["Name"] = "Test BatchWrite Forum"; forum1["Threads"] = 0; forumBatchWrite.AddDocumentToPut(forum1); // 2a. Specify item to add in the Thread table. Table thread = Table.LoadTable(client, "Thread"); var threadBatchWrite = thread.CreateBatchWrite(); var thread1 = new Document(); thread1["ForumName"] = "S3 forum"; thread1["Subject"] = "My sample question"; thread1["Message"] = "Message text"; thread1["KeywordTags"] = new List<string> { "S3", "Bucket" }; threadBatchWrite.AddDocumentToPut(thread1); // 2b. Specify item to delete from the Thread table. threadBatchWrite.AddKeyToDelete("someForumName", "someSubject"); // 3. Create multi-table batch. var superBatch = new MultiTableDocumentBatchWrite(); superBatch.AddBatch(forumBatchWrite); superBatch.AddBatch(threadBatchWrite); API Version 2012-08-10 131 Amazon DynamoDB Manuel du développeur .NET : Modèle de document Console.WriteLine("Performing batch write in MultiTableBatchWrite()"); superBatch.Execute(); } } } Interrogation des tables dans DynamoDB à l'aide du modèle de document du kit SDK AWS pour .NET Rubriques • Méthode Table.Query dans le kit SDK AWS pour .NET (p. 132) • Méthode Table.Scan dans le kit SDK AWS pour .NET (p. 137) Méthode Table.Query dans le kit SDK AWS pour .NET La méthode Query vous permet d'interroger vos tables. Vous pouvez uniquement interroger les tables ayant une clé primaire composite (clé de partition et clé de tri). Si la clé primaire de votre table est constituée d'une seule clé de partition, l'opération Query n'est pas prise en charge. Par défaut, Query effectue en interne les requêtes qui sont cohérentes à terme. Pour en savoir plus sur le modèle de cohérence, consultez Cohérence en lecture (p. 16). La méthode Query fournit deux surcharges. Les paramètres requis minimum de la méthode Query sont une valeur de clé de partition et un filtre de clé de tri. Vous pouvez utiliser la surcharge suivante pour fournir ces paramètres requis minimum. Query(Primitive partitionKey, RangeFilter Filter); Par exemple, l'extrait de code C# suivant interroge toutes les réponses de forum publiées au cours des 15 derniers jours. string tableName = "Reply"; Table table = Table.LoadTable(client, tableName); DateTime twoWeeksAgoDate = DateTime.UtcNow - TimeSpan.FromDays(15); RangeFilter filter = new RangeFilter(QueryOperator.GreaterThan, twoWeeksAgoDate); Search search = table.Query("DynamoDB Thread 2", filter); Cela crée un objet Search. Vous pouvez maintenant appeler la méthode Search.GetNextSet de façon itérative pour récupérer une page de résultats à la fois, comme illustré dans l'extrait de code C# suivant. Le code affiche les valeurs d'attribut pour chaque élément que la requête retourne. List<Document> documentSet = new List<Document>(); do { documentSet = search.GetNextSet(); foreach (var document in documentSet) PrintDocument(document); } while (!search.IsDone); API Version 2012-08-10 132 Amazon DynamoDB Manuel du développeur .NET : Modèle de document private static void PrintDocument(Document document) { Console.WriteLine(); foreach (var attribute in document.GetAttributeNames()) { string stringValue = null; var value = document[attribute]; if (value is Primitive) stringValue = value.AsPrimitive().Value; else if (value is PrimitiveList) stringValue = string.Join(",", (from primitive in value.AsPrimitiveList().Entries select primitive.Value).ToArray()); Console.WriteLine("{0} - {1}", attribute, stringValue); } } Spécification de paramètres facultatifs Vous pouvez également spécifier des paramètres facultatifs pour Query, en spécifiant par exemple une liste d'attributs à récupérer, les lectures cohérentes à terme, la taille de page et le nombre d'éléments renvoyés par page. Pour obtenir une liste complète de paramètres, consultez Query. Pour spécifier des paramètres facultatifs, vous devez utiliser la surcharge suivante dans laquelle vous fournissez l'objet QueryOperationConfig. Query(QueryOperationConfig config); Supposons que vous vouliez exécuter la requête de l'exemple précédent (récupérer les réponses de forum publiées dans les 15 derniers jours). Cependant, supposons que vous souhaitiez fournir des paramètres de requête facultatifs pour récupérer uniquement des attributs spécifiques et demander également une lecture à cohérence forte. L'extrait de code C# suivant construit la demande à l'aide de l'objet QueryOperationConfig. Table table = Table.LoadTable(client, "Reply"); DateTime twoWeeksAgoDate = DateTime.UtcNow - TimeSpan.FromDays(15); QueryOperationConfig config = new QueryOperationConfig() { HashKey = "DynamoDB Thread 2", //Partition key AttributesToGet = new List<string> { "Subject", "ReplyDateTime", "PostedBy" }, ConsistentRead = true, Filter = new RangeFilter(QueryOperator.GreaterThan, twoWeeksAgoDate) }; Search search = table.Query(config); Exemple : Requête à l'aide de la méthode Table.Query L'exemple de code C# suivant utilise la méthode Table.Query pour exécuter les exemples de requêtes suivants : • Les requêtes suivantes sont exécutées sur la table Reply. • Recherchez les réponses des threads de forum qui ont été publiées dans les 15 derniers jours. Cette requête est exécutée deux fois. Dans le premier appel Table.Query, l'exemple fournit uniquement les paramètres de requête nécessaires. Dans le deuxième appel Table.Query, vous API Version 2012-08-10 133 Amazon DynamoDB Manuel du développeur .NET : Modèle de document fournissez les paramètres de requête facultatifs pour demander une lecture à cohérence forte et une liste d'attributs à récupérer. • Recherchez les réponses des threads de forum publiées pendant une période donnée. Cette requête utilise l'opérateur de requête Between pour trouver les réponses publiées entre deux dates. • Obtenez un produit de la table ProductCatalog. Comme la table ProductCatalog possède une clé primaire qui n'est qu'une clé de partition, vous pouvez obtenir uniquement des éléments ; vous ne pouvez pas interroger la table. L'exemple récupère un élément de produit spécifique à l'aide de l'Id de l'élément. using using using using using using using System; System.Collections.Generic; System.Linq; Amazon.DynamoDBv2; Amazon.DynamoDBv2.DocumentModel; Amazon.Runtime; Amazon.SecurityToken; namespace com.amazonaws.codesamples { class MidLevelQueryAndScan { private static AmazonDynamoDBClient client = new AmazonDynamoDBClient(); static void Main(string[] args) { try { // Query examples. Table replyTable = Table.LoadTable(client, "Reply"); string forumName = "Amazon DynamoDB"; string threadSubject = "DynamoDB Thread 2"; FindRepliesInLast15Days(replyTable, forumName, threadSubject); FindRepliesInLast15DaysWithConfig(replyTable, forumName, threadSubject); FindRepliesPostedWithinTimePeriod(replyTable, forumName, threadSubject); // Get Example. Table productCatalogTable = Table.LoadTable(client, "ProductCatalog"); int productId = 101; GetProduct(productCatalogTable, productId); Console.WriteLine("To continue, press Enter"); Console.ReadLine(); } catch (AmazonDynamoDBException e) { Console.WriteLine(e.Message); } catch (AmazonServiceException e) { Console.WriteLine(e.Message); } catch (Exception e) { Console.WriteLine(e.Message); } } API Version 2012-08-10 134 Amazon DynamoDB Manuel du développeur .NET : Modèle de document private static void GetProduct(Table tableName, int productId) { Console.WriteLine("*** Executing GetProduct() ***"); Document productDocument = tableName.GetItem(productId); if (productDocument != null) { PrintDocument(productDocument); } else { Console.WriteLine("Error: product " + productId + " does not exist"); } } private static void FindRepliesInLast15Days(Table table, string forumName, string threadSubject) { string Attribute = forumName + "#" + threadSubject; DateTime twoWeeksAgoDate = DateTime.UtcNow TimeSpan.FromDays(15); QueryFilter filter = new QueryFilter("Id", QueryOperator.Equal, partitionKey); filter.AddCondition("ReplyDateTime", QueryOperator.GreaterThan, twoWeeksAgoDate); // Use Query overloads that takes the minimum required query parameters. Search search = table.Query(filter); List<Document> documentSet = new List<Document>(); do { documentSet = search.GetNextSet(); Console.WriteLine("\nFindRepliesInLast15Days: printing ............"); foreach (var document in documentSet) PrintDocument(document); } while (!search.IsDone); } private static void FindRepliesPostedWithinTimePeriod(Table table, string forumName, string threadSubject) { DateTime startDate = DateTime.UtcNow.Subtract(new TimeSpan(21, 0, 0, 0)); DateTime endDate = DateTime.UtcNow.Subtract(new TimeSpan(1, 0, 0, 0)); QueryFilter filter = new QueryFilter("Id", QueryOperator.Equal, forumName + "#" + threadSubject); filter.AddCondition("ReplyDateTime", QueryOperator.Between, startDate, endDate); QueryOperationConfig config = new QueryOperationConfig() { Limit = 2, // 2 items/page. Select = SelectValues.SpecificAttributes, AttributesToGet = new List<string> { "Message", "ReplyDateTime", "PostedBy" }, API Version 2012-08-10 135 Amazon DynamoDB Manuel du développeur .NET : Modèle de document ConsistentRead = true, Filter = filter }; Search search = table.Query(config); List<Document> documentList = new List<Document>(); do { documentList = search.GetNextSet(); Console.WriteLine("\nFindRepliesPostedWithinTimePeriod: printing replies posted within dates: {0} and {1} ............", startDate, endDate); foreach (var document in documentList) { PrintDocument(document); } } while (!search.IsDone); } private static void FindRepliesInLast15DaysWithConfig(Table table, string forumName, string threadName) { DateTime twoWeeksAgoDate = DateTime.UtcNow TimeSpan.FromDays(15); QueryFilter filter = new QueryFilter("Id", QueryOperator.Equal, forumName + "#" + threadName); filter.AddCondition("ReplyDateTime", QueryOperator.GreaterThan, twoWeeksAgoDate); // You are specifying optional parameters so use QueryOperationConfig. QueryOperationConfig config = new QueryOperationConfig() { Filter = filter, // Optional parameters. Select = SelectValues.SpecificAttributes, AttributesToGet = new List<string> { "Message", "ReplyDateTime", "PostedBy" }, ConsistentRead = true }; Search search = table.Query(config); List<Document> documentSet = new List<Document>(); do { documentSet = search.GetNextSet(); Console.WriteLine("\nFindRepliesInLast15DaysWithConfig: printing ............"); foreach (var document in documentSet) PrintDocument(document); } while (!search.IsDone); } private static void PrintDocument(Document document) { // count++; API Version 2012-08-10 136 Amazon DynamoDB Manuel du développeur .NET : Modèle de document Console.WriteLine(); foreach (var attribute in document.GetAttributeNames()) { string stringValue = null; var value = document[attribute]; if (value is Primitive) stringValue = value.AsPrimitive().Value.ToString(); else if (value is PrimitiveList) stringValue = string.Join(",", (from primitive in value.AsPrimitiveList().Entries select primitive.Value).ToArray()); Console.WriteLine("{0} - {1}", attribute, stringValue); } } } } Méthode Table.Scan dans le kit SDK AWS pour .NET La méthode Scan effectue une analyse complète de la table. Elle fournit deux surcharges. Le seul paramètre requis par la méthode Scan est le filtre d'analyse que vous pouvez fournir à l'aide de la surcharge suivante. Scan(ScanFilter filter); Par exemple, supposons que vous mainteniez une table de threads de forum suivant des informations telles que l'objet (principal) du thread, le message associé, l'ID de forum auquel le thread appartient, les balises et autres informations. Supposons que l'objet soit la clé primaire. Thread(Subject, Message, ForumId, Tags, LastPostedDateTime, .... ) Il s'agit d'une version simplifiée des forums et des threads que vous voyez sur les forums AWS (consultez Forums de discussion). L'extrait de code C# suivant interroge tous les threads d'un forum spécifique (ForumId = 101) marqués « sortkey ». Etant donné que ForumId n'est pas une clé primaire, l'exemple analyse la table. Le ScanFilter inclut deux conditions. La requête retourne tous les threads qui satisfont aux deux conditions. string tableName = "Thread"; Table ThreadTable = Table.LoadTable(client, tableName); ScanFilter scanFilter = new ScanFilter(); scanFilter.AddCondition("ForumId", ScanOperator.Equal, 101); scanFilter.AddCondition("Tags", ScanOperator.Contains, "sortkey"); Search search = ThreadTable.Scan(scanFilter); Spécification de paramètres facultatifs Vous pouvez également spécifier des paramètres facultatifs pour Scan, tels qu'une liste spécifique d'attributs à extraire ou l'exécution ou non d'une lecture à cohérence forte. Pour spécifier des paramètres facultatifs, vous devez créer un objet ScanOperationConfig qui inclut les paramètres obligatoires et facultatifs, et utiliser la surcharge suivante. API Version 2012-08-10 137 Amazon DynamoDB Manuel du développeur .NET : Modèle de document Scan(ScanOperationConfig config); L'extrait de code C# suivant exécute la même requête précédente (rechercher les threads de forum dans lesquels ForumId a la valeur 101 et l'attribut Tag contient le mot-clé « sortkey »). Cependant, cette fois-ci, supposons que vous souhaitiez ajouter un paramètre facultatif pour récupérer uniquement une liste d'attributs spécifiques. Dans ce cas, vous devez créer un objet ScanOperationConfig en fournissant tous les paramètres, requis et facultatifs, comme illustré dans l'exemple de code suivant. string tableName = "Thread"; Table ThreadTable = Table.LoadTable(client, tableName); ScanFilter scanFilter = new ScanFilter(); scanFilter.AddCondition("ForumId", ScanOperator.Equal, forumId); scanFilter.AddCondition("Tags", ScanOperator.Contains, "sortkey"); ScanOperationConfig config = new ScanOperationConfig() { AttributesToGet = new List<string> { "Subject", "Message" } , Filter = scanFilter }; Search search = ThreadTable.Scan(config); Exemple : Analyse à l'aide de la méthode Table.Scan L'opération Scan effectue une analyse de table complète, ce qui en fait une opération potentiellement coûteuse. Vous devez utiliser les requêtes à la place. Cependant, parfois, vous devrez peut-être exécuter une analyse sur une table. Par exemple, vous pouvez avoir une erreur d'entrée de données dans la tarification du produit et vous devez analyser la table comme illustré dans l'exemple de code C# suivant. L'exemple analyse la table ProductCatalog pour rechercher les produits pour lesquels la valeur de prix est inférieure à 0. L'exemple illustre l'utilisation de deux surcharges Table.Scan. • Table.Scan qui prend l'objet ScanFilter comme paramètre. Vous pouvez passer le paramètre ScanFilter lors du passage des seuls paramètres requis. • Table.Scan qui prend l'objet ScanOperationConfig comme paramètre. Vous devez utiliser le paramètre ScanOperationConfig si vous souhaitez passer des paramètres facultatifs à la méthode Scan. using using using using using System; System.Collections.Generic; System.Linq; Amazon.DynamoDBv2; Amazon.DynamoDBv2.DocumentModel; namespace com.amazonaws.codesamples { class MidLevelScanOnly { private static AmazonDynamoDBClient client = new AmazonDynamoDBClient(); static void Main(string[] args) { API Version 2012-08-10 138 Amazon DynamoDB Manuel du développeur .NET : Modèle de document Table productCatalogTable = Table.LoadTable(client, "ProductCatalog"); // Scan example. FindProductsWithNegativePrice(productCatalogTable); FindProductsWithNegativePriceWithConfig(productCatalogTable); Console.WriteLine("To continue, press Enter"); Console.ReadLine(); } private static void FindProductsWithNegativePrice(Table productCatalogTable) { // Assume there is a price error. So we scan to find items priced < 0. ScanFilter scanFilter = new ScanFilter(); scanFilter.AddCondition("Price", ScanOperator.LessThan, 0); Search search = productCatalogTable.Scan(scanFilter); List<Document> documentList = new List<Document>(); do { documentList = search.GetNextSet(); Console.WriteLine("\nFindProductsWithNegativePrice: printing ............"); foreach (var document in documentList) PrintDocument(document); } while (!search.IsDone); } private static void FindProductsWithNegativePriceWithConfig(Table productCatalogTable) { // Assume there is a price error. So we scan to find items priced < 0. ScanFilter scanFilter = new ScanFilter(); scanFilter.AddCondition("Price", ScanOperator.LessThan, 0); ScanOperationConfig config = new ScanOperationConfig() { Filter = scanFilter, Select = SelectValues.SpecificAttributes, AttributesToGet = new List<string> { "Title", "Id" } }; Search search = productCatalogTable.Scan(config); List<Document> documentList = new List<Document>(); do { documentList = search.GetNextSet(); Console.WriteLine("\nFindProductsWithNegativePriceWithConfig: printing ............"); foreach (var document in documentList) PrintDocument(document); } while (!search.IsDone); } API Version 2012-08-10 139 Amazon DynamoDB Manuel du développeur .NET : modèle de persistance des objets private static void PrintDocument(Document document) { // count++; Console.WriteLine(); foreach (var attribute in document.GetAttributeNames()) { string stringValue = null; var value = document[attribute]; if (value is Primitive) stringValue = value.AsPrimitive().Value.ToString(); else if (value is PrimitiveList) stringValue = string.Join(",", (from primitive in value.AsPrimitiveList().Entries select primitive.Value).ToArray()); Console.WriteLine("{0} - {1}", attribute, stringValue); } } } } .NET : modèle de persistance des objets Rubriques • Attributs DynamoDB (p. 142) • Classe DynamoDBContext (p. 144) • Types de données pris en charge (p. 149) • Verrouillage optimiste avec numéro de version avec DynamoDB utilisant le modèle de persistance des objets du kit SDK AWS pour .NET (p. 150) • Mappage des données arbitraires avec DynamoDB à l'aide du modèle de persistance des objets du kit SDK AWS pour .NET (p. 152) • Opérations par lot à l'aide du modèle de persistance des objets du kit SDK AWS pour .NET (p. 154) • Exemple : opérations CRUD à l'aide du modèle de persistance des objets du kit SDK AWS pour .NET (p. 158) • Exemple : opération d'écriture par lot à l'aide du modèle de persistance des objets du kit SDK AWS pour .NET (p. 159) • Exemple : requête et analyse dans DynamoDB à l'aide du modèle de persistance des objets du kit SDK AWS pour .NET (p. 163) Le kit SDK AWS pour .NET fournit un modèle de persistance des objets qui vous permet de mapper vos classes côté client avec les tables DynamoDB. Ensuite, chaque instance d'objet est mappée à un élément des tables correspondantes. Pour enregistrer vos objets côté client sur les tables, le modèle de persistance des objets fournit la classe DynamoDBContext, point d'entrée pour DynamoDB. Cette classe vous fournit une connexion à DynamoDB et vous permet d'accéder aux tables, d'effectuer diverses opérations CRUD et d'exécuter des requêtes. Le modèle de persistance des objets fournit un ensemble d'attributs pour mapper les classes côté client avec les tables, et les propriétés/champs avec les attributs de table. Note Le modèle de persistance des objets n'autorise pas une API à créer, mettre à jour ou supprimer des tables. Il fournit uniquement des opérations sur les données. Vous pouvez API Version 2012-08-10 140 Amazon DynamoDB Manuel du développeur .NET : modèle de persistance des objets utiliser uniquement l'API de bas niveau du kit SDK AWS pour .NET pour créer, mettre à jour et supprimer des tables. Pour de plus amples informations, veuillez consulter Utilisation de tables : .NET (p. 192). Pour expliquer comment fonctionne le modèle de persistance des objets, suivons un exemple. Commençons par la table ProductCatalog. Elle possède Id comme clé primaire. ProductCatalog(Id, ...) Supposons que vous ayez une classe Book avec les propriétés Title, ISBN et Authors. Vous pouvez mapper la classe Book avec la table ProductCatalog en ajoutant les attributs définis par le modèle de persistance des objets, comme illustré dans l'extrait de code C# suivant. [DynamoDBTable("ProductCatalog")] public class Book { [DynamoDBHashKey] public int Id { get; set; } public string Title { get; set; } public int ISBN { get; set; } [DynamoDBProperty("Authors")] public List<string> BookAuthors { get; set; } [DynamoDBIgnore] public string CoverPage { get; set; } } Dans l'exemple précédent, l'attribut DynamoDBTable mappe la classe Book avec la table ProductCatalog. Le modèle de persistance des objets prend en charge le mappage explicite par défaut entre les propriétés de classe et les attributs de table. • Mappage explicite :pour mapper une propriété à une clé primaire, vous devez utiliser les attributs DynamoDBHashKey et DynamoDBRangeKey du modèle de persistance des objets. En outre, pour les attributs de clé non primaire, si un nom de propriété de votre classe et l'attribut de table correspondant auquel vous voulez le mapper ne sont pas identiques, vous devez définir le mappage en ajoutant explicitement l'attribut DynamoDBProperty. Dans l'exemple précédent, la propriété Id est mappée avec la clé primaire avec le même nom et la propriété BookAuthors est mappée avec l'attribut Authors de la table ProductCatalog. • Mappage par défaut :par défaut, le modèle de persistance des objets mappe les propriétés de la classe aux attributs avec le même nom dans la table. Dans l'exemple précédent, les propriétés Title et ISBN sont mappées aux attributs avec le même nom dans la table ProductCatalog. Vous n'avez pas à mapper chaque propriété de classe individuelle. Vous identifiez ces propriétés en ajoutant l'attribut DynamoDBIgnore. Lorsque vous enregistrez une instance Book sur la table, DynamoDBContext n'inclut pas la propriété CoverPage. Il ne retourne pas non plus cette propriété lorsque vous récupérez l'instance « book ». Vous pouvez mapper les propriétés de types primitifs .NET, tels qu'int et string. Vous pouvez aussi mapper tous les types de données arbitraires aussi longtemps que vous fournissez un convertisseur API Version 2012-08-10 141 Amazon DynamoDB Manuel du développeur .NET : modèle de persistance des objets approprié pour mapper les données arbitraires à l'un des types DynamoDB. Pour en savoir sur le mappage des types arbitraires, consultez Mappage des données arbitraires avec DynamoDB à l'aide du modèle de persistance des objets du kit SDK AWS pour .NET (p. 152). Le modèle de persistance des objets prend en charge le verrouillage optimiste. Lors d'une opération de mise à jour, vous êtes ainsi assuré d'avoir la copie la plus récente de l'élément que vous êtes sur le point de mettre à jour. Pour de plus amples informations, veuillez consulter Verrouillage optimiste avec numéro de version avec DynamoDB utilisant le modèle de persistance des objets du kit SDK AWS pour .NET (p. 150). Attributs DynamoDB Cette section décrit les attributs que le modèle de persistance des objets propose afin que vous puissiez mapper vos classes et propriétés avec les attributs et les tables DynamoDB. Note Dans les attributs suivants, seuls DynamoDBTable et DynamoDBHashKey sont obligatoires. DynamoDBGlobalSecondaryIndexHashKey Mappe une propriété de classe avec la clé de partition d'un index secondaire global. Utilisez cet attribut si vous devez exécuter une opération Query sur un index secondaire global. DynamoDBGlobalSecondaryIndexRangeKey Mappe une propriété de classe à la clé de tri d'un index secondaire global. Utilisez cet attribut si vous devez exécuter une opération Query sur un index secondaire global et que vous souhaitez affiner vos résultats à l'aide de la clé de tri d'index. DynamoDBHashKey Mappe une propriété de classe à la clé de partition de la clé primaire de la table. Les attributs de clé primaire ne peuvent pas être de type collection. L'exemple de code C# suivant mappe la classe Book à la table ProductCatalog et la propriété Id à la clé de partition de la clé primaire de la table. [DynamoDBTable("ProductCatalog")] public class Book { [DynamoDBHashKey] public int Id { get; set; } // Additional properties go here. } DynamoDBIgnore Indique que la propriété associée doit être ignorée. Si vous ne voulez pas enregistrer vos propriétés de la classe, vous pouvez ajouter cet attribut pour demander à DynamoDBContext de ne pas d'inclure cette propriété lors de l'enregistrement des objets dans la table. DynamoDBLocalSecondaryIndexRangeKey Mappe une propriété de classe à la clé de tri d'un index secondaire local. Utilisez cet attribut si vous devez exécuter une opération Query sur un index secondaire local et que vous souhaitez affiner vos résultats à l'aide de la clé de tri d'index. API Version 2012-08-10 142 Amazon DynamoDB Manuel du développeur .NET : modèle de persistance des objets DynamoDBProperty Mappe une propriété de classe à un attribut de table. Si la propriété de la classe est mappée à un attribut de table de même nom, vous n'avez pas besoin de spécifier cet attribut. Cependant, si les noms ne sont pas identiques, vous pouvez utiliser cette balise pour fournir le mappage. Dans l'instruction C# suivante, DynamoDBProperty mappe la propriété BookAuthors à l'attribut Authors de la table. [DynamoDBProperty("Authors")] public List<string> BookAuthors { get; set; } DynamoDBContext utilise ces informations de mappage pour créer l'attribut Authors lors de l'enregistrement des données de l'objet sur la table correspondante. DynamoDBRenamable Spécifie un autre nom pour une propriété de classe. Cette option est utile si vous écrivez un convertisseur personnalisé pour mapper les données arbitraires avec une table DynamoDB où le nom d'une propriété de classe est différent d'un attribut de la table. DynamoDBRangeKey Mappe une propriété de classe avec la clé de tri de la clé primaire de la table. Si la table possède une clé primaire (clé de partition et la clé de tri), vous devez spécifier les deux attributs DynamoDBHashKey et DynamoDBRangeKey dans votre mappage de classe. Par exemple, l'exemple de table Reply a une clé primaire composée de la clé de partition Id et de la clé de tri Replenishment. L'exemple de code C# suivant mappe la classe Reply avec la table Reply. La définition de classe indique également que deux de ses propriétés sont mappées avec la clé primaire. Pour plus d'informations sur les exemples de table, consultez Création de tables et chargement d'exemples de données (p. 167). [DynamoDBTable("Reply")] public class Reply { [DynamoDBHashKey] public int ThreadId { get; set; } [DynamoDBRangeKey] public string Replenishment { get; set; } // Additional properties go here. } DynamoDBTable Identifie la table cible de DynamoDB avec laquelle la classe est mappée. Par exemple, l'exemple de code C# suivant mappe la classe Developer avec la table People de DynamoDB. [DynamoDBTable("People")] public class Developer { ...} Cet attribut peut être hérité ou remplacé. • L'attribut DynamoDBTable peut être hérité. Dans l'exemple précédent, si vous ajoutez une nouvelle classe, Lead, qui hérite de la classe Developer, elle est également mappée avec la table People. Les deux objets Developer et Lead sont stockés dans la table People. • L'attribut DynamoDBTable peut également être remplacé. Dans l'exemple de code C# suivant, la classe Manager hérite de la classe Developer ; cependant, l'ajout explicite de l'attribut DynamoDBTable mappe la classe avec une autre table (Managers). API Version 2012-08-10 143 Amazon DynamoDB Manuel du développeur .NET : modèle de persistance des objets [DynamoDBTable("Managers")] public class Manager extends Developer { ...} Vous pouvez ajouter le paramètre facultatif LowerCamelCaseProperties pour demander à DynamoDB de mettre en minuscule la première lettre du nom de la propriété lors du stockage des objets sur une table, comme illustré dans l'extrait C# suivant. [DynamoDBTable("People", LowerCamelCaseProperties=true)] public class Developer { string DeveloperName; ...} Lors de l'enregistrement des instances de la classe Developer, DynamoDBContext enregistre la propriété DeveloperName en tant que developerName. DynamoDBVersion Identifie une propriété de classe pour stocker le numéro de version de l'élément. Pour plus d'informations sur la gestion des versions, consultez Verrouillage optimiste avec numéro de version avec DynamoDB utilisant le modèle de persistance des objets du kit SDK AWS pour .NET (p. 150). Classe DynamoDBContext La classe DynamoDBContext est le point d'entrée de la base de données DynamoDB. Elle fournit une connexion à DynamoDB et vous permet d'accéder aux données de vos différentes tables, d'effectuer diverses opérations CRUD et d'exécuter des requêtes. La classe DynamoDBContext fournit les méthodes suivantes : CreateMultiTableBatchGet Crée un objet MultiTableBatchGet, composé de plusieurs objets BatchGet individuels. Chacun de ces objets BatchGet peut être utilisé pour récupérer les éléments d'une même table DynamoDB. Pour récupérer les éléments des tables, utilisez la méthode ExecuteBatchGet, en passant l'objet MultiTableBatchGet comme paramètre. CreateMultiTableBatchWrite Crée un objet MultiTableBatchWrite, composé de plusieurs objets BatchWrite individuels. Chacun de ces objets BatchWrite peut être utilisé pour l'écriture ou la suppression d'éléments d'une même table DynamoDB. Pour écrire dans les tables, utilisez la méthode ExecuteBatchWrite, en passant l'objet MultiTableBatchWrite comme paramètre. CreateBatchGet Crée un objet BatchGet que vous pouvez utiliser pour extraire plusieurs éléments d'une table. Pour de plus amples informations, veuillez consulter Batch Get : obtention de plusieurs éléments (p. 156). CreateBatchWrite Crée un objet BatchWrite que vous pouvez utiliser pour placer plusieurs éléments dans une table ou pour supprimer plusieurs éléments d'une table. Pour de plus amples informations, veuillez consulter Ecriture par lots : insertion et suppression de plusieurs éléments (p. 154). API Version 2012-08-10 144 Amazon DynamoDB Manuel du développeur .NET : modèle de persistance des objets Delete Supprime un élément de la table. La méthode nécessite la clé primaire de l'élément que vous souhaitez supprimer. Vous pouvez fournir comme paramètre de la méthode la valeur de la clé primaire ou un objet côté client contenant une valeur de clé primaire. • Si vous spécifiez un objet côté client comme paramètre et que vous avez activé le verrouillage optimiste, la suppression n'aboutit que si les versions de l'objet côté client et côté serveur correspondent. • Si vous spécifiez uniquement la valeur de clé primaire comme paramètre, la suppression réussit, que vous ayez activé ou non le verrouillage optimiste. Note Pour effectuer cette opération en arrière-plan, utilisez à la place la méthode DeleteAsync. Dispose Supprime toutes les ressources gérées et non gérées. ExecuteBatchGet Lit les données à partir d'une ou de plusieurs tables, en traitant tous les objets BatchGet dans un MultiTableBatchGet. Note Pour effectuer cette opération en arrière-plan, utilisez à la place la méthode ExecuteBatchGetAsync. ExecuteBatchWrite Ecrit ou supprime les données d'une ou de plusieurs tables, en traitant tous les objets BatchWrite d'un MultiTableBatchWrite. Note Pour effectuer cette opération en arrière-plan, utilisez à la place la méthode ExecuteBatchWriteAsync. FromDocument Soit une instance d'un Document, la méthode FromDocument retourne une instance d'une classe côté client. Cette option est utile si vous souhaitez utiliser les classes du modèle de document en même temps que le modèle de persistance des objets pour effectuer les opérations de données. Pour plus d'informations sur les classes du modèle de document fournies par le kit SDK AWS pour .NET, consultez .NET : Modèle de document (p. 117). Supposons que vous ayez un objet Document nommé doc et contenant une représentation d'un élément Forum. (Pour voir comment construire cet objet, consultez la description de la méthode ToDocument ci-dessous.) Vous pouvez utiliser FromDocumentpour récupérer l'élément Forum du Document, comme illustré dans l'extrait de code C# suivant. forum101 = context.FromDocument<Forum>(101); API Version 2012-08-10 145 Amazon DynamoDB Manuel du développeur .NET : modèle de persistance des objets Note Si votre objet Document implémente l'interface IEnumerable, vous pouvez utiliser à la place la méthode FromDocuments. Cela vous permettra d'itérer sur toutes les instances de la classe du Document. FromQuery Exécute une opération Query, avec les paramètres de requête définis dans un objet QueryOperationConfig. Note Pour effectuer cette opération en arrière-plan, utilisez à la place la méthode FromQueryAsync. FromScan Exécute une opération Scan, avec les paramètres d'analyse définis dans un objet ScanOperationConfig. Note Pour effectuer cette opération en arrière-plan, utilisez à la place la méthode FromScanAsync. GetTargetTable Récupère la table cible du type spécifié. Cette option est utile si vous écrivez un convertisseur personnalisé pour le mappage des données arbitraires avec une table DynamoDB et que vous devez déterminer quelle table est associée à un type de données personnalisé. Load Récupère un élément dans une table. La méthode nécessite uniquement la clé primaire de l'élément que vous voulez récupérer. Par défaut, DynamoDB retourne l'élément avec les valeurs cohérentes à terme. Pour plus d'informations sur le modèle de cohérence à terme, consultez Cohérence en lecture (p. 16). Note Pour effectuer cette opération en arrière-plan, utilisez à la place la méthode LoadAsync. Query Les requêtes d'une table basée sur les paramètres de requête que vous fournissez. Vous pouvez interroger une table uniquement si elle comporte une clé primaire composite (clé de partition et clé de tri). Lors de l'interrogation, vous devez spécifier une clé de partition et une condition qui s'applique à la clé de tri. Supposons que vous ayez une classe Reply côté client mappée avec la table Reply de DynamoDB. L'extrait de code C# suivant interroge la table Reply pour trouver les réponses aux conversations du forum publiées au cours des 15 derniers jours. Le tableau Reply possède une clé primaire composée de la clé de partition Id et de la clé de tri ReplyDateTime. Pour plus d'informations sur la table Reply, consultez Création de tables et chargement d'exemples de données (p. 167). API Version 2012-08-10 146 Amazon DynamoDB Manuel du développeur .NET : modèle de persistance des objets DynamoDBContext context = new DynamoDBContext(client); string replyId = "DynamoDB#DynamoDB Thread 1"; //Partition key DateTime twoWeeksAgoDate = DateTime.UtcNow.Subtract(new TimeSpan(14, 0, 0, 0)); // Date to compare. IEnumerable<Reply> latestReplies = context.Query<Reply>(replyId, QueryOperator.GreaterThan, twoWeeksAgoDate); Cela retourne un ensemble d'objets Reply. La méthode Query retourne une collection IEnumerable « avec chargement différé ». Elle ne renvoie initialement qu'une seule page de résultats puis effectue un appel de service pour la page suivante si nécessaire. Pour obtenir tous les éléments correspondants, il vous suffit d'itérer sur IEnumerable. Si votre table comporte une clé primaire simple (clé de partition), vous ne pouvez pas utiliser la méthode Query. Vous pouvez utiliser à la place la méthode Load et fournir la clé de partition pour récupérer l'élément. Note Pour effectuer cette opération en arrière-plan, utilisez à la place la méthode QueryAsync. Save Enregistre l'objet spécifié dans la table. Si la clé primaire spécifiée dans l'objet en entrée n'existe pas dans la table, la méthode ajoute un nouvel élément à la table. Si la clé primaire existe, la méthode met à jour l'élément existant. Si vous avez configuré le verrouillage optimiste, la mise à jour ne réussit que si les versions côté client et côté serveur de l'élément correspondent. Pour de plus amples informations, veuillez consulter Verrouillage optimiste avec numéro de version avec DynamoDB utilisant le modèle de persistance des objets du kit SDK AWS pour .NET (p. 150). Note Pour effectuer cette opération en arrière-plan, utilisez à la place la méthode SaveAsync. Scan Effectue une analyse de la totalité de la table. Vous pouvez filtrer le résultat d'analyse en spécifiant une condition d'analyse. La condition peut être évaluée sur tous les attributs de la table. Supposons que vous ayez une classe Book côté client mappée avec la table ProductCatalog dans DynamoDB. L'extrait C# suivant analyse la table et retourne uniquement les éléments « book » dont le prix est inférieur à 0. IEnumerable<Book> itemsWithWrongPrice = context.Scan<Book>( new ScanCondition("Price", ScanOperator.LessThan, price), new ScanCondition("ProductCategory", ScanOperator.Equal, "Book") ); La méthode Scan retourne une collection IEnumerable « avec chargement différé ». Elle ne renvoie initialement qu'une seule page de résultats puis effectue un appel de service pour la page suivante si nécessaire. Pour obtenir tous les éléments correspondants, il vous suffit d'itérer sur IEnumerable. Pour des raisons de performance, vous devez interroger vos tables et éviter une analyse de table. API Version 2012-08-10 147 Amazon DynamoDB Manuel du développeur .NET : modèle de persistance des objets Note Pour effectuer cette opération en arrière-plan, utilisez à la place la méthode ScanAsync. ToDocument Retourne une instance de la classe du modèle de document Document à partir de votre instance de classe. Cette option est utile si vous souhaitez utiliser les classes du modèle de document en même temps que le modèle de persistance des objets pour effectuer les opérations de données. Pour plus d'informations sur les classes du modèle de document fournies par le kit SDK AWS pour .NET, consultez .NET : Modèle de document (p. 117). Supposons que vous ayez une classe côté client mappée avec l'exemple de table Forum. Vous pouvez utiliser ensuite un DynamoDBContext pour obtenir un élément, en tant qu'objet Document, à partir de la table Forum, comme illustré dans l'extrait de code C# suivant. DynamoDBContext context = new DynamoDBContext(client); Forum forum101 = context.Load<Forum>(101); // Retrieve a forum by primary key. Document doc = context.ToDocument<Forum>(forum101); Spécification des paramètres facultatifs pour DynamoDBContext Lors de l'utilisation du modèle de persistance des objets, vous pouvez spécifier les paramètres facultatifs suivants pour DynamoDBContext. • ConsistentRead : lors de l'extraction des données à l'aide des opérations Load, Query ou Scan, vous pouvez le cas échéant ajouter ce paramètre pour demander les valeurs des données les plus récentes. • IgnoreNullValues : ce paramètre demande à DynamoDBContext d'ignorer les valeurs null sur les attributs pendant une opération Save. Si ce paramètre a la valeur false (ou s'il n'est pas défini), une valeur null est interprétée comme directive de suppression de l'attribut spécifique. • SkipVersionCheck : ce paramètre demande à DynamoDBContext de ne pas comparer les versions lors de l'enregistrement ou de la suppression d'un élément. Pour plus d'informations sur la gestion des versions, consultez Verrouillage optimiste avec numéro de version avec DynamoDB utilisant le modèle de persistance des objets du kit SDK AWS pour .NET (p. 150). • TableNamePrefix : préfixe tous les noms de table avec une chaîne spécifique. Si ce paramètre a la valeur null (ou s'il n'est pas défini), aucun préfixe n'est utilisé. L'extrait C# suivant crée un DynamoDBContext en spécifiant deux des précédents paramètres facultatifs. AmazonDynamoDBClient client = new AmazonDynamoDBClient(); ... DynamoDBContext context = new DynamoDBContext(client, new DynamoDBContextConfig { ConsistentRead = true, SkipVersionCheck = true}); DynamoDBContext inclut ces paramètres facultatifs avec chaque demande que vous envoyez à l'aide de ce contexte. Au lieu de définir ces paramètres au niveau DynamoDBContext, vous pouvez les spécifier pour les opérations individuelles que vous exécutez à l'aide de DynamoDBContext comme illustré dans API Version 2012-08-10 148 Amazon DynamoDB Manuel du développeur .NET : modèle de persistance des objets l'extrait de code C# suivant. L'exemple charge un élément « book » spécifique. La méthode Load de DynamoDBContext spécifie les précédents paramètres facultatifs. AmazonDynamoDBClient client = new AmazonDynamoDBClient(); ... DynamoDBContext context = new DynamoDBContext(client); Book bookItem = context.Load<Book>(productId,new DynamoDBContextConfig{ ConsistentRead = true, SkipVersionCheck = true }); Dans ce cas, DynamoDBContext inclut ces paramètres uniquement lors de l'envoi de la demande Get. Types de données pris en charge Le modèle de persistance des objets prend en charge un ensemble de types de données .NET primitifs, de collections et de types de données arbitraires. Le modèle prend en charge les types de données primitifs suivants. • bool • byte • char • DateTime • decimal • double • float • Int16 • Int32 • Int64 • SByte • string • UInt16 • UInt32 • UInt64 Le modèle de persistance des objets prend également en charge les types de collection .NET avec les limitations suivantes : • Le type de collection doit implémenter l'interface ICollection. • Le type de collection doit être composé des types primitifs pris en charge. Par exemple, ICollection<string>, ICollection<bool>. • Le type de collection doit fournir un constructeur sans paramètre. Le tableau suivant récapitule le mappage des types .NET précédents avec les types DynamoDB. Type .NET primitif Type DynamoDB Tous les types de numéro N (type Number) Tous les types String (chaîne) S (type String) MemoryStream, byte[] B (type Binary) API Version 2012-08-10 149 Amazon DynamoDB Manuel du développeur .NET : modèle de persistance des objets Type .NET primitif Type DynamoDB bool N (type Number), 0 représente false et 1 représente true. Types de collection Type BS(binary set), type SS (string set) et type NS (number set) DateTime S (type String). Les valeurs DateTime sont stockées comme chaînes formatées ISO-8601. Le modèle de persistance des objets prend aussi en charge les types de données arbitraires. Cependant, vous devez fournir un code convertisseur pour mapper les types complexes avec les types DynamoDB. Verrouillage optimiste avec numéro de version avec DynamoDB utilisant le modèle de persistance des objets du kit SDK AWS pour .NET La prise en charge du verrouillage optimiste dans le modèle de persistance des objets garantit que la version de l'élément de votre application est la même que celle de l'élément côté serveur avant la mise à jour ou la suppression de l'élément. Supposons que vous récupériez un élément pour une mise à jour. Cependant, avant de renvoyer vos mises à jour, une autre application met à jour le même élément. Maintenant, votre application possède une copie obsolète de l'élément. Sans verrouillage optimiste, toute mise à jour que vous effectuez remplace la mise à jour effectuée par l'autre application. La fonctionnalité de verrouillage optimiste du modèle de persistance des objets fournit la balise DynamoDBVersion que vous pouvez utiliser pour activer le verrouillage optimiste. Pour utiliser cette fonctionnalité, vous ajoutez une propriété à votre classe pour stocker le numéro de version. Vous ajoutez l'attribut DynamoDBVersion sur la propriété. Lorsque vous enregistrez l'objet pour la première fois, DynamoDBContext attribue un numéro de version et incrémente cette valeur chaque fois que vous mettez à jour l'élément. Votre demande de mise à jour ou de suppression n'aboutit que si la version de l'objet côté client correspond au numéro de version de l'élément côté serveur. Si votre application possède une copie obsolète, elle doit alors obtenir la dernière version à partir du serveur avant de pouvoir mettre à jour ou supprimer cet élément. L'extrait de code C# suivant définit une classe Book avec des attributs de persistance des objets correspondant à la table ProductCatalog. La propriété VersionNumber de la classe décorée avec l'attribut DynamoDBVersion stocke la valeur du numéro de version. [DynamoDBTable("ProductCatalog")] public class Book { [DynamoDBHashKey] //Partition key public int Id { get; set; } [DynamoDBProperty] public string Title { get; set; } [DynamoDBProperty] public string ISBN { get; set; } [DynamoDBProperty("Authors")] public List<string> BookAuthors { get; set; } [DynamoDBVersion] public int? VersionNumber { get; set; } } API Version 2012-08-10 150 Amazon DynamoDB Manuel du développeur .NET : modèle de persistance des objets Note Vous pouvez appliquer l'attribut DynamoDBVersion uniquement à un type de primitif numérique autorisant la valeur null (tel que int?). Le verrouillage optimiste a l'impact suivant sur les opérations DynamoDBContext : • Enregistrer—Pour un nouvel élément, DynamoDBContext affecte la valeur 0 au numéro de version initial. Si vous récupérez un élément existant, puis mettez à jour une ou plusieurs de ses propriétés et tentez d'enregistrer les modifications, l'opération d'enregistrement n'aboutit que si les numéros de version côté client et côté serveur correspondent. DynamoDBContext incrémente le numéro de version. Vous n'avez pas besoin définir le numéro de version. • Supprimer—La méthode Delete fournit des surcharges qui peuvent accepter une valeur de clé primaire ou un objet comme paramètre, comme illustré dans l'extrait de code C# suivant. DynamoDBContext context = new DynamoDBContext(client); ... // Load a book. Book book = context.Load<ProductCatalog>(111); // Do other operations. // Delete 1 - Pass in the book object. context.Delete<ProductCatalog>(book); // Delete 2 - pass in the Id (primary key) context.Delete<ProductCatalog>(222); Si vous fournissez un objet en tant que paramètre, la suppression n'aboutit que si la version de l'objet correspond à la version correspondante de l'élément côté serveur. Cependant, si vous fournissez une valeur de clé primaire comme paramètre, DynamoDBContext ignore les numéros de version et supprime l'élément sans procéder au contrôle de version. Notez que l'implémentation interne du verrouillage optimiste dans le code du modèle de persistance des objets utilise les actions d'API de mise à jour conditionnelle et de suppression conditionnelle dans DynamoDB. Désactivation du verrouillage optimiste Pour désactiver le verrouillage optimiste, vous utilisez la propriété de configuration SkipVersionCheck. Vous pouvez définir cette propriété lors de la création de DynamoDBContext. Dans ce cas, le verrouillage optimiste est désactivé pour toutes les requêtes que vous effectuez à l'aide du contexte. Pour de plus amples informations, veuillez consulter Spécification des paramètres facultatifs pour DynamoDBContext (p. 148). Au lieu de définir la propriété au niveau du contexte, vous pouvez désactiver le verrouillage optimiste pour une opération spécifique, comme illustré dans l'extrait de code C# suivant. L'exemple de code utilise le contexte pour supprimer un élément « book ». La méthode Delete définit la propriété facultative SkipVersionCheck sur true, désactivant ainsi le contrôle de version. DynamoDBContext context = new DynamoDBContext(client); // Load a book. Book book = context.Load<ProductCatalog>(111); ... // Delete the book. context.Delete<Book>(book, new DynamoDBContextConfig { SkipVersionCheck = true }); API Version 2012-08-10 151 Amazon DynamoDB Manuel du développeur .NET : modèle de persistance des objets Mappage des données arbitraires avec DynamoDB à l'aide du modèle de persistance des objets du kit SDK AWS pour .NET En plus des types .NET pris en charge (voir Types de données pris en charge (p. 149)), vous pouvez utiliser les types de votre application pour lesquels il n'y a pas de mappage direct avec les types DynamoDB. Le modèle de persistance des objets prend en charge le stockage des données de types arbitraires aussi longtemps que vous fournissez le convertisseur pour convertir les données du type arbitraire en type DynamoDB et inversement. Le code du convertisseur transforme les données pendant l'enregistrement et le chargement des objets. Vous pouvez créer n'importe quel type côté client ; cependant, les données stockées dans les tables constituent l'un des types de DynamoDB et, au cours de la requête et de l'analyse, les comparaisons de données se font par rapport aux données stockées dans DynamoDB. L'exemple de code C# suivant définit une classe Book avec les propriétés Id, Title, ISBN et Dimension. La propriété Dimension est du type DimensionType qui décrit les propriétés Height, Width et Thickness. L'exemple de code fournit les méthodes de convertisseur, ToEntry et FromEntry pour convertir les données entre le type DimensionType et les types string (chaîne) de DynamoDB. Par exemple, lors de l'enregistrement d'une instance « Book », le convertisseur crée une chaîne Dimension (« 8.5x11x.05 », par exemple) et lorsque vous extrayez un livre, la chaîne est convertie en instance DimensionType. L'exemple mappe le type Book avec la table ProductCatalog. A titre d'illustration, il enregistre un exemple d'instance Book, met à jour ses dimensions et enregistre à nouveau l'instance Book mise à jour. Pour obtenir les instructions pas à pas sur le test de l'exemple suivant, consultez Exemples de code .NET (p. 175). using using using using using using using System; System.Collections.Generic; Amazon.DynamoDBv2; Amazon.DynamoDBv2.DataModel; Amazon.DynamoDBv2.DocumentModel; Amazon.Runtime; Amazon.SecurityToken; namespace com.amazonaws.codesamples { class HighLevelMappingArbitraryData { private static AmazonDynamoDBClient client = new AmazonDynamoDBClient(); static void Main(string[] args) { try { DynamoDBContext context = new DynamoDBContext(client); // 1. Create a book. DimensionType myBookDimensions = new DimensionType() { Length = 8M, Height = 11M, Thickness = 0.5M }; API Version 2012-08-10 152 Amazon DynamoDB Manuel du développeur .NET : modèle de persistance des objets Book myBook = new Book { Id = 501, Title = "AWS SDK for .NET Object Persistence Model Handling Arbitrary Data", ISBN = "999-9999999999", BookAuthors = new List<string> { "Author 1", "Author 2" }, Dimensions = myBookDimensions }; context.Save(myBook); // 2. Retrieve the book. Book bookRetrieved = context.Load<Book>(501); // 3. Update property (book dimensions). bookRetrieved.Dimensions.Height += 1; bookRetrieved.Dimensions.Length += 1; bookRetrieved.Dimensions.Thickness += 0.2M; // Update the book. context.Save(bookRetrieved); Console.WriteLine("To continue, press Enter"); Console.ReadLine(); } catch (AmazonDynamoDBException e) { Console.WriteLine(e.Message); } catch (AmazonServiceException e) { Console.WriteLine(e.Message); } catch (Exception e) { Console.WriteLine(e.Message); } } } [DynamoDBTable("ProductCatalog")] public class Book { [DynamoDBHashKey] //Partition key public int Id { get; set; } [DynamoDBProperty] public string Title { get; set; } [DynamoDBProperty] public string ISBN { get; set; } // Multi-valued (set type) attribute. [DynamoDBProperty("Authors")] public List<string> BookAuthors { get; set; } // Arbitrary type, with a converter to map it to DynamoDB type. [DynamoDBProperty(typeof(DimensionTypeConverter))] public DimensionType Dimensions { get; set; } } public class DimensionType { public decimal Length { get; set; } public decimal Height { get; set; } public decimal Thickness { get; set; } } // Converts the complex type DimensionType to string and vice-versa. public class DimensionTypeConverter : IPropertyConverter API Version 2012-08-10 153 Amazon DynamoDB Manuel du développeur .NET : modèle de persistance des objets { public DynamoDBEntry ToEntry(object value) { DimensionType bookDimensions = value as DimensionType; if (bookDimensions == null) throw new ArgumentOutOfRangeException(); string data = string.Format("{1}{0}{2}{0}{3}", " x ", bookDimensions.Length, bookDimensions.Height, bookDimensions.Thickness); DynamoDBEntry entry = new Primitive { Value = data }; return entry; } public object FromEntry(DynamoDBEntry entry) { Primitive primitive = entry as Primitive; if (primitive == null || !(primitive.Value is String) || string.IsNullOrEmpty((string)primitive.Value)) throw new ArgumentOutOfRangeException(); string[] data = ((string)(primitive.Value)).Split(new string[] { " x " }, StringSplitOptions.None); if (data.Length != 3) throw new ArgumentOutOfRangeException(); DimensionType complexData = new DimensionType { Length = Convert.ToDecimal(data[0]), Height = Convert.ToDecimal(data[1]), Thickness = Convert.ToDecimal(data[2]) }; return complexData; } } } Opérations par lot à l'aide du modèle de persistance des objets du kit SDK AWS pour .NET Ecriture par lots : insertion et suppression de plusieurs éléments Pour placer plusieurs objets dans une table ou les en supprimer dans une seule demande, effectuez les opérations suivantes : • Exécutez la méthode CreateBatchWrite de DynamoDBContext et créez une instance de la classe BatchWrite. • Spécifiez les éléments que vous voulez placer ou supprimer. • Pour placer un ou plusieurs éléments, utilisez la méthode AddPutItem ou AddPutItems. • Pour supprimer un ou plusieurs éléments, vous pouvez spécifier la clé primaire de l'élément ou un objet côté client qui soit mappé avec l'élément que vous souhaitez supprimer. Utilisez les méthodes AddDeleteItem, AddDeleteItems et AddDeleteKey pour spécifier la liste des éléments à supprimer. • Appelez la méthode BatchWrite.Execute pour placer tous les éléments spécifiés dans la table ou les en supprimer. API Version 2012-08-10 154 Amazon DynamoDB Manuel du développeur .NET : modèle de persistance des objets Note Lorsque vous utilisez le modèle de persistance des objets, vous pouvez spécifier un nombre quelconque d'opérations dans un lot. Cependant, notez que DynamoDB limite le nombre d'opérations d'un lot et la taille totale du lot dans une opération de traitement par lots. Pour plus d'informations sur les limites spécifiques, consultez BatchWriteItem. Si l'API détecte que votre demande d'écriture par lot a dépassé le nombre autorisé de demandes d'écriture ou la taille maximale autorisée de la charge utile HTTP, elle scinde le lot en plusieurs lots plus petits. En outre, si une réponse à une écriture par lot retourne des éléments non traités, l'API envoie automatiquement une autre requête de lots avec les éléments non traités. Supposons que vous ayez défini une classe Book en C# mappée sur la table ProductCatalog dans DynamoDB. L'extrait de code C# suivant utilise l'objet BatchWrite pour charger deux éléments et en supprimer un de la table ProductCatalog. DynamoDBContext context = new DynamoDBContext(client); var bookBatch = context.CreateBatchWrite<Book>(); // 1. Specify two books to add. Book book1 = new Book { Id = 902, ISBN = "902-11-11-1111", ProductCategory = "Book", Title = "My book3 in batch write" }; Book book2 = new Book { Id = 903, ISBN = "903-11-11-1111", ProductCategory = "Book", Title = "My book4 in batch write" }; bookBatch.AddPutItems(new List<Book> { book1, book2 }); // 2. Specify one book to delete. bookBatch.AddDeleteKey(111); bookBatch.Execute(); Pour placer ou supprimer les objets de plusieurs tables, procédez comme suit : • Créez une instance de la classe BatchWrite pour chaque type et spécifiez les éléments que vous voulez placer ou supprimer, comme décrit dans la section précédente. • Créez une instance de MultiTableBatchWrite à l'aide de l'une des méthodes suivantes : • Exécutez la méthode Combine sur l'un des objets BatchWrite que vous avez créés lors de l'étape précédente. • Créez une instance du type MultiTableBatchWrite en fournissant une liste d'objets BatchWrite. • Exécutez la méthode CreateMultiTableBatchWrite de DynamoDBContext et passez votre liste d'objets BatchWrite. • Appelez la méthode Execute de MultiTableBatchWrite, qui exécute les opérations de placement et de suppression spécifiées sur les diverses tables. API Version 2012-08-10 155 Amazon DynamoDB Manuel du développeur .NET : modèle de persistance des objets Supposons que vous ayez défini les classes C# Forum et Thread, mappées avec les tables Forum et Thread de DynamoDB. En outre, supposons que la gestion des versions soit activée pour la classe Thread. Comme la gestion des versions n'est pas prise en charge lors de l'utilisation des opérations par lot, vous devez la désactiver explicitement, comme illustré dans l'extrait de code C# suivant. L'extrait de code utilise l'objet MultiTableBatchWrite pour effectuer une mise à jour multi-table. DynamoDBContext context = new DynamoDBContext(client); // Create BatchWrite objects for each of the Forum and Thread classes. var forumBatch = context.CreateBatchWrite<Forum>(); DynamoDBOperationConfig config = new DynamoDBOperationConfig(); config.SkipVersionCheck = true; var threadBatch = context.CreateBatchWrite<Thread>(config); // 1. New Forum item. Forum newForum = new Forum { Name = "Test BatchWrite Forum", Threads = 0 }; forumBatch.AddPutItem(newForum); // 2. Specify a forum to delete by specifying its primary key. forumBatch.AddDeleteKey("Some forum"); // 3. New Thread item. Thread newThread = new Thread { ForumName = "Amazon S3 forum", Subject = "My sample question", KeywordTags = new List<string> { "Amazon S3", "Bucket" }, Message = "Message text" }; threadBatch.AddPutItem(newThread); // Now execute multi-table batch write. var superBatch = new MultiTableBatchWrite(forumBatch, threadBatch); superBatch.Execute(); Pour obtenir un exemple pratique, consultez Exemple : opération d'écriture par lot à l'aide du modèle de persistance des objets du kit SDK AWS pour .NET (p. 159). Note L'API par lot de DynamoDB limite le nombre d'écritures dans un lot, ainsi que la taille du lot. Pour plus d'informations, consultez BatchWriteItem. Lors de l'utilisation du modèle de persistance des objets .NET, vous pouvez spécifier un nombre quelconque d'opérations. Cependant, si le nombre d'opérations d'un lot ou la taille dépassent la limite, l'API .NET décompose la demande d'écriture par lot en lots plus petits et envoie plusieurs demandes d'écriture par lot à DynamoDB. Batch Get : obtention de plusieurs éléments Pour récupérer plusieurs éléments d'une table en une seule demande, procédez comme suit : • Créez une instance de la classe CreateBatchGet. API Version 2012-08-10 156 Amazon DynamoDB Manuel du développeur .NET : modèle de persistance des objets • Spécifiez la liste de clés primaires à récupérer. • Appelez la méthode Execute. La réponse retourne les éléments dans la propriété Results. L'exemple de code C# suivant extrait trois éléments de la table ProductCatalog. Les éléments du résultat n'apparaissent pas nécessairement dans le même ordre que celui dans lequel vous avez spécifié les clés primaires. DynamoDBContext context = new DynamoDBContext(client); var bookBatch = context.CreateBatchGet<ProductCatalog>(); bookBatch.AddKey(101); bookBatch.AddKey(102); bookBatch.AddKey(103); bookBatch.Execute(); // Process result. Console.WriteLine(devBatch.Results.Count); Book book1 = bookBatch.Results[0]; Book book2 = bookBatch.Results[1]; Book book3 = bookBatch.Results[2]; Pour récupérer les objets à partir de plusieurs tables, procédez comme suit : • Pour chaque type, créez une instance du type CreateBatchGet et fournissez les valeurs de clé primaire que vous voulez récupérer de chaque table. • Créez une instance de la classe MultiTableBatchGet à l'aide de l'une des méthodes suivantes : • Exécutez la méthode Combine sur l'un des objets BatchGet que vous avez créés lors de l'étape précédente. • Créez une instance du type MultiBatchGet en fournissant une liste d'objets BatchGet. • Exécutez la méthode CreateMultiTableBatchGet de DynamoDBContext et passez votre liste d'objets BatchGet. • Appelez la méthode Execute de MultiTableBatchGet qui retourne les résultats typés des objets BatchGet individuels. L'extrait de code C# suivant récupère plusieurs éléments des tables Order et OrderDetail à l'aide de la méthode CreateBatchGet. var orderBatch = context.CreateBatchGet<Order>(); orderBatch.AddKey(101); orderBatch.AddKey(102); var orderDetailBatch = context.CreateBatchGet<OrderDetail>(); orderDetailBatch.AddKey(101, "P1"); orderDetailBatch.AddKey(101, "P2"); orderDetailBatch.AddKey(102, "P3"); orderDetailBatch.AddKey(102, "P1"); var orderAndDetailSuperBatch = orderBatch.Combine(orderDetailBatch); orderAndDetailSuperBatch.Execute(); Console.WriteLine(orderBatch.Results.Count); Console.WriteLine(orderDetailBatch.Results.Count); Order order1 = orderBatch.Results[0]; Order order2 = orderDetailBatch.Results[1]; OrderDetail orderDetail1 = orderDetailBatch.Results[0]; API Version 2012-08-10 157 Amazon DynamoDB Manuel du développeur .NET : modèle de persistance des objets Exemple : opérations CRUD à l'aide du modèle de persistance des objets du kit SDK AWS pour .NET L'exemple de code C# suivant déclare une classe Book avec les propriétés Id, Title, ISBN et Authors. Il utilise les attributs de persistance des objets pour mapper ces propriétés avec la table ProductCatalog dans DynamoDB. L'exemple de code utilise ensuite DynamoDBContext pour illustrer les opérations CRUD classiques. L'exemple crée un exemple d'instance Book et l'enregistre dans la table ProductCatalog. L'exemple récupère ensuite l'élément « book », puis met à jour ses propriétés ISBN et Authors. Notez que la mise à jour remplace la liste d'auteurs existante. L'exemple supprime enfin l'élément « book ». Pour plus d'informations sur la table ProductCatalog utilisée dans cet exemple, consultez Création de tables et chargement d'exemples de données (p. 167). Pour obtenir les instructions pas à pas afin de tester l'exemple suivant, consultez Exemples de code .NET (p. 175). Note L'exemple suivant n'utilise par .NET Core qui ne prend pas en charge les méthodes synchrones. Pour plus d'informations, consultez API asynchrones AWS pour .NET. using using using using using System; System.Collections.Generic; Amazon.DynamoDBv2; Amazon.DynamoDBv2.DataModel; Amazon.Runtime; namespace com.amazonaws.codesamples { class HighLevelItemCRUD { private static AmazonDynamoDBClient client = new AmazonDynamoDBClient(); static void Main(string[] args) { try { DynamoDBContext context = new DynamoDBContext(client); TestCRUDOperations(context); Console.WriteLine("To continue, press Enter"); Console.ReadLine(); } catch (AmazonDynamoDBException e) { Console.WriteLine(e.Message); } catch (AmazonServiceException e) { Console.WriteLine(e.Message); } catch (Exception e) { Console.WriteLine(e.Message); } } private static void TestCRUDOperations(DynamoDBContext context) { int bookID = 1001; // Some unique value. Book myBook = new Book { Id = bookID, Title = "object persistence-AWS SDK for.NET SDK-Book 1001", ISBN = "111-1111111001", API Version 2012-08-10 158 Amazon DynamoDB Manuel du développeur .NET : modèle de persistance des objets BookAuthors = new List<string> { "Author 1", "Author 2" }, }; // Save the book. context.Save(myBook); // Retrieve the book. Book bookRetrieved = context.Load<Book>(bookID); // Update few properties. bookRetrieved.ISBN = "222-2222221001"; bookRetrieved.BookAuthors = new List<string> { " Author 1", "Author x" }; // Replace existing authors list with this. context.Save(bookRetrieved); // Retrieve the updated book. This time add the optional ConsistentRead parameter using DynamoDBContextConfig object. Book updatedBook = context.Load<Book>(bookID, new DynamoDBContextConfig { ConsistentRead = true }); // Delete the book. context.Delete<Book>(bookID); // Try to retrieve deleted book. It should return null. Book deletedBook = context.Load<Book>(bookID, new DynamoDBContextConfig { ConsistentRead = true }); if (deletedBook == null) Console.WriteLine("Book is deleted"); } } [DynamoDBTable("ProductCatalog")] public class Book { [DynamoDBHashKey] //Partition key public int Id { get; set; } [DynamoDBProperty] public string Title { get; set; } [DynamoDBProperty] public string ISBN { get; set; } [DynamoDBProperty("Authors")] //String Set datatype public List<string> BookAuthors { get; set; } } } Exemple : opération d'écriture par lot à l'aide du modèle de persistance des objets du kit SDK AWS pour .NET L'exemple de code C# suivant déclare les classes Book, Forum, Thread et Reply et les mappe aux tables DynamoDB à l'aide des attributs du modèle de persistance des objets. L'exemple de code utilise ensuite DynamoDBContext pour illustrer les opérations d'écriture par lot suivantes. • Objet BatchWrite pour placer et supprimer les éléments « book » de la table ProductCatalog. • Objet MultiTableBatchWrite pour placer et supprimer les éléments des tables Forum et Thread. API Version 2012-08-10 159 Amazon DynamoDB Manuel du développeur .NET : modèle de persistance des objets Pour plus d'informations sur les tables utilisées dans cet exemple, consultez Création de tables et chargement d'exemples de données (p. 167). Pour obtenir les instructions pas à pas afin de tester l'exemple suivant, consultez Exemples de code .NET (p. 175). using using using using using using System; System.Collections.Generic; Amazon.DynamoDBv2; Amazon.DynamoDBv2.DataModel; Amazon.Runtime; Amazon.SecurityToken; namespace com.amazonaws.codesamples { class HighLevelBatchWriteItem { private static AmazonDynamoDBClient client = new AmazonDynamoDBClient(); static void Main(string[] args) { try { DynamoDBContext context = new DynamoDBContext(client); SingleTableBatchWrite(context); MultiTableBatchWrite(context); } catch (AmazonServiceException e) { Console.WriteLine(e.Message); } catch (Exception e) { Console.WriteLine(e.Message); } Console.WriteLine("To continue, press Enter"); Console.ReadLine(); } private static void SingleTableBatchWrite(DynamoDBContext context) { Book book1 = new Book { Id = 902, InPublication = true, ISBN = "902-11-11-1111", PageCount = "100", Price = 10, ProductCategory = "Book", Title = "My book3 in batch write" }; Book book2 = new Book { Id = 903, InPublication = true, ISBN = "903-11-11-1111", PageCount = "200", Price = 10, ProductCategory = "Book", Title = "My book4 in batch write" }; var bookBatch = context.CreateBatchWrite<Book>(); API Version 2012-08-10 160 Amazon DynamoDB Manuel du développeur .NET : modèle de persistance des objets bookBatch.AddPutItems(new List<Book> { book1, book2 }); Console.WriteLine("Performing batch write in SingleTableBatchWrite()."); bookBatch.Execute(); } private static void MultiTableBatchWrite(DynamoDBContext context) { // 1. New Forum item. Forum newForum = new Forum { Name = "Test BatchWrite Forum", Threads = 0 }; var forumBatch = context.CreateBatchWrite<Forum>(); forumBatch.AddPutItem(newForum); // 2. New Thread item. Thread newThread = new Thread { ForumName = "S3 forum", Subject = "My sample question", KeywordTags = new List<string> { "S3", "Bucket" }, Message = "Message text" }; DynamoDBOperationConfig config = new DynamoDBOperationConfig(); config.SkipVersionCheck = true; var threadBatch = context.CreateBatchWrite<Thread>(config); threadBatch.AddPutItem(newThread); threadBatch.AddDeleteKey("some partition key value", "some sort key value"); var superBatch = new MultiTableBatchWrite(forumBatch, threadBatch); Console.WriteLine("Performing batch write in MultiTableBatchWrite()."); superBatch.Execute(); } } [DynamoDBTable("Reply")] public class Reply { [DynamoDBHashKey] //Partition key public string Id { get; set; } [DynamoDBRangeKey] //Sort key public DateTime ReplyDateTime { get; set; } // Properties included implicitly. public string Message { get; set; } // Explicit property mapping with object persistence model attributes. [DynamoDBProperty("LastPostedBy")] public string PostedBy { get; set; } // Property to store version number for optimistic locking. API Version 2012-08-10 161 Amazon DynamoDB Manuel du développeur .NET : modèle de persistance des objets [DynamoDBVersion] public int? Version { get; set; } } [DynamoDBTable("Thread")] public class Thread { // PK mapping. [DynamoDBHashKey] //Partition key public string ForumName { get; set; } [DynamoDBRangeKey] //Sort key public String Subject { get; set; } // Implicit mapping. public string Message { get; set; } public string LastPostedBy { get; set; } public int Views { get; set; } public int Replies { get; set; } public bool Answered { get; set; } public DateTime LastPostedDateTime { get; set; } // Explicit mapping (property and table attribute names are different. [DynamoDBProperty("Tags")] public List<string> KeywordTags { get; set; } // Property to store version number for optimistic locking. [DynamoDBVersion] public int? Version { get; set; } } [DynamoDBTable("Forum")] public class Forum { [DynamoDBHashKey] //Partition key public string Name { get; set; } // All the following properties are explicitly mapped, // only to show how to provide mapping. [DynamoDBProperty] public int Threads { get; set; } [DynamoDBProperty] public int Views { get; set; } [DynamoDBProperty] public string LastPostBy { get; set; } [DynamoDBProperty] public DateTime LastPostDateTime { get; set; } [DynamoDBProperty] public int Messages { get; set; } } [DynamoDBTable("ProductCatalog")] public class Book { [DynamoDBHashKey] //Partition key public int Id { get; set; } public string Title { get; set; } public string ISBN { get; set; } public int Price { get; set; } public string PageCount { get; set; } public string ProductCategory { get; set; } public bool InPublication { get; set; } } API Version 2012-08-10 162 Amazon DynamoDB Manuel du développeur .NET : modèle de persistance des objets } Exemple : requête et analyse dans DynamoDB à l'aide du modèle de persistance des objets du kit SDK AWS pour .NET L'exemple C# de cette section définit les classes suivantes et les mappe avec les tables de DynamoDB. Pour plus d'informations sur la création des tables dans cet exemple, consultez Création de tables et chargement d'exemples de données (p. 167). • Classe Book mappée avec la table ProductCatalog • Classes Forum, Thread et Reply mappées avec les tables de même nom. L'exemple exécute ensuite les opérations de requête et d'analyse suivantes à l'aide de DynamoDBContext. • Obtenez un livre par ID. La table ProductCatalog a un Id comme clé primaire. Il n'a pas de clé de tri dans le cadre de sa clé primaire. Par conséquent, vous ne pouvez pas interroger la table. Vous pouvez obtenir un élément à l'aide de sa valeur Id. • Exécutez les requêtes suivantes sur la table Reply. La clé primaire de la table Reply est composée des attributs Id et ReplyDateTime. ReplyDateTime est une clé de tri. Vous pouvez donc interroger cette table). • Recherchez les réponses à un thread de forum publié au cours des 15 derniers jours. • Recherchez les réponses à un thread de forum publié dans une plage de dates spécifique. • Analysez la table ProductCatalog pour trouver les livres dont le prix est inférieur à zéro. Pour des raisons de performance, vous devez utiliser une requête au lieu d'une opération d'analyse. Cependant, il y a des fois où vous pourrez avoir besoin d'analyser une table. Imaginons qu'il y ait eu une erreur en entrée de données et que le prix de l'un des livres soit inférieur à 0. Cet exemple analyse la table ProductCategory pour rechercher les éléments « book » (ProductCategory a la valeur « book ») dont le prix est inférieur à 0. Pour obtenir les instructions sur la façon de créer un exemple concret, consultez Exemples de code .NET (p. 175). using using using using using using using System; System.Collections.Generic; System.Configuration; Amazon.DynamoDBv2; Amazon.DynamoDBv2.DataModel; Amazon.DynamoDBv2.DocumentModel; Amazon.Runtime; namespace com.amazonaws.codesamples { class HighLevelQueryAndScan { private static AmazonDynamoDBClient client = new AmazonDynamoDBClient(); static void Main(string[] args) { try { API Version 2012-08-10 163 Amazon DynamoDB Manuel du développeur .NET : modèle de persistance des objets DynamoDBContext context = new DynamoDBContext(client); // Get item. GetBook(context, 101); // Sample forum and thread to test queries. string forumName = "Amazon DynamoDB"; string threadSubject = "DynamoDB Thread 1"; // Sample queries. FindRepliesInLast15Days(context, forumName, threadSubject); FindRepliesPostedWithinTimePeriod(context, forumName, threadSubject); // Scan table. FindProductsPricedLessThanZero(context); Console.WriteLine("To continue, press Enter"); Console.ReadLine(); } catch (AmazonDynamoDBException e) { Console.WriteLine(e.Message); } catch (AmazonServiceException e) { Console.WriteLine(e.Message); } catch (Exception e) { Console.WriteLine(e.Message); } } private static void GetBook(DynamoDBContext context, int productId) { Book bookItem = context.Load<Book>(productId); Console.WriteLine("\nGetBook: Printing result....."); Console.WriteLine("Title: {0} \n No.Of threads:{1} \n No. of messages: {2}", bookItem.Title, bookItem.ISBN, bookItem.PageCount); } private static void FindRepliesInLast15Days(DynamoDBContext context, string forumName, string threadSubject) { string replyId = forumName + "#" + threadSubject; DateTime twoWeeksAgoDate = DateTime.UtcNow TimeSpan.FromDays(15); IEnumerable<Reply> latestReplies = context.Query<Reply>(replyId, QueryOperator.GreaterThan, twoWeeksAgoDate); Console.WriteLine("\nFindRepliesInLast15Days: Printing result....."); foreach (Reply r in latestReplies) Console.WriteLine("{0}\t{1}\t{2}\t{3}", r.Id, r.PostedBy, r.Message, r.ReplyDateTime); } private static void FindRepliesPostedWithinTimePeriod(DynamoDBContext context, string forumName, string threadSubject) { API Version 2012-08-10 164 Amazon DynamoDB Manuel du développeur .NET : modèle de persistance des objets string forumId = forumName + "#" + threadSubject; Console.WriteLine("\nFindRepliesPostedWithinTimePeriod: Printing result....."); DateTime startDate = DateTime.UtcNow - TimeSpan.FromDays(30); DateTime endDate = DateTime.UtcNow - TimeSpan.FromDays(1); IEnumerable<Reply> repliesInAPeriod = context.Query<Reply>(forumId, QueryOperator.Between, startDate, endDate); foreach (Reply r in repliesInAPeriod) Console.WriteLine("{0}\t{1}\t{2}\t{3}", r.Id, r.PostedBy, r.Message, r.ReplyDateTime); } private static void FindProductsPricedLessThanZero(DynamoDBContext context) { int price = 0; IEnumerable<Book> itemsWithWrongPrice = context.Scan<Book>( new ScanCondition("Price", ScanOperator.LessThan, price), new ScanCondition("ProductCategory", ScanOperator.Equal, "Book") ); Console.WriteLine("\nFindProductsPricedLessThanZero: Printing result....."); foreach (Book r in itemsWithWrongPrice) Console.WriteLine("{0}\t{1}\t{2}\t{3}", r.Id, r.Title, r.Price, r.ISBN); } } [DynamoDBTable("Reply")] public class Reply { [DynamoDBHashKey] //Partition key public string Id { get; set; } [DynamoDBRangeKey] //Sort key public DateTime ReplyDateTime { get; set; } // Properties included implicitly. public string Message { get; set; } // Explicit property mapping with object persistence model attributes. [DynamoDBProperty("LastPostedBy")] public string PostedBy { get; set; } // Property to store version number for optimistic locking. [DynamoDBVersion] public int? Version { get; set; } } [DynamoDBTable("Thread")] public class Thread { // PK mapping. [DynamoDBHashKey] //Partition key public string ForumName { get; set; } API Version 2012-08-10 165 Amazon DynamoDB Manuel du développeur .NET : modèle de persistance des objets [DynamoDBRangeKey] //Sort key public DateTime Subject { get; set; } // Implicit mapping. public string Message { get; set; } public string LastPostedBy { get; set; } public int Views { get; set; } public int Replies { get; set; } public bool Answered { get; set; } public DateTime LastPostedDateTime { get; set; } // Explicit mapping (property and table attribute names are different. [DynamoDBProperty("Tags")] public List<string> KeywordTags { get; set; } // Property to store version number for optimistic locking. [DynamoDBVersion] public int? Version { get; set; } } [DynamoDBTable("Forum")] public class Forum { [DynamoDBHashKey] public string Name { get; set; } // All the following properties are explicitly mapped, // only to show how to provide mapping. [DynamoDBProperty] public int Threads { get; set; } [DynamoDBProperty] public int Views { get; set; } [DynamoDBProperty] public string LastPostBy { get; set; } [DynamoDBProperty] public DateTime LastPostDateTime { get; set; } [DynamoDBProperty] public int Messages { get; set; } } [DynamoDBTable("ProductCatalog")] public class Book { [DynamoDBHashKey] //Partition key public int Id { get; set; } public string Title { get; set; } public string ISBN { get; set; } public int Price { get; set; } public string PageCount { get; set; } public string ProductCategory { get; set; } public bool InPublication { get; set; } } } API Version 2012-08-10 166 Amazon DynamoDB Manuel du développeur Exécution des exemples de code Exécution des exemples de code du Guide du développeur Les kits SDK AWS offrent une assistance étendue pour DynamoDB dans Java, JavaScript dans le navigateur, .NET, Node.js, PHP, Python et Ruby. Pour démarrer rapidement avec ces langages, consultez le Guide de démarrage de Amazon DynamoDB. Les kits SDK AWS sont disponibles pour une grande variété de langues. Pour obtenir la liste complète, consultez Outils d'Amazon Web Services. Les exemples de code de ce Guide du développeur couvrent de façon plus approfondie les opérations DynamoDB, à l'aide des langages de programmation suivants : • Java (p. 173) • .NET (p. 175) • PHP (p. 177) Avant de commencer cet exercice, vous devez vous inscrire à AWS, obtenir votre clé d'accès et votre clé secrète, et configurer l'interface de ligne de commande AWS sur votre ordinateur. Si vous ne l'avez pas encore fait, consultez Configuration de DynamoDB (service web) (p. 49). Note Si vous utilisez la version téléchargeable de DynamoDB, vous devez utiliser l'AWS CLI afin de créer les tables et les exemples de données. Vous devez également spécifier le paramètre --endpoint-url avec chaque commande de l'AWS CLI. Pour de plus amples informations, veuillez consulter Définition du point de terminaison local (p. 47). Création de tables et chargement d'exemples de données Dans cette section, vous allez utiliser AWS Management Console pour créer des tables dans DynamoDB. Vous chargez ensuite les données dans ces tables à l'aide du AWS Command Line Interface (AWS CLI). Ces tables et leurs données sont utilisées comme exemples tout au long du Guide du développeur. Note Si vous êtes un développeur d'applications, nous vous recommandons de lire également le Guide de démarrage de Amazon DynamoDB. Dans le Guide de démarrage de Amazon DynamoDB, vous utilisez la version téléchargeable de DynamoDB. Cela vous permet de découvrir gratuitement l'API de bas niveau DynamoDB, sans avoir à payer de frais pour le débit, le stockage ou le transfert de données. Rubriques • Etape 1 : Créer des tables (p. 168) • Etape 2 : Charger les données dans les tables (p. 170) • Etape 3 : Interroger les données (p. 171) • Etape 4 : (Facultatif) Nettoyer (p. 172) API Version 2012-08-10 167 Amazon DynamoDB Manuel du développeur Chargement des exemples de données • Récapitulatif (p. 172) Etape 1 : Créer des tables Dans cette section, vous allez utiliser AWS Management Console pour créer des tables dans DynamoDB pour deux cas simples d'utilisation. Cas d'utilisation 1 : Catalogue de produits Supposons que vous souhaitiez stocker les informations sur les produits dans DynamoDB. Comme chaque produit possède ses propres attributs distincts, vous devrez stocker différentes informations sur chacun de ces produits. Vous pouvez créer une table ProductCatalog, où chaque élément est identifié de façon unique par un seul attribut numérique : Id. Nom de la table Clé primaire ProductCatalog Clé de partition : Id (Number) Cas d'utilisation 2 : Application Forum Supposons que vous souhaitiez créer une application pour panneaux de messages ou forums de discussion. L'application Discussion Forums d'Amazon Web Services est un exemple d'une telle application : les clients peuvent collaborer avec la communauté de développeurs, poser des questions ou répondre aux messages des autres clients. Chaque service AWS possède un forum dédié. Tout le monde peut démarrer un nouveau fil de discussion en publiant un message sur un forum. Chaque thread peut recevoir un nombre quelconque de réponses. Vous pouvez modéliser cette application en créant trois tables : Forum, Thread et Reply. Nom de la table Clé primaire Forum Clé de partition : Name (String) Thread Clé de partition : ForumName (String) Clé de tri : Subject (String) Reply Clé de partition : Id (String) Clé de tri : ReplyDateTime (String) La table Reply possède un index secondaire global nommé PostedBy-Message-Index. Cet index facilite les requêtes sur deux attributs non-clés de la table Reply. Nom d'index Clé primaire PostedBy-Message-Index Clé de partition : PostedBy (String) Clé de tri : Message (String) Créer la table ProductCatalog 1. Ouvrez la console DynamoDB à l'adresse https://console.aws.amazon.com/dynamodb/. API Version 2012-08-10 168 Amazon DynamoDB Manuel du développeur Chargement des exemples de données 2. Choisissez Create Table. 3. Dans l'écran Create DynamoDB table, procédez comme suit : 4. a. Dans le champ Table name, entrez ProductCatalog. b. Pour Primary key, dans le champ Partition key, entrez Id. Définissez le type de données sur Number. Lorsque les paramètres vous conviennent, choisissez Create. Créer la table Forum 1. Ouvrez la console DynamoDB à l'adresse https://console.aws.amazon.com/dynamodb/. 2. Choisissez Create Table. 3. Dans l'écran Create DynamoDB table, procédez comme suit : 4. a. Dans le champ Table name, entrez Forum. b. Pour Primary key, dans le champ Partition key, entrez Name. Définissez le type de données sur String. Lorsque les paramètres vous conviennent, choisissez Create. Créer la table Thread 1. Ouvrez la console DynamoDB à l'adresse https://console.aws.amazon.com/dynamodb/. 2. Choisissez Create Table. 3. Dans l'écran Create DynamoDB table, procédez comme suit : a. Dans le champ Table name, entrez Thread. b. Pour Primary key, procédez comme suit : • Dans le champ Partition key, tapez ForumName. Définissez le type de données sur String. • Choisissez Add sort key. • Dans le champ Sort key, tapez Subject. Définissez le type de données sur String. 4. Lorsque les paramètres vous conviennent, choisissez Create. Créer la table Reply 1. Ouvrez la console DynamoDB à l'adresse https://console.aws.amazon.com/dynamodb/. 2. Choisissez Create Table. 3. Dans l'écran Create DynamoDB table, procédez comme suit : a. Dans le champ Table name, entrez Reply. b. Pour Primary key, procédez comme suit : • Dans le champ Partition key, tapez Id. Définissez le type de données sur String. • Choisissez Add sort key. • Dans le champ Sort key, tapez ReplyDateTime. Définissez le type de données sur String. c. Dans la section Table settings, annulez la sélection de Use default settings. d. Dans la section Secondary indexes, choisissez Add index. e. Dans la fenêtre Add index, procédez comme suit : • Pour Primary key, procédez comme suit : • Dans le champ Partition key, tapez PostedBy. Définissez le type de données sur String. API Version 2012-08-10 169 Amazon DynamoDB Manuel du développeur Chargement des exemples de données • Sélectionnez Add sort key. 4. • Dans le champ Sort key, tapez Message. Définissez le type de données sur String. • Dans le champ Index name, entrez PostedBy-Message-Index. • Définissez Projected attributes sur All. • Choisissez Add index. Lorsque les paramètres vous conviennent, choisissez Create. Etape 2 : Charger les données dans les tables Dans cette étape, vous allez charger les exemples de données dans les tables que vous avez créées. Vous pouvez entrer les données manuellement dans la console DynamoDB ; cependant, pour gagner du temps, vous allez utiliser à la place l'AWS Command Line Interface. Note Si vous n'avez pas encore défini l'AWS CLI, consultez pour plus d'informations. Vous allez télécharger une archive .zip qui contient les fichiers JSON avec des exemples de données pour chaque table. Pour chaque fichier, vous allez utiliser l'AWS CLI pour charger les données dans DynamoDB. Chaque chargement de données réussi produit le résultat suivant : { "UnprocessedItems": {} } Télécharger l'exemple d'archive de fichier de données 1. Téléchargez l'exemple d'archive de données (sampledata.zip) à l'aide de ce lien : 2. • sampledata.zip Extrayez les fichiers de données .json de l'archive. 3. Copiez les fichiers de données .json sur votre répertoire actuel. Charger les exemples de données dans les tables DynamoDB 1. Pour charger la table ProductCatalog avec les données, saisissez la commande suivante : aws dynamodb batch-write-item --request-items file://ProductCatalog.json 2. Pour charger la table Forum avec les données, saisissez la commande suivante : aws dynamodb batch-write-item --request-items file://Forum.json 3. Pour charger la table Thread avec les données, saisissez la commande suivante : aws dynamodb batch-write-item --request-items file://Thread.json 4. Pour charger la table Reply avec les données, saisissez la commande suivante : aws dynamodb batch-write-item --request-items file://Reply.json Vérifier le chargement de données Vous pouvez utiliser AWS Management Console pour vérifier les données que vous avez chargées dans les tables. API Version 2012-08-10 170 Amazon DynamoDB Manuel du développeur Chargement des exemples de données Pour vérifier les données à l'aide d'AWS Management Console 1. Ouvrez la console DynamoDB à l'adresse https://console.aws.amazon.com/dynamodb/. 2. Dans le volet de navigation, choisissez Tables. 3. Dans la liste des tables, sélectionnez ProductCatalog. 4. Choisissez la table Items afin d'afficher les données que vous avez chargées dans la table. 5. Pour visualiser un élément de la table, choisissez son Id. (Si vous le souhaitez, vous pouvez également modifier l'élément.) 6. Pour revenir à la liste des tables, choisissez Cancel. Répétez cette procédure pour chacune des autres tables que vous avez créés : • Forum • Thread • Reply Etape 3 : Interroger les données Dans cette étape, vous allez essayer quelques requêtes simples sur les tables que vous avez créées, à l'aide de la console DynamoDB. 1. Ouvrez la console DynamoDB à l'adresse https://console.aws.amazon.com/dynamodb/. 2. Dans le volet de navigation, choisissez Tables. 3. Dans la liste des tables, sélectionnez Reply. 4. Choisissez la table Items afin d'afficher les données que vous avez chargées dans la table. 5. Sélectionnez le lien de filtrage des données, qui se trouve juste en dessous du bouton Create item. Lorsque vous procédez ainsi, la console révèle un volet de filtrage des données. 6. Dans le volet de filtrage des données, procédez comme suit : a. Modifiez l'opération de Scan en Query. b. Pour Partition key, saisissez la valeur Amazon DynamoDB#DynamoDB Thread 1. API Version 2012-08-10 171 Amazon DynamoDB Manuel du développeur Chargement des exemples de données c. 7. Choisissez Démarrer. Seuls les éléments qui correspondent à vos critères de requête sont retournés à partir de la table Reply. La table Reply a un index secondaire global sur les attributs PostedBy et Message. Vous pouvez utiliser le volet de filtrage des données pour interroger l'index. Procédez comme suit : a. Modifiez la source de la requête de : [Table] Reply: Id, ReplyDateTime en : [Index] PostedBy-Message-Index: PostedBy, Message b. Pour Partition key, saisissez la valeur User A. c. Choisissez Démarrer. Seuls les éléments qui correspondent à vos critères de requête sont retournés à partir de PostedBy-Message-Index. Prenez le temps d'explorer vos autres tables à l'aide de la console DynamoDB : • ProductCatalog • Forum • Thread Etape 4 : (Facultatif) Nettoyer Le présent Amazon DynamoDB Guide du développeur fait référence à ces exemples de tables de façon répétée pour aider à illustrer les opérations de table et d'élément à l'aide de l'API de bas niveau DynamoDB et des différents kits SDK AWS. Vous pouvez trouver ces tables utiles à des fins de référence si vous avez prévoyez de lire le reste de ce Guide du développeur. Cependant, si vous ne voulez pas conserver ces tables, vous devez les supprimer pour éviter d'être facturé pour des ressources dont vous n'avez pas besoin. Pour supprimer les exemples de tables 1. Ouvrez la console DynamoDB à l'adresse https://console.aws.amazon.com/dynamodb/. 2. Dans le volet de navigation, choisissez Tables. 3. Dans la liste des tables, sélectionnez ProductCatalog. 4. Choisissez Delete Table. Il vous sera demandé de confirmer votre choix. Répétez cette procédure pour chacune des autres tables que vous avez créés : • Forum • Thread • Reply Récapitulatif Dans cet exercice, vous avez utilisé la console DynamoDB pour créer plusieurs tables dans DynamoDB. Vous avez ensuite utilisé l'AWS CLI pour charger les données dans les tables et effectué certaines opérations de base sur les données à l'aide de la console DynamoDB. La console DynamoDB et l'AWS CLI sont utiles pour une mise en route rapide. Cependant, vous voudrez probablement en savoir plus sur le fonctionnement de DynamoDB et sur l'écriture des API Version 2012-08-10 172 Amazon DynamoDB Manuel du développeur Exemples de Code Java programmes d'application avec DynamoDB. Le reste du présent Guide du développeur traite de ces sujets. Exemples de Code Java Rubriques • Java : définition de vos informations d'identification AWS (p. 174) • Java : définition de la région AWS et du point de terminaison (p. 174) Ce Guide du développeur contient des extraits de code Java et des programmes prêts à être exécutés. Vous pouvez trouver ces exemples de code dans les sections suivantes : • Utilisation des éléments dans DynamoDB (p. 206) • Utilisation de tables dans DynamoDB (p. 179) • Utilisation des requêtes et des analyses (p. 290) • Amélioration de l'accès aux données avec les index secondaires (p. 337) • Java : DynamoDBMapper (p. 79) • Capture d'activité Table avec Flux DynamoDB (p. 430) Note Le Guide de démarrage de Amazon DynamoDB contient des exemples de programme Java supplémentaires. Vous pouvez démarrer rapidement en utilisant Eclipse avec AWS Toolkit for Eclipse. En plus d'un IDE complet, vous obtenez aussi le AWS SDK for Java avec les mises à jour automatiques, ainsi que des modèles préconfigurés pour le développement d'applications AWS. Pour exécuter les exemples de code Java (à l'aide d'Eclipse) 1. Téléchargez et installez l'IDE Eclipse. 2. Téléchargez et installez AWS Toolkit for Eclipse. 3. Démarrez Eclipse et dans le menu Eclipse, choisissez File, New, puis Other. 4. Dans Select a wizard, choisissez successivement AWS, AWS Java Project et Next. 5. Dans Create an AWS Java, procédez comme suit : a. Dans Project name, tapez un nom pour votre projet. b. Dans Select Account, choisissez votre profil d'informations d'identification dans la liste. S'il s'agit de votre première utilisation de AWS Toolkit for Eclipse, choisissez Configure AWS Accounts pour configurer vos informations d'identification AWS. 6. Choisissez Finish pour créer le projet. 7. Dans le menu Eclipse, choisissez File, New, puis Class. 8. Dans Java Class, tapez un nom pour votre classe dans Name (utilisez le même nom que celui de l'exemple de code que vous souhaitez exécuter), puis choisissez Finish pour créer la classe. 9. Copiez l'exemple de code de la page de documentation que vous lisez dans l'éditeur Eclipse. 10. Pour exécuter le code, choisissez Run dans le menu Eclipse. Le SDK pour Java fournit des clients thread-safe à utiliser avec DynamoDB. En tant que bonne pratique, vos applications doivent créer un seul client et le réutiliser entre les threads. API Version 2012-08-10 173 Amazon DynamoDB Manuel du développeur Exemples de Code Java Pour plus d'informations, consultez Kit SDK AWS pour Java. Note Les exemples de code du Guide du développeur sont destinés à être utilisés avec la dernière version du AWS SDK for Java. Si vous utilisez AWS Toolkit for Eclipse, vous pouvez configurer les mises à jour automatiques pour le SDK pour Java. Pour procéder ainsi dans Eclipse, accédez à Preferences et choisissez AWS Toolkit --> AWS SDK for Java --> Download new SDKs automatically. Java : définition de vos informations d'identification AWS Le SDK pour Java nécessite que vous fournissiez les informations d'identification AWS à votre application lors de l'exécution. Les exemples de code du Guide du développeur présument que vous utilisez un fichier d'informations d'identification AWS, comme décrit dans la section Configuration de vos informations d'identification AWS du document AWS SDK for Java Developer Guide. Voici un exemple de fichier d'informations d'identification AWS nommé ~/.aws/credentials, où le caractère tilde (~) représente votre répertoire de base : [default] aws_access_key_id = AWS access key ID goes here aws_secret_access_key = Secret key goes here Java : définition de la région AWS et du point de terminaison Par défaut, les exemples de code accèdent à DynamoDB dans la région USA Ouest (Oregon). Vous pouvez modifier la région en modifiant les propriétés AmazonDynamoDBClient. L'extrait de code suivant instancie un nouvel AmazonDynamoDBClient. Le client est ensuite modifié de telle sorte que le code s'exécute sur DynamoDB dans une autre région. import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient; import com.amazonaws.regions.Regions; ... // This client will default to US West (Oregon) AmazonDynamoDBClient client = new AmazonDynamoDBClient(); // Modify the client so that it accesses a different region. client.withRegion(Regions.US_EAST_1); Vous pouvez utiliser la méthode withRegion pour exécuter votre code sur Amazon DynamoDB dans n'importe quelle région où il est disponible. Pour obtenir la liste complète, consultez Régions AWS et points de terminaison dans le Référence générale d'Amazon Web Services. Si vous souhaitez exécuter les exemples de code à l'aide de DynamoDB localement sur votre ordinateur, vous devez définir le point de terminaison, comme illustré ci-après : AmazonDynamoDBClient client = new AmazonDynamoDBClient(); // Set the endpoint URL client.withEndpoint("http://localhost:8000"); API Version 2012-08-10 174 Amazon DynamoDB Manuel du développeur Exemples de code .NET Exemples de code .NET Rubriques • .NET : définition de vos informations d'identification AWS (p. 176) • .NET : définition de la région AWS et du point de terminaison (p. 176) Le Guide du développeur contient des extraits de code .NET et des programmes prêts à être exécutés. Vous pouvez trouver ces exemples de code dans les sections suivantes : • Utilisation des éléments dans DynamoDB (p. 206) • Utilisation de tables dans DynamoDB (p. 179) • Utilisation des requêtes et des analyses (p. 290) • Amélioration de l'accès aux données avec les index secondaires (p. 337) • .NET : Modèle de document (p. 117) • .NET : modèle de persistance des objets (p. 140) • Capture d'activité Table avec Flux DynamoDB (p. 430) Note Le Guide de démarrage de Amazon DynamoDB contient des exemples de programme .NET supplémentaires. Vous pouvez démarrer rapidement en utilisant le Kit AWS SDK pour .NET avec la Toolkit for Visual Studio. Pour exécuter les exemples de code .NET (à l'aide de Visual Studio) 1. Téléchargez et installez Microsoft Visual Studio. 2. Téléchargez et installez la Toolkit for Visual Studio. 3. Démarrez Visual Studio et sélectionnez File, New et Project. 4. Dans New Project, choisissez AWS Empty Project, puis OK. 5. Dans AWS Access Credentials, choisissez Use existing profile, sélectionnez votre profil d' informations d'identification dans la liste, puis choisissez OK. S'il s'agit de votre première utilisation de la Toolkit for Visual Studio, choisissez Use a new profile pour configurer vos informations d'identification AWS. 6. Dans votre projet Visual Studio, sélectionnez l'onglet du code source de votre programme (Program.cs). Copiez l'exemple de code de la page de documentation que vous lisez dans l'éditeur Visual Studio, en remplaçant tout autre code que vous voyez dans l'éditeur. 7. Si vous voyez des messages d'erreur sous la forme The type or namespace name...could not be found, vous devez installer l'assembly du SDK AWS pour DynamoDB comme suit : 8. a. Dans l'Explorateur de solutions, ouvrez le menu contextuel (clic droit) de votre projet, puis choisissez Manage NuGet Packages. b. Dans le gestionnaire de package NuGet, choisissez Browse. c. Dans la zone de recherche, tapez AWSSDK.DynamoDBv2 et attendez la fin de la recherche. d. Choisissez AWSSDK. DynamoDBv2, puis Install. e. Lorsque l'installation est terminée, sélectionnez l'onglet Program.cs pour revenir à votre programme. Pour exécuter le code, choisissez le bouton Start dans la barre d'outils Visual Studio. API Version 2012-08-10 175 Amazon DynamoDB Manuel du développeur Exemples de code .NET Le Kit AWS SDK pour .NET fournit des clients thread-safe avec DynamoDB. En tant que bonne pratique, vos applications doivent créer un seul client et le réutiliser entre les threads. Pour plus d'informations, accédez à Kit SDK AWS pour .NET. Note Les exemples de code du Guide du développeur sont destinés à être utilisés avec la dernière version du Kit AWS SDK pour .NET. .NET : définition de vos informations d'identification AWS Le Kit AWS SDK pour .NET nécessite que vous fournissiez les informations d'identification AWS à votre application lors de l'exécution. Les exemples de code du Guide du développeur présument que vous utilisez le SDK Store pour gérer votre fichier d'informations d'identification AWS, comme décrit dans Utilisation du SDK Store dans le Kit AWS SDK pour .NET Developer Guide. La Toolkit for Visual Studio prend en charge plusieurs jeux d'informations d'identification à partir d'un nombre quelconque de comptes. Chaque ensemble est référencé comme profil. Visual Studio ajoute des entrées au fichier App.config du projet de telle sorte que votre application puisse trouver les informations d'identification AWS lors de l'exécution. L'exemple suivant affiche le fichier App.config par défaut qui est généré lorsque vous créez un projet avec la Toolkit for Visual Studio : <?xml version="1.0" encoding="utf-8" ?> <configuration> <appSettings> <add key="AWSProfileName" value="default"/> <add key="AWSRegion" value="us-west-2" /> </appSettings> </configuration> Lors de l'exécution, le programme utilise l'ensemble default des informations d'identification AWS, comme spécifié par l'entrée AWSProfileName. Les informations d'identification AWS elles-mêmes sont conservées dans le SDK Store, sous forme chiffrée. La Toolkit for Visual Studio fournit une interface utilisateur graphique pour gérer vos informations d'identification, le tout depuis Visual Studio. Pour plus d'informations, consultez Spécification des informations d'identification dans le Guide de l'utilisateur AWS Toolkit for Visual Studio. Note Par défaut, les exemples de code accèdent à DynamoDB dans la région USA Ouest (Oregon). Vous pouvez modifier la région en modifiant l'entrée AWSRegion dans le fichier App.config. Vous pouvez définir AWSRegion sur n'importe quelle région AWS dans laquelle Amazon DynamoDB est disponible. Pour obtenir la liste complète, consultez Régions AWS et points de terminaison dans le Référence générale d'Amazon Web Services. .NET : définition de la région AWS et du point de terminaison Par défaut, les exemples de code accèdent à DynamoDB dans la région USA Ouest (Oregon). Vous pouvez modifier la région en modifiant l'entrée AWSRegion dans le fichier App.config. Vous pouvez également modifier la région en modifiant les propriétés AmazonDynamoDBClient. L'extrait de code suivant instancie un nouvel AmazonDynamoDBClient. Le client est modifié de telle sorte que le code s'exécute sur DynamoDB dans une autre région. API Version 2012-08-10 176 Amazon DynamoDB Manuel du développeur Exemples de Code PHP AmazonDynamoDBConfig clientConfig = new AmazonDynamoDBConfig(); // This client will access the US East 1 region. clientConfig.RegionEndpoint = RegionEndpoint.USEast1; AmazonDynamoDBClient client = new AmazonDynamoDBClient(clientConfig); Pour obtenir la liste complète des régions prises en charge, consultez la section Régions et points de terminaison AWS du manuel Référence générale d'Amazon Web Services. Si vous souhaitez exécuter les exemples de code à l'aide de DynamoDB localement sur votre ordinateur, vous devez définir le point de terminaison : AmazonDynamoDBConfig clientConfig = new AmazonDynamoDBConfig(); // Set the endpoint URL clientConfig.ServiceURL = "http://localhost:8000"; AmazonDynamoDBClient client = new AmazonDynamoDBClient(clientConfig); Exemples de Code PHP Rubriques • PHP : définition de vos informations d'identification AWS (p. 178) • PHP : définition de la région AWS et du point de terminaison (p. 178) Le Guide du développeur contient des extraits de code PHP et des programmes prêts à être exécutés. Vous pouvez trouver ces exemples de code dans les sections suivantes : • Utilisation des éléments dans DynamoDB (p. 206) • Utilisation de tables dans DynamoDB (p. 179) • Utilisation des requêtes et des analyses (p. 290) • Amélioration de l'accès aux données avec les index secondaires (p. 337) • Capture d'activité Table avec Flux DynamoDB (p. 430) Note Le Guide de démarrage de Amazon DynamoDB contient des exemples de programme PHP supplémentaires. La façon dont vous utilisez le Kit SDK pour PHP dépend de votre environnement et de la façon dont vous souhaitez exécuter votre application. Les exemples de code du présent document s'exécutent à partir de la ligne de commande, mais vous pouvez les modifier si vous souhaitez les exécuter dans un autre environnement (un serveur web, par exemple). Pour exécuter les exemples de code PHP (à partir de la ligne de commande) 1. Vérifiez que votre environnement réponde aux exigences minimales pour le Kit SDK pour PHP, comme décrit dans Exigences minimales. 2. Téléchargez et installez le AWS SDK pour PHP. Selon la méthode d'installation que vous utilisez, vous pouvez être amené à modifier le code afin de résoudre les dépendances parmi les extensions PHP. Pour plus d'informations, consultez la section Prise en main de la rubrique Mise en route de la documentation AWS SDK pour PHP. 3. Copiez l'exemple de code (à partir de la page de documentation que vous lisez) dans un fichier de votre ordinateur. API Version 2012-08-10 177 Amazon DynamoDB Manuel du développeur Exemples de Code PHP 4. Exécutez le code à partir de la ligne de commande. Par exemple: php myProgram.php Note Les exemples de code du Guide du développeur sont destinés à être utilisés avec la dernière version du AWS SDK pour PHP. PHP : définition de vos informations d'identification AWS Le Kit SDK pour PHP nécessite que vous fournissiez les informations d'identification AWS à votre application lors de l'exécution. Les exemples de code du Guide du développeur présument que vous utilisiez un fichier d'informations d'identification AWS, comme décrit dans Informations d'identification dans la documentation du AWS SDK pour PHP. Voici un exemple de fichier d'informations d'identification AWS nommé ~/.aws/credentials, où le caractère tilde (~) représente votre répertoire de base : [default] aws_access_key_id = AWS access key ID goes here aws_secret_access_key = Secret key goes here PHP : définition de la région AWS et du point de terminaison Vous devez spécifier une région AWS lorsque vous créez un client DynamoDB. Pour ce faire, vous fournissez l'objet Aws\Sdk avec la région de votre choix. L'extrait de code suivant instancie un nouvel objet Aws\Sdk, à l'aide de la région USA Ouest (Oregon). Il crée ensuite un client DynamoDB qui utilise cette région. $sdk = new Aws\Sdk([ 'region' => 'us-west-2', // US West (Oregon) Region 'version' => 'latest' // Use the latest version of the AWS SDK for PHP ]); // Create a new DynamoDB client $dynamodb = $sdk->createDynamoDb(); Si vous souhaitez exécuter les exemples de code à l'aide de DynamoDB localement sur votre ordinateur, vous devez définir le point de terminaison, comme illustré ci-après : $sdk = new Aws\Sdk([ 'endpoint' => 'http://localhost:8000', // Use DynamoDB running locally 'region' => 'us-west-2', // US West (Oregon) Region 'version' => 'latest' // Use the latest version of the AWS SDK for PHP ]); // Create a new DynamoDB client $dynamodb = $sdk->createDynamoDb(); API Version 2012-08-10 178 Amazon DynamoDB Manuel du développeur Utilisation de tables Utilisation d'DynamoDB Ce chapitre détaille les thèmes suivants : Rubriques • Utilisation de tables dans DynamoDB (p. 179) • Utilisation des éléments dans DynamoDB (p. 206) • Utilisation des requêtes et des analyses (p. 290) • Amélioration de l'accès aux données avec les index secondaires (p. 337) • Capture d'activité Table avec Flux DynamoDB (p. 430) Utilisation de tables dans DynamoDB Rubriques • Spécification de la clé primaire (p. 180) • Spécification d'exigences de lecture et d'écriture pour des tables (p. 180) • Calcul des unités de capacité (p. 182) • Liste et description des tables (p. 184) • Balisage pour DynamoDB (p. 185) • Utilisation des tables : Java (p. 187) • Utilisation de tables : .NET (p. 192) • Utilisation des tables : PHP (p. 199) Lorsque vous créez une table dans Amazon DynamoDB, vous devez fournir un nom de table, sa clé primaire et vos valeurs requises de débit de lecture et d'écriture. Le nom de la table peut inclure les caractères a-z, A-Z, 0-9, « _ » (trait de soulignement), « - » (tiret), et «. » (point). Les noms peuvent comporter entre 3 et 255 caractères. Dans une base de données relationnelle, une table a un schéma prédéfini qui décrit les propriétés, telles que le nom de la table, la clé primaire, les noms de colonnes et les types de données. Tous les enregistrements stockés dans la table doivent avoir le même ensemble de colonnes. DynamoDB est une base de données NoSQL : à l'exception de la clé primaire obligatoire, une table DynamoDB est sans schéma. Des éléments individuels dans une table DynamoDB peuvent avoir n'importe quel nombre d'attributs, bien qu'il y ait une limite de 400 KB sur la taille d'élément. Pour connaître les bonnes pratiques, consultez Instructions pour l'utilisation des tables (p. 572). Vous pouvez également étiqueter les ressources DynamoDB existantes avec des balises. Pour plus d'informations, consultez Balisage pour DynamoDB (p. 185). API Version 2012-08-10 179 Amazon DynamoDB Manuel du développeur Spécification de la clé primaire Spécification de la clé primaire Lorsque vous créez une table, en plus du nom de la table, vous devez spécifier la clé primaire de la table. La clé primaire identifie de manière unique chaque élément de la table, afin que deux éléments dans la table ne puissent pas avoir la même clé primaire. DynamoDB prend en charge deux différents types de clés primaires : • Clé de partition : clé primaire simple, composée d'un attribut appelé clé de partition. DynamoDB utilise la valeur de la clé de partition comme entrée d'une fonction de hachage interne ; la sortie de la fonction de hachage détermine la partition où l'élément sera stocké. Aucun élément dans une table ne peut avoir la même valeur de clé de partition qu'un autre. • Clé de partition et clé de tri : clé primaire composite, constituée de deux attributs. Le premier attribut est la clé de partition et le second attribut est la clé de tri. DynamoDB utilise la valeur de la clé de partition comme entrée d'une fonction de hachage interne ; la sortie de la fonction de hachage détermine la partition où l'élément sera stocké. Tous les éléments avec la même clé de partition sont stockés ensemble, dans l'ordre par valeur de clé de tri. Il est possible pour deux éléments d'avoir la même valeur de clé de partition, mais ces deux éléments doivent avoir des valeurs de clés de tri différentes. Spécification d'exigences de lecture et d'écriture pour des tables DynamoDB est conçu pour prendre en charge des charges de travail de n'importe quelle échelle avec des temps de réponse prévisibles et à faible latence. Afin de garantir des réponses à faible latence et haute disponibilité, DynamoDB nécessite que vous spécifiiez vos valeurs requises de débit de lecture et d'écriture lorsque vous créez une table. DynamoDB utilise ces informations pour réserver suffisamment de ressources matérielles et partitionner de manière adéquate vos données sur plusieurs serveurs afin de répondre à vos exigences de débit. À mesure que les exigences de données et d'accès de votre application changent, vous pouvez facilement augmenter ou diminuer votre débit alloué à l'aide de la console DynamoDB ou de l'API. DynamoDB attribue et réserve des ressources pour gérer vos exigences de débit avec une latence faible constante et vous payez la réservation horaire de ces ressources. Cependant, vous payez à mesure que vous vous développez et vous pouvez facilement monter ou descendre en puissance vos exigences de débit. Par exemple, vous pourrez souhaiter remplir une nouvelle table avec une grande quantité de données à partir d'un magasin de données existant. Dans ce cas, vous pourriez créer la table avec un imposant paramètre de débit d'écriture, et après le chargement initial des données, vous pourriez réduire le débit d'écriture et augmenter le débit de lecture afin de répondre aux exigences de votre application. Lors de la création de la table, vous spécifiez vos exigences de débit en ce qui concerne les unités de capacité suivantes. Vous pouvez également spécifier ces unités dans une demande UpdateTable pour augmenter ou diminuer le débit alloué d'une table existante : • Unités de capacité de lecture :le nombre de lectures fortement cohérentes par seconde d'éléments jusqu'à 4 KB en taille par seconde. Par exemple, lorsque vous demandez 10 unités de capacité de lecture, vous demandez un débit de 10 lectures fortement cohérentes par seconde de 4 KB pour cette table. Pour les lectures cohérentes à terme, une unité de capacité de lecture correspond à deux lectures par seconde pour des éléments jusqu'à 4 KB. Pour plus d'informations sur la cohérence de lecture, consultez Cohérence en lecture (p. 16). • Unités de capacité de lecture :le nombre d'écritures 1 KB par seconde. Par exemple, lorsque vous demandez 10 unités de capacité d'écriture, vous demandez un débit de 10 écritures par seconde de taille 1 KB par seconde pour cette table. API Version 2012-08-10 180 Amazon DynamoDB Manuel du développeur Exigences de lecture et d'écriture pour des tables DynamoDB utilise ces unités de capacité pour fournir des ressources suffisantes pour offrir le débit demandé. Au moment de décider les unités de capacité pour votre table, vous devez prendre en considération ce qui suit : • Taille de l'élément : DynamoDB alloue des ressources pour votre table selon le nombre d'unités de capacité de lecture ou d'écriture que vous spécifiez. Ces unités de capacité sont basées sur une taille d'élément de données de 4 KB par lecture ou 1 KB par écriture. Par exemple, si les éléments de votre table sont inférieurs ou égaux à 4 KB, chaque opération de lecture d'élément consommera une unité de capacité de lecture. Si vos objets sont plus gros que 4 KB, chacun opération de lecture consomme des unités de capacité supplémentaires, auquel cas vous pouvez exécuter moins d'opérations de lecture de base de données par seconde que le nombre d'unités de capacité de lecture que vous avez fournies. Par exemple, si vous demandez un débit de 10 unités capacité de lecture pour une table, mais que vos éléments ont une taille de 8 Ko, alors vous aurez un maximum de 5 lectures fortement cohérentes par seconde sur cette table. • Taux attendus de demandes de lecture et d'écriture : vous devez également déterminer le nombre attendu d'opérations de lecture et d'écriture par seconde que votre application effectuera sur la table. Cela, ainsi que la taille d'élément estimée, vous aide à déterminer les valeurs d'unité de capacité de lecture et d'écriture. • Cohérence : les unités de capacité de lecture sont basées sur des opérations de lecture fortement cohérentes qui exigent davantage d'effort et utilisent deux fois plus de ressources de base de données que les lectures cohérentes à terme. Par exemple, une table qui a 10 unités de capacité de lecture de débit alloué fournirait soit 10 lectures fortement cohérentes par seconde d'éléments 4 KB, soit 20 lectures cohérentes à terme par seconde des mêmes éléments. Le fait que votre application requière des lectures fortement cohérentes ou cohérentes à terme est un critère qui contribue à déterminer le nombre d'unités de capacité de lecture que vous devez fournir pour votre table. Par défaut, les opérations de lecture de DynamoDB sont cohérentes à terme. Certaines de ces opérations vous permettent de spécifier des lectures fortement cohérentes. • Secondary indexes – Des requêtes sur les index utilisent un débit lecture alloué. DynamoDB prend en charge deux types index secondairees (index secondaire globales et local secondary indexes). Pour en savoir plus sur les index et le débit alloué, consultez Amélioration de l'accès aux données avec les index secondaires (p. 337). Ces facteurs vous aideront à déterminer les exigences de débit de votre application que vous fournissez lorsque vous créez une table. Vous pouvez surveiller les performances à l'aide des métriques CloudWatch et même configurer des alarmes pour vous avertir si vous atteignez un certain seuil d'unités de capacité utilisées. La console DynamoDB fournit plusieurs métriques par défaut que vous pouvez passer en revue pour surveiller les performances de votre table et ajuster les exigences de débit en fonction des besoins. Pour plus d'informations, accédez à Console DynamoDB. DynamoDB répartit automatiquement vos données sur des partitions de table, qui sont stockées sur plusieurs serveurs. Pour un débit optimal, vous devez répartir les demandes de lecture aussi régulièrement que possible sur ces partitions. Par exemple, vous pourriez fournir une table avec 1 million d'unités de capacité de lecture par seconde. Si vous exécutez 1 million de demandes pour un seul élément dans la table, toute l'activité de lecture sera concentrée sur une seule partition. Toutefois, si vous répartissez vos demandes sur tous les éléments dans la table, DynamoDB peut accéder aux partitions de la table en parallèle et vous permettre d'atteindre votre objectif de débit alloué pour la table. Pour les lectures, la table suivante compare certaines valeurs de débit alloué pour différentes moyennes de tailles d'élément, de taux de demande et de combinaisons de cohérence. Taille d'élément attendue Cohérence Lectures souhaitées par seconde Débit alloué requis 4 Ko Fortement cohérente 50 50 API Version 2012-08-10 181 Amazon DynamoDB Manuel du développeur Calcul des unités de capacité Taille d'élément attendue Cohérence Lectures souhaitées par seconde Débit alloué requis 8 Ko Fortement cohérente 50 100 4 Ko Cohérente à terme 50 25 8 Ko Cohérente à terme 50 50 Les tailles d'éléments pour les lectures sont arrondies au multiple 4 KB suivant. Par exemple, un élément de 3 500 octets utilise le même débit qu'un élément 4 KB. Pour les écritures, la table suivante compare certaines valeurs de débit alloué pour différentes moyennes de tailles d'élément et de taux de demande d'écriture. Taille d'élément attendue Ecritures par seconde souhaitées Débit alloué requis 1 Ko 50 50 2 Ko 50 100 Les tailles d'éléments pour les écritures sont arrondies au multiple 1 KB suivant. Par exemple, un élément de 500 octets utilise le même débit qu'un élément 1 KB. DynamoDB affecte des ressources à vos unités de capacité de lecture et d'écriture requises et, par conséquent, vous devez rester dans les taux que vous avez demandés. Le débit alloué dépend aussi de la taille des données demandées. Si votre taux de demande de lecture ou d'écriture, associé à la taille cumulée des données demandées, dépasse la capacité réservée actuelle, DynamoDB renvoie une erreur qui indique que le niveau de débit alloué a été dépassé. Définissez votre débit alloué à l'aide du paramètre ProvisionedThroughput. Pour plus d'informations sur la configuration du paramètre ProvisionedThroughput, consultez CreateTable dans le manuel Amazon DynamoDB API Reference. Pour plus d'informations sur l'utilisation du débit alloué, consultez Instructions pour l'utilisation des tables (p. 572). Note Si vous vous attendez à de futurs pics dans votre charge de travail (par exemple, le lancement d'un nouveau produit) qui conduiront votre débit à dépasser le débit alloué actuel pour votre table, nous vous conseillons d'utiliser l'opération UpdateTable afin d'accroître la valeur ProvisionedThroughput. Pour les valeurs maximales actuelles de débit alloué par table ou par compte, consultez Limites dans DynamoDB (p. 564). Lorsque vous émettez une demande UpdateTable, l'état de la table change de AVAILABLE à UPDATING. La table reste entièrement disponible pour une utilisation pendant sa UPDATING. Pendant ce temps, DynamoDB alloue les ressources nécessaires pour prendre en charge les nouveaux niveaux de débit alloué. Lorsque ce processus est terminé, l'état de la table change de UPDATING à AVAILABLE. Calcul des unités de capacité Dans DynamoDB, les unités de capacité sont définies comme suit : API Version 2012-08-10 182 Amazon DynamoDB Manuel du développeur Calcul des unités de capacité • Une unité de capacité en lecture représente une lecture à cohérence forte par seconde, ou deux lectures cohérentes à terme par seconde, pour les éléments dont la taille peut atteindre jusqu'à 4 KB. • Une unité de capacité en écriture représente une écriture par seconde pour les éléments dont la taille peut atteindre jusqu'à 1 KB. La taille d'un élément est la somme des longueurs de ses noms et valeurs d'attribut. (Pour optimiser la consommation d'unités de capacité, nous vous recommandons de réduire la longueur des noms d'attributs). La taille d'une valeur d'attribut Null ou Boolean est (longueur du nom d'attribut + un octet). Un attribut de type List ou Map a besoin de 3 octets de surcharge, quel que soit son contenu. La taille d'un attribut List ou Map vide est (longueur du nom d'attribut + 3 octets). Si l'attribut n'est pas vide, la taille est (longueur du nom d'attribut + somme (longueur des valeurs d'attributs) + 3 octets). Opérations de lecture La section suivante décrit comment les opérations de lecture DynamoDB utilisent des unités de capacité de lecture : • GetItem—lit un seul élément d'une table. Pour le calcul des unités de capacité, la taille d'un élément est arrondie à la limite 4 KB suivante. Par exemple, si vous lisez un élément de 3,5 Ko, DynamoDB arrondit sa taille à 4 KB. Si vous lisez un élément de 10 Ko, DynamoDB arrondit sa taille à 12 Ko. • BatchGetItem—lit jusqu'à 100 éléments à partir d'une ou de plusieurs tables. DynamoDB traite chaque élément du lot comme une demande GetItem individuelle, ainsi DynamoDB arrondit tout d'abord la taille de chaque élément à la limite 4 KB suivante, puis calcule la taille totale. Le résultat n'est pas nécessairement le même que la taille totale de tous les éléments. Par exemple, si BatchGetItem lit un élément de 1,5 Ko et un élément 6,5 Ko, DynamoDB calcule la taille comme étant de 12 Ko (4 KB + 8 Ko), et non de 8 Ko (1,5 Ko+6,5 Ko). • Query— lit plusieurs éléments ayant la même valeur de clé de partition. Tous les éléments renvoyés sont traités comme une seule opération de lecture, dans laquelle DynamoDB calcule la taille totale de tous les éléments, puis l'arrondit à la limite 4 KB suivante. Par exemple, supposons que votre requête renvoie 10 éléments dont la taille combinée est de 40,8 Ko. DynamoDB arrondit la taille d'élément pour l'opération à 44 Ko. Si une requête renvoie 1 500 éléments de 64 octets chacun, la taille cumulée est de 96 Ko. • Scan—lit tous les éléments d'une table. DynamoDB porte sur la taille des éléments qui sont évalués, et non sur la taille des éléments renvoyés par l'analyse. Si vous effectuez une opération de lecture sur un élément qui n'existe pas, DynamoDB utilise toujours un débit de lecture alloué : une demande de lecture fortement cohérente utilise une unité de capacité de lecture, tandis qu'une demande de lecture cohérente à terme utilise 0,5 d'une unité de capacité de lecture. Pour toute opération qui renvoie des éléments, vous pouvez demander un sous-ensemble d'attributs à récupérer. Néanmoins, cela n'a aucun impact sur les calculs de taille d'élément. En outre, Query et Scan peuvent renvoyer des nombres d'éléments au lieu de valeurs d'attribut. L'obtention du nombre d'éléments utilise la même quantité d'unités de capacité de lecture et est soumise aux mêmes calculs de taille d'élément, parce que DynamoDB doit lire chaque élément pour incrémenter le nombre. Opération de lecture et cohérence en lecture Les calculs précédents supposent des demandes de lecture fortement cohérentes. Pour une demande de lecture cohérente à terme, l'opération utilise seulement la moitié des unités de capacité. Pour une API Version 2012-08-10 183 Amazon DynamoDB Manuel du développeur Liste et description des tables lecture cohérente à terme, si la taille d'un élément total est de 80 Ko, l'opération utilise seulement 10 unités de capacité. Opérations d'écriture La section suivante décrit comment les opérations d'écriture DynamoDB utilisent des unités de capacité d'écriture : • PutItem—écrit un seul élément sur une table. Si un élément avec la même clé primaire existe dans la table, l'opération remplace l'élément. Pour calculer la consommation de débit alloué, la taille d'élément qui compte est la plus grande des deux. • UpdateItem— modifie un seul élément du tableau. DynamoDB porte sur la taille de l'élément tel qu'il apparaît avant et après la mise à jour. Le débit alloué utilisé reflète la plus grande de ces tailles d'élément. Même si vous mettez à jour simplement un sous-ensemble d'attributs de l'élément, UpdateItem utilise toujours la totalité du volume de débit alloué (la plus importante des tailles d'élément « avant » et « après »). • DeleteItem—supprime un seul élément d'une table. La consommation de débit alloué s'appuie sur la taille de l'élément supprimé. • BatchWriteItem—écrit jusqu'à 25 éléments d'une ou de plusieurs tables. DynamoDB traite chaque élément du lot comme une demande PutItem ou DeleteItem individuelle (les mises à jour ne sont pas prises en charge), ainsi DynamoDB arrondit tout d'abord la taille de chaque élément à la limite 1 KB suivante, puis calcule la taille totale. Le résultat n'est pas nécessairement le même que la taille totale de tous les éléments. Par exemple, si BatchWriteItem écrit un élément de 500 octets et un élément de 3,5 Ko, DynamoDB calcule la taille de 5 Ko (1 Ko + 4 Ko), pas de 4 Ko (500 octets + 3,5 Ko). Pour les opérations PutItem, UpdateItem, et DeleteItem, DynamoDB arrondit la taille de l'élément à la limite 1 KB suivante. Par exemple, si vous placez ou supprimez un élément de 1,6 Ko, DynamoDB arrondit la taille d'élément à 2 Ko. PutItem, UpdateItem et DeleteItem permettent des écritures conditionnelles, dans lesquelles vous spécifiez une expression qui doit évaluer la valeur true pour que l'opération réussisse. Si l'expression a la valeur false, DynamoDB consomme toujours des unités de capacité d'écriture de la table : • Si l'élément existe, le nombre d'unités de capacité d'écriture utilisées dépend de la taille de l'élément. (Par exemple, un échec d'écriture conditionnelle d'un élément 1 KB utiliserait une unité de capacité d'écriture ; si l'élément faisait deux fois cette taille, l'échec d'écriture conditionnelle utiliserait deux unités de capacité d'écriture.) • Si l'élément n'existe pas, DynamoDB utilisera une unité de capacité d'écriture. Liste et description des tables Pour obtenir une liste de toutes vos tables, utilisez l'opération ListTables. Un seul appel ListTables peut renvoyer un maximum de 100 noms de table. Si vous avez plus de 100 tables, vous pouvez demander que ListTables renvoie des résultats paginés, afin que vous puissiez récupérer tous les noms de table. Pour déterminer la structure de toute table, utilisez l'opération DescribeTable. Les métadonnées renvoyées par DescribeTable incluent l'horodatage au moment de la création, son schéma clé, ses paramètres de débit alloué, sa taille estimée et tout index secondaire présent. Note Si vous exécutez une demande DescribeTable immédiatement après une demande CreateTable, DynamoDB peut renvoyer un ResourceNotFoundException. Cela est dû au fait que DescribeTable utilise une demande cohérente à terme et que les métadonnées API Version 2012-08-10 184 Amazon DynamoDB Manuel du développeur Balisage pour DynamoDB pour votre table peuvent ne pas être disponibles à ce moment-là. Attendez quelques secondes, puis réessayez d'envoyer la demande DescribeTable. Dans le calcul du stockage utilisé par la table, DynamoDB ajoute 100 bytes de surcharge à chaque élément pour l'indexation. L'opération DescribeTable renvoie une taille de table qui inclut cette surcharge. Cette surcharge est également incluse lors de la facturation qui vous est faite des frais de stockage. Cependant, cette 100 bytes supplémentaire n'est pas utilisée dans le calcul de l'unité de capacité. Pour en savoir plus sur les tarifs, consultez Tarification DynamoDB. Balisage pour DynamoDB Vous pouvez étiqueter les ressources DynamoDB avec des balises. Les balises vous permettent de classer vos ressources de différentes manières, par exemple, par objectif, par propriétaire, par environnement ou selon d'autres critères. Les balises vous aident à : • Identifier rapidement une ressource en fonction des balises qui lui ont été attribuées. • Consulter les factures AWS réparties par balises. Note Les index secondaires locaux (LSI) et les index secondaires globaux (GSI) associés aux tables balisées sont étiquetés avec les mêmes balises automatiquement. Actuellement, l'utilisation des flux DynamoDB ne peut pas être balisée. Le balisage est pris en charge par les services AWS comme Amazon EC2, Amazon S3, DynamoDB, etc. Un balisage efficace peut fournir un aperçu sur les coûts en vous autorisant à créer des rapports sur les services associés à une balise spécifique. Pour commencer à utiliser le balisage, vous devez : 1. Comprendre Restrictions liées au balisage (p. 185). 2. Créer des balises en utilisant Opérations de balisage (p. 186). 3. Utiliser Rapport de répartition des coûts (p. 186) pour assurer le suivi des coûts AWS par balise active. En dernier lieu, il est conseillé de suivre les stratégie de balisage optimales. Pour plus d'informations, consultez Stratégies de balisage AWS. Restrictions liées au balisage Chaque balise est constituée d'une clé et d'une valeur que vous définissez. Les restrictions suivantes s'appliquent : • Chaque table DynamoDB peut avoir une seule balise avec la même clé. Si vous tentez d'ajouter une balise existante (même clé), la valeur de la balise existante sera mise à jour avec la nouvelle valeur. • • • • Les clés et valeurs de balise sont sensibles à la casse. Longueur de clé maximale : 128 caractères Unicode Longueur de valeur maximale : 256 caractères Unicode Les caractères autorisés sont les lettres, les espaces blancs et les chiffres, ainsi que les caractères spéciaux suivants : + - = . _ : / • Nombre maximal de balises par ressource : 50 • Les noms et les valeurs des balises attribuées par AWS reçoivent automatiquement le préfixe aws:, que vous ne pouvez pas attribuer. Les noms des balises attribuées par AWS ne sont pas pris en API Version 2012-08-10 185 Amazon DynamoDB Manuel du développeur Balisage pour DynamoDB compte pour la limite de balise de 50. Les noms des balises attribuées par l'utilisateur ont le préfixe user: dans le rapport de répartition des coûts. • Vous ne pouvez pas baliser une ressource en même temps que sa création. Le balisage est une action distincte qui peut être effectuée uniquement après la création de la ressource. • Vous ne pouvez pas antidater l'application d'une balise. Opérations de balisage Cette section décrit l'utilisation de la console DynamoDB ou de l'interface de ligne de commande pour ajouter, répertorier, modifier ou supprimer des balises. Vous pouvez ensuite activer ces balises définies par l'utilisateur afin de les faire apparaître sur la console Gestion de la facturation et des coûts pour le suivi de la répartition des coûts. Pour plus d'informations, consultez Rapport de répartition des coûts (p. 186). Pour les modifications en bloc, vous pouvez également utiliser Tag Editor dans l'AWS Management Console. Pour plus d'informations, consultez Utilisation de Tag Editor. Pour utiliser l'API à la place, consultez Amazon DynamoDB API Reference. Rubriques • Balisage (console) (p. 186) • Balisage (interface de ligne de commande) (p. 186) Balisage (console) Pour utiliser la console afin d'ajouter, de modifier ou de supprimer des balises : 1. Ouvrez la console DynamoDB à l'adresse https://console.aws.amazon.com/dynamodb/home. 2. Choisissez une table, puis choisissez l'onglet Paramètres. Vous pouvez ajouter, répertorier, modifier ou supprimer des balises ici. Dans cet exemple, la balise Movies a été créée avec la valeurmoviesProd pour la table Movies. Balisage (interface de ligne de commande) Pour ajouter la balise Owner avec la valeur blueTeam pour la table Movies : aws dynamodb tag-resource \ --resource-arn arn:aws:dynamodb:us-east-1:123456789012:table/Movies \ --tags Key=Owner,Value=blueTeam Pour répertorier toutes les balises associées à la table Movies : aws dynamodb list-tags-of-resource \ --resource-arn arn:aws:dynamodb:us-east-1:123456789012:table/Movies Rapport de répartition des coûts AWS utilise les balises pour organiser les coûts des ressources sur vos rapports de répartition des coûts. AWS fournit deux types de balises de répartition des coûts : • Une balise générée par AWS. AWS définit, crée et applique cette balise pour vous. • Balises définies par l'utilisateur. Vous définissez, créez et appliquez ces balises. API Version 2012-08-10 186 Amazon DynamoDB Manuel du développeur Utilisation des tables : Java Vous devez activer les deux types de balises séparément afin de les faire apparaître dans l'Explorateur de coûts ou sur un rapport de répartition des coûts. Pour activer les balises générées par AWS : 1. Connectez-vous à AWS Management Console et ouvrez la console Gestion de la facturation et des coûts à partir de l'adresse https://console.aws.amazon.com/billing/home#/. 2. Dans le volet de navigation, choisissez Balises de répartition des coûts. 3. Sous Balises de répartition des coûts générées par AWS, choisissez Activer. Pour activer les balises définies par l'utilisateur : 1. Connectez-vous à AWS Management Console et ouvrez la console Gestion de la facturation et des coûts à partir de l'adresse https://console.aws.amazon.com/billing/home#/. 2. Dans le volet de navigation, choisissez Balises de répartition des coûts. 3. Sous Balises de répartition des coûts définies par l'utilisateur, choisissez Activer. Une fois que vous avez créé et activé des balises, AWS génère un rapport de répartition des coûts faisant apparaître la consommation et les coûts regroupés par balise active. Le rapport de répartition des coûts inclut tous les coûts AWS de chaque période de facturation. Ce rapport inclut les ressources balisées et non balisées, afin que vous puissiez organiser clairement les frais pour les ressources. Note Pour l'instant, les données transférées depuis DynamoDB ne sont pas réparties par balises sur les rapports de répartition des coûts. Pour plus d'informations, consultez Utilisation des balises de répartition des coûts. Utilisation des tables : Java Rubriques • Création d'une table (p. 187) • Mise à jour d'une table (p. 188) • Suppression d'une table (p. 189) • Liste des tables (p. 189) • Exemple : Créer, mettre à jour, supprimer et afficher les tables à l'aide de l'API Document de AWS SDK for Java (p. 190) Vous pouvez utiliser le AWS SDK for Java pour créer, mettre à jour et supprimer des tables, répertorier toutes les tables de votre compte ou obtenir des informations sur une table spécifique. Voici les étapes courantes des opérations de table à l'aide de l'API Document de AWS SDK for Java. Création d'une table Pour créer une table, vous devez fournir le nom de la table, sa clé primaire et les valeurs de débit alloué. L'exemple de code suivant crée un exemple de table qui utilise un Id d'attribut de type numérique comme clé primaire. Pour créer une table à l'aide de l'API AWS SDK for Java : 1. Créez une instance de la classe DynamoDB. API Version 2012-08-10 187 Amazon DynamoDB Manuel du développeur Utilisation des tables : Java 2. Instanciez un CreateTableRequest pour fournir les informations de demande. Vous devez fournir le nom de la table, les définitions d'attribut, le schéma de clé et les valeurs de débit provisionné. 3. Exécutez la méthode createTable en fournissant l'objet de requête comme paramètre. L'exemple de code suivant démontre les étapes précédentes. DynamoDB dynamoDB = new DynamoDB(new AmazonDynamoDBClient( new ProfileCredentialsProvider())); ArrayList<AttributeDefinition> attributeDefinitions= new ArrayList<AttributeDefinition>(); attributeDefinitions.add(new AttributeDefinition().withAttributeName("Id").withAttributeType("N")); ArrayList<KeySchemaElement> keySchema = new ArrayList<KeySchemaElement>(); keySchema.add(new KeySchemaElement().withAttributeName("Id").withKeyType(KeyType.HASH)); CreateTableRequest request = new CreateTableRequest() .withTableName(tableName) .withKeySchema(keySchema) .withAttributeDefinitions(attributeDefinitions) .withProvisionedThroughput(new ProvisionedThroughput() .withReadCapacityUnits(5L) .withWriteCapacityUnits(6L)); Table table = dynamoDB.createTable(request); table.waitForActive(); La table n'est pas prête à être utilisée jusqu'à ce que DynamoDB la crée et définisse son état sur ACTIVE. La demande createTable retourne un objet Table que vous pouvez utiliser pour obtenir plus d'informations sur la table. TableDescription tableDescription = dynamoDB.getTable(tableName).describe(); System.out.printf("%s: %s \t ReadCapacityUnits: %d \t WriteCapacityUnits: %d", tableDescription.getTableStatus(), tableDescription.getTableName(), tableDescription.getProvisionedThroughput().getReadCapacityUnits(), tableDescription.getProvisionedThroughput().getWriteCapacityUnits()); Vous pouvez appeler la méthode describe du client pour obtenir les informations de table à tout moment. TableDescription tableDescription = dynamoDB.getTable(tableName).describe(); Mise à jour d'une table Vous pouvez mettre à jour uniquement les valeurs de débit alloué d'une table existante. Selon les exigences de votre application, vous pourrez avoir besoin de mettre à jour ces valeurs. API Version 2012-08-10 188 Amazon DynamoDB Manuel du développeur Utilisation des tables : Java Note Vous pouvez augmenter le nombre d'unités de capacité de lecture et d'unités de capacité d'écriture à tout moment. Cependant, vous pouvez réduire ces valeurs uniquement quatre fois sur une période de 24 heures. Pour obtenir des instructions et des limitations supplémentaires, consultez Spécification d'exigences de lecture et d'écriture pour des tables (p. 180). Pour mettre à jour une table à l'aide de l'API AWS SDK for Java : 1. Créez une instance de la classe Table. 2. Créez une instance de la classe ProvisionedThroughput pour fournir les nouvelles valeurs de débit. 3. Exécutez la méthode updateTable en fournissant l'instance ProvisionedThroughput comme paramètre. L'exemple de code suivant démontre les étapes précédentes. DynamoDB dynamoDB = new DynamoDB(new AmazonDynamoDBClient( new ProfileCredentialsProvider())); Table table = dynamoDB.getTable("ProductCatalog"); ProvisionedThroughput provisionedThroughput = new ProvisionedThroughput() .withReadCapacityUnits(15L) .withWriteCapacityUnits(12L); table.updateTable(provisionedThroughput); table.waitForActive(); Suppression d'une table Pour supprimer une table : 1. Créez une instance de la classe Table. 2. Créez une instance de la classe DeleteTableRequest et fournissez le nom de la table que vous voulez supprimer. 3. Exécutez la méthode deleteTable en fournissant l'instance Table comme paramètre. L'exemple de code suivant démontre les étapes précédentes. DynamoDB dynamoDB = new DynamoDB(new AmazonDynamoDBClient( new ProfileCredentialsProvider())); Table table = dynamoDB.getTable("ProductCatalog"); table.delete(); table.waitForDelete(); Liste des tables Pour afficher les tables de votre compte, créez une instance de DynamoDB et exécutez la méthode listTables. L'opération ListTables ne requiert aucun paramètre. API Version 2012-08-10 189 Amazon DynamoDB Manuel du développeur Utilisation des tables : Java DynamoDB dynamoDB = new DynamoDB(new AmazonDynamoDBClient( new ProfileCredentialsProvider())); TableCollection<ListTablesResult> tables = dynamoDB.listTables(); Iterator<Table> iterator = tables.iterator(); while (iterator.hasNext()) { Table table = iterator.next(); System.out.println(table.getTableName()); } Exemple : Créer, mettre à jour, supprimer et afficher les tables à l'aide de l'API Document de AWS SDK for Java L'exemple de code suivant exemple utilise l'API Document AWS SDK for Java pour créer, mettre à jour et supprimer une table (ExampleTable). Dans le cadre de la mise à jour de la table, les valeurs de débit alloué sont augmentées. L'exemple affiche aussi toutes les tables de votre compte et obtient la description d'une table spécifique. Pour obtenir les instructions pas à pas afin d'exécuter l'exemple suivant, consultez Exemples de Code Java (p. 173). // Copyright 2012-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. // Licensed under the Apache License, Version 2.0. package com.amazonaws.codesamples.document; import java.util.ArrayList; import java.util.Iterator; import import import import import import import import import import import import com.amazonaws.auth.profile.ProfileCredentialsProvider; com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient; com.amazonaws.services.dynamodbv2.document.DynamoDB; com.amazonaws.services.dynamodbv2.document.Table; com.amazonaws.services.dynamodbv2.document.TableCollection; com.amazonaws.services.dynamodbv2.model.AttributeDefinition; com.amazonaws.services.dynamodbv2.model.CreateTableRequest; com.amazonaws.services.dynamodbv2.model.KeySchemaElement; com.amazonaws.services.dynamodbv2.model.KeyType; com.amazonaws.services.dynamodbv2.model.ListTablesResult; com.amazonaws.services.dynamodbv2.model.ProvisionedThroughput; com.amazonaws.services.dynamodbv2.model.TableDescription; public class DocumentAPITableExample { static DynamoDB dynamoDB = new DynamoDB(new AmazonDynamoDBClient( new ProfileCredentialsProvider())); static String tableName = "ExampleTable"; public static void main(String[] args) throws Exception { createExampleTable(); listMyTables(); getTableInformation(); updateExampleTable(); deleteExampleTable(); } API Version 2012-08-10 190 Amazon DynamoDB Manuel du développeur Utilisation des tables : Java static void createExampleTable() { try { ArrayList<AttributeDefinition> attributeDefinitions = new ArrayList<AttributeDefinition>(); attributeDefinitions.add(new AttributeDefinition() .withAttributeName("Id") .withAttributeType("N")); ArrayList<KeySchemaElement> keySchema = new ArrayList<KeySchemaElement>(); keySchema.add(new KeySchemaElement() .withAttributeName("Id") .withKeyType(KeyType.HASH)); //Partition key CreateTableRequest request = new CreateTableRequest() .withTableName(tableName) .withKeySchema(keySchema) .withAttributeDefinitions(attributeDefinitions) .withProvisionedThroughput(new ProvisionedThroughput() .withReadCapacityUnits(5L) .withWriteCapacityUnits(6L)); System.out.println("Issuing CreateTable request for " + tableName); Table table = dynamoDB.createTable(request); System.out.println("Waiting for " + tableName + " to be created...this may take a while..."); table.waitForActive(); getTableInformation(); } catch (Exception e) { System.err.println("CreateTable request failed for " + tableName); System.err.println(e.getMessage()); } } static void listMyTables() { TableCollection<ListTablesResult> tables = dynamoDB.listTables(); Iterator<Table> iterator = tables.iterator(); System.out.println("Listing table names"); while (iterator.hasNext()) { Table table = iterator.next(); System.out.println(table.getTableName()); } } static void getTableInformation() { System.out.println("Describing " + tableName); API Version 2012-08-10 191 Amazon DynamoDB Manuel du développeur Utilisation de tables : .NET TableDescription tableDescription = dynamoDB.getTable(tableName).describe(); System.out.format("Name: %s:\n" + "Status: %s \n" + "Provisioned Throughput (read capacity units/sec): %d \n" + "Provisioned Throughput (write capacity units/sec): %d \n", tableDescription.getTableName(), tableDescription.getTableStatus(), tableDescription.getProvisionedThroughput().getReadCapacityUnits(), tableDescription.getProvisionedThroughput().getWriteCapacityUnits()); } static void updateExampleTable() { Table table = dynamoDB.getTable(tableName); System.out.println("Modifying provisioned throughput for " + tableName); try { table.updateTable(new ProvisionedThroughput() .withReadCapacityUnits(6L).withWriteCapacityUnits(7L)); table.waitForActive(); } catch (Exception e) { System.err.println("UpdateTable request failed for " + tableName); System.err.println(e.getMessage()); } } static void deleteExampleTable() { Table table = dynamoDB.getTable(tableName); try { System.out.println("Issuing DeleteTable request for " + tableName); table.delete(); System.out.println("Waiting for " + tableName + " to be deleted...this may take a while..."); table.waitForDelete(); } catch (Exception e) { System.err.println("DeleteTable request failed for " + tableName); System.err.println(e.getMessage()); } } } Utilisation de tables : .NET Rubriques • Création d'une table (p. 193) • Mise à jour d'une table (p. 194) • Suppression d'une table (p. 195) API Version 2012-08-10 192 Amazon DynamoDB Manuel du développeur Utilisation de tables : .NET • Liste des tables (p. 195) • Exemple : créer, mettre à jour, supprimer et répertorier des tables à l'aide de l'API de bas niveau d'AWS SDK pour .NET (p. 196) Vous pouvez utiliser le Kit AWS SDK pour .NET pour créer, mettre à jour et supprimer des tables, répertorier toutes les tables de votre compte ou obtenir des informations sur une table spécifique. Voici les étapes courantes pour les opérations de table à l'aide de Kit AWS SDK pour .NET. 1. Créez une instance de la classe AmazonDynamoDBClient (le client). 2. Fournissez les paramètres obligatoires et facultatifs pour l'opération en créant les objets de requête correspondants. Par exemple, créez un objet CreateTableRequest pour créer une table et un objet UpdateTableRequest pour mettre à jour une table existante. 3. Exécutez la méthode appropriée fournie par le client que vous avez créée à l'étape précédente. Création d'une table Pour créer une table, vous devez fournir le nom de la table, sa clé primaire et les valeurs de débit alloué. Voici les étapes pour créer une table en utilisant l'API de bas niveau .NET. 1. Créez une instance de la classe AmazonDynamoDBClient. 2. Créez une instance de la classe CreateTableRequest pour fournir l'information de requête. Vous devez fournir le nom de la table, la clé primaire et les valeurs du débit alloué. 3. Exécutez la méthode AmazonDynamoDBClient.CreateTable en fournissant l'objet de requête comme un paramètre. L'extrait de code C# suivant illustre les étapes précédentes. L'exemple crée une table (ProductCatalog) qui utilise l'Id comme clé primaire et ensemble de valeurs de débit alloué. En fonction des besoins de votre application, vous pouvez mettre à jour les valeurs de débit alloué en utilisant l'API UpdateTable. AmazonDynamoDBClient client = new AmazonDynamoDBClient(); string tableName = "ProductCatalog"; var request = new CreateTableRequest { TableName = tableName, AttributeDefinitions = new List<AttributeDefinition>() { new AttributeDefinition { AttributeName = "Id", AttributeType = "N" } }, KeySchema = new List<KeySchemaElement>() { new KeySchemaElement { AttributeName = "Id", KeyType = "HASH" //Partition key API Version 2012-08-10 193 Amazon DynamoDB Manuel du développeur Utilisation de tables : .NET } }, ProvisionedThroughput = new ProvisionedThroughput { ReadCapacityUnits = 10, WriteCapacityUnits = 5 } }; var response = client.CreateTable(request); Vous devez attendre que DynamoDB ait créé la table et défini l'état de la table sur ACTIVE. La réponse CreateTable inclut la propriété TableDescription qui fournit les informations de table nécessaires. var result = response.CreateTableResult; var tableDescription = result.TableDescription; Console.WriteLine("{1}: {0} \t ReadCapacityUnits: {2} \t WriteCapacityUnits: {3}", tableDescription.TableStatus, tableDescription.TableName, tableDescription.ProvisionedThroughput.ReadCapacityUnits, tableDescription.ProvisionedThroughput.WriteCapacityUnits); string status = tableDescription.TableStatus; Console.WriteLine(tableName + " - " + status); Vous pouvez également appeler la méthode DescribeTable du client pour obtenir des informations de table à tout moment. var res = client.DescribeTable(new DescribeTableRequest{TableName = "ProductCatalog"}); Mise à jour d'une table Vous pouvez mettre à jour uniquement les valeurs de débit alloué d'une table existante. Selon les exigences de votre application, vous pourrez avoir besoin de mettre à jour ces valeurs. Note Vous pouvez augmenter le nombre d'unités de capacité de lecture et d'unités de capacité d'écriture à tout moment. Vous pouvez également diminuer le nombre d'unités de capacité de lecture à tout moment. Cependant, vous pouvez réduire le nombre d'unités de capacité d'écriture uniquement de quatre fois sur une période de 24 heures. Toute modification que vous apportez doit être au moins de 10 % différente par rapport aux valeurs actuelles. Pour obtenir des instructions et des limitations supplémentaires, consultez Spécification d'exigences de lecture et d'écriture pour des tables (p. 180). Voici les étapes pour mettre à jour une table en utilisant l'API de bas niveau .NET. 1. Créez une instance de la classe AmazonDynamoDBClient. 2. Créez une instance de la classe UpdateTableRequest pour fournir l'information de requête. Vous devez fournir le nom de la table et les nouvelles valeurs du débit alloué. 3. Exécutez la méthode AmazonDynamoDBClient.UpdateTable en fournissant l'objet de requête comme un paramètre. API Version 2012-08-10 194 Amazon DynamoDB Manuel du développeur Utilisation de tables : .NET L'extrait de code C# suivant illustre les étapes précédentes. AmazonDynamoDBClient client = new AmazonDynamoDBClient(); string tableName = "ExampleTable"; var request = new UpdateTableRequest() { TableName = tableName, ProvisionedThroughput = new ProvisionedThroughput() { // Provide new values. ReadCapacityUnits = 20, WriteCapacityUnits = 10 } }; var response = client.UpdateTable(request); Suppression d'une table Voici les étapes pour supprimer une table en utilisant l'API de bas niveau .NET. 1. Créez une instance de la classe AmazonDynamoDBClient. 2. Créez une instance de la classe DeleteTableRequest et fournissez le nom de la table que vous voulez supprimer. 3. Exécutez la méthode AmazonDynamoDBClient.DeleteTable en fournissant l'objet de requête comme un paramètre. L'extrait de code C# suivant illustre les étapes précédentes. AmazonDynamoDBClient client = new AmazonDynamoDBClient(); string tableName = "ExampleTable"; var request = new DeleteTableRequest{ TableName = tableName }; var response = client.DeleteTable(request); Liste des tables Pour répertorier les tables de votre compte à l'aide de l'API de bas niveau AWS SDK pour .NET, créez une instance du AmazonDynamoDBClient et exécutez la méthode ListTables. L'opération ListTables ne requiert aucun paramètre. Cependant, vous pouvez spécifier des paramètres facultatifs. Par exemple, vous pouvez définir le paramètre Limit si vous souhaitez utiliser la pagination pour limiter le nombre de noms de tables par page. Cela nécessite de votre part la création d'un objet ListTablesRequest et la fourniture de paramètres facultatifs, comme illustré dans l'extrait de code C# suivant. Avec la taille de la page, la demande définit le paramètre ExclusiveStartTableName. À l'origine, ExclusiveStartTableName est null, toutefois, après l'extraction de la première page de résultats, pour récupérer la page suivante de résultats, vous devez définir cette valeur de paramètre sur la propriété LastEvaluatedTableName du résultat actuel. AmazonDynamoDBClient client = new AmazonDynamoDBClient(); // Initial value for the first page of table names. string lastEvaluatedTableName = null; do { // Create a request object to specify optional parameters. API Version 2012-08-10 195 Amazon DynamoDB Manuel du développeur Utilisation de tables : .NET var request = new ListTablesRequest { Limit = 10, // Page size. ExclusiveStartTableName = lastEvaluatedTableName }; var response = client.ListTables(request); ListTablesResult result = response.ListTablesResult; foreach (string name in result.TableNames) Console.WriteLine(name); lastEvaluatedTableName = result.LastEvaluatedTableName; } while (lastEvaluatedTableName != null); Exemple : créer, mettre à jour, supprimer et répertorier des tables à l'aide de l'API de bas niveau d'AWS SDK pour .NET L'exemple C# suivant crée, met à jour et supprime une table (ExampleTable). Il répertorie également toutes les tables de votre compte et obtient la description d'une table spécifique. La mise à jour de la table augmente les valeurs de débit alloué. Pour obtenir les instructions pas à pas afin de tester l'exemple suivant, consultez Exemples de code .NET (p. 175). using using using using using System; System.Collections.Generic; Amazon.DynamoDBv2; Amazon.DynamoDBv2.Model; Amazon.Runtime; namespace com.amazonaws.codesamples { class LowLevelTableExample { private static AmazonDynamoDBClient client = new AmazonDynamoDBClient(); private static string tableName = "ExampleTable"; static void Main(string[] args) { try { CreateExampleTable(); ListMyTables(); GetTableInformation(); UpdateExampleTable(); DeleteExampleTable(); Console.WriteLine("To continue, press Enter"); Console.ReadLine(); } catch (AmazonDynamoDBException e) { Console.WriteLine(e.Message); } catch (AmazonServiceException e) { Console.WriteLine(e.Message); } catch (Exception e) { Console.WriteLine(e.Message); } API Version 2012-08-10 196 Amazon DynamoDB Manuel du développeur Utilisation de tables : .NET } private static void CreateExampleTable() { Console.WriteLine("\n*** Creating table ***"); var request = new CreateTableRequest { AttributeDefinitions = new List<AttributeDefinition>() { new AttributeDefinition { AttributeName = "Id", AttributeType = "N" }, new AttributeDefinition { AttributeName = "ReplyDateTime", AttributeType = "N" } }, KeySchema = new List<KeySchemaElement> { new KeySchemaElement { AttributeName = "Id", KeyType = "HASH" //Partition key }, new KeySchemaElement { AttributeName = "ReplyDateTime", KeyType = "RANGE" //Sort key } }, ProvisionedThroughput = new ProvisionedThroughput { ReadCapacityUnits = 5, WriteCapacityUnits = 6 }, TableName = tableName }; var response = client.CreateTable(request); var tableDescription = response.TableDescription; Console.WriteLine("{1}: {0} \t ReadsPerSec: {2} \t WritesPerSec: {3}", tableDescription.TableStatus, tableDescription.TableName, tableDescription.ProvisionedThroughput.ReadCapacityUnits, tableDescription.ProvisionedThroughput.WriteCapacityUnits); string status = tableDescription.TableStatus; Console.WriteLine(tableName + " - " + status); WaitUntilTableReady(tableName); } API Version 2012-08-10 197 Amazon DynamoDB Manuel du développeur Utilisation de tables : .NET private static void ListMyTables() { Console.WriteLine("\n*** listing tables ***"); string lastTableNameEvaluated = null; do { var request = new ListTablesRequest { Limit = 2, ExclusiveStartTableName = lastTableNameEvaluated }; var response = client.ListTables(request); foreach (string name in response.TableNames) Console.WriteLine(name); lastTableNameEvaluated = response.LastEvaluatedTableName; } while (lastTableNameEvaluated != null); } private static void GetTableInformation() { Console.WriteLine("\n*** Retrieving table information ***"); var request = new DescribeTableRequest { TableName = tableName }; var response = client.DescribeTable(request); TableDescription description = response.Table; Console.WriteLine("Name: {0}", description.TableName); Console.WriteLine("# of items: {0}", description.ItemCount); Console.WriteLine("Provision Throughput (reads/sec): {0}", description.ProvisionedThroughput.ReadCapacityUnits); Console.WriteLine("Provision Throughput (writes/sec): {0}", description.ProvisionedThroughput.WriteCapacityUnits); } private static void UpdateExampleTable() { Console.WriteLine("\n*** Updating table ***"); var request = new UpdateTableRequest() { TableName = tableName, ProvisionedThroughput = new ProvisionedThroughput() { ReadCapacityUnits = 6, WriteCapacityUnits = 7 } }; var response = client.UpdateTable(request); API Version 2012-08-10 198 Amazon DynamoDB Manuel du développeur Utilisation des tables : PHP WaitUntilTableReady(tableName); } private static void DeleteExampleTable() { Console.WriteLine("\n*** Deleting table ***"); var request = new DeleteTableRequest { TableName = tableName }; var response = client.DeleteTable(request); Console.WriteLine("Table is being deleted..."); } private static void WaitUntilTableReady(string tableName) { string status = null; // Let us wait until table is created. Call DescribeTable. do { System.Threading.Thread.Sleep(5000); // Wait 5 seconds. try { var res = client.DescribeTable(new DescribeTableRequest { TableName = tableName }); Console.WriteLine("Table name: {0}, status: {1}", res.Table.TableName, res.Table.TableStatus); status = res.Table.TableStatus; } catch (ResourceNotFoundException) { // DescribeTable is eventually consistent. So you might // get resource not found. So we handle the potential exception. } } while (status != "ACTIVE"); } } } Utilisation des tables : PHP Rubriques • Création d'une table (p. 200) • Mise à jour d'une table (p. 201) • Suppression d'une table (p. 201) • Liste des tables (p. 202) • Exemple : Créer, mettre à jour, supprimer et afficher les tables à l'aide de l'API de bas niveau du kit SDK AWS pour PHP (p. 203) API Version 2012-08-10 199 Amazon DynamoDB Manuel du développeur Utilisation des tables : PHP Vous pouvez utiliser le AWS SDK pour PHP pour créer, mettre à jour et supprimer des tables, répertorier toutes les tables de votre compte ou obtenir des informations sur une table spécifique. Voici les étapes courantes pour les opérations DynamoDB à l'aide du Kit SDK pour PHP : 1. Créer une instance du client DynamoDB. 2. Fournir les paramètres d'une opération DynamoDB, y compris les paramètres facultatifs. 3. Charger la réponse à partir de DynamoDB dans une variable locale pour votre application. Création d'une table Pour créer une table, vous devez fournir le nom de la table, sa clé primaire et les valeurs de débit alloué. L'exemple de code PHP suivant crée une ExampleTable qui utilise un attribut Id de type numérique comme clé primaire. L'extrait de code PHP suivant crée une table (ProductCatalog) qui utilise l'Id comme clé primaire et ensemble de valeurs de débit alloué. En fonction des besoins de votre application, vous pouvez mettre à jour les valeurs de débit alloué avec la méthode updateTable. require 'vendor/autoload.php'; $sdk = new Aws\Sdk([ 'region' => 'us-west-2', 'version' => 'latest' ]); $dynamodb = $sdk->createDynamoDb(); $tableName = 'ExampleTable'; echo "# Creating table $tableName...\n"; $result = $dynamodb->createTable([ 'TableName' => $tableName, 'AttributeDefinitions' => [ [ 'AttributeName' => 'Id', 'AttributeType' => 'N' ] ], 'KeySchema' => [ [ 'AttributeName' => 'Id', 'KeyType' => 'HASH' ] ], 'ProvisionedThroughput' => [ 'ReadCapacityUnits' => 5, 'WriteCapacityUnits' => 6 ] ]); print_r($result->getPath('TableDescription')); Vous devez attendre que DynamoDB crée la table et définisse le statut de la table sur ACTIVE avant que vous ne puissiez placer les données dans la table. Vous pouvez utiliser la fonction waitUntil du client pour attendre que l'état de la table devienne ACTIVE. L'extrait de code suivant montre comment procéder. Le tableau associatif @waiter est facultatif : il vous permet de spécifier les options d'interrogation pour waitUntil. $dynamodb->waitUntil('TableExists', [ API Version 2012-08-10 200 Amazon DynamoDB Manuel du développeur Utilisation des tables : PHP 'TableName' => $tableName, '@waiter' => [ 'delay' => 5, 'maxAttempts' => 20 ] ]); Mise à jour d'une table Vous pouvez mettre à jour une table existante, en modifier ses valeurs de débit provisionné ou ses index secondaires. Immédiatement après une demande UpdateTable réussie, l'état de la table est UPDATING. Une fois l'opération terminée, le tableau retourne à l'état ACTIVE. L'extrait de code PHP suivant modifie les paramètres de débit alloué d'une table. Puis, il attend jusqu'à ce que le tableau devienne ACTIVE à nouveau. $tableName = 'ExampleTable'; echo "Updating provisioned throughput settings on $tableName...\n"; $result = $dynamodb->updateTable([ 'TableName' => $tableName, 'ProvisionedThroughput' => [ 'ReadCapacityUnits' => 6, 'WriteCapacityUnits' => 7 ] ]); $dynamodb->waitUntil('TableExists', [ 'TableName' => $tableName, '@waiter' => [ 'delay' => 5, 'maxAttempts' => 20 ] ]); echo "New provisioned throughput settings:\n"; echo "Read capacity units: " . $result['TableDescription']['ProvisionedThroughput'] ['ReadCapacityUnits'] . "\n"; echo "Write capacity units: " . $result['TableDescription']['ProvisionedThroughput'] ['WriteCapacityUnits'] . "\n"; Suppression d'une table Vous pouvez supprimer une table si vous n'en avez plus besoin. Immédiatement après une demande DeleteTable réussie, l'état de la table est DELETING. Une fois l'opération terminée, la table n'existe plus. L'extrait de code PHP suivant supprime une table et attend que l'opération se termine. API Version 2012-08-10 201 Amazon DynamoDB Manuel du développeur Utilisation des tables : PHP $tableName = 'ExampleTable'; echo "Deleting the table...\n"; $result = $dynamodb->deleteTable([ 'TableName' => $tableName ]); $dynamodb->waitUntil('TableNotExists', [ 'TableName' => $tableName, '@waiter' => [ 'delay' => 5, 'maxAttempts' => 20 ] ]); echo "The table has been deleted.\n"; Liste des tables Vous pouvez utiliser l'opération ListTables pour retourner les noms de toutes vos tables de la région AWS actuelle. Vous pouvez spécifier des paramètres facultatifs. Par exemple, vous pouvez définir le paramètre Limit si vous souhaitez utiliser la pagination pour limiter le nombre de noms de tables par page. Vous pouvez aussi définir le paramètre ExclusiveStartTableName. Après l'extraction de la première page de résultats, DynamoDB retourne une valeur LastEvalutedTableName. Utilisez la valeur LastEvalutedTableName pour le paramètre ExclusiveStartTableName afin d'obtenir la page suivante de résultats. L'extrait de code PHP suivant répertorie toutes les tables que vous possédez dans la région AWS actuelle. Il utilise la valeur LastEvalutedTableName pour le paramètre ExclusiveStartTableName, avec une valeur Limit de 2 noms de table par page. $tables = []; unset($response); do { if (isset($response)) { $params = [ 'Limit' => 2, 'ExclusiveStartTableName' => $response['LastEvaluatedTableName'] ]; }else { $params = ['Limit' => 2]; } $response = $dynamodb->listTables($params); foreach ($response['TableNames'] as $key => $value) { echo "$value\n"; } $tables = array_merge($tables, $response['TableNames']); } while ($response['LastEvaluatedTableName']); // Print total number of tables API Version 2012-08-10 202 Amazon DynamoDB Manuel du développeur Utilisation des tables : PHP echo "Total number of tables: "; print_r(count($tables)); echo "\n"; Exemple : Créer, mettre à jour, supprimer et afficher les tables à l'aide de l'API de bas niveau du kit SDK AWS pour PHP L'exemple de code PHP suivant crée, met à jour et supprime une table (ExampleTable). Dans le cadre de la mise à jour de la table, les valeurs de débit alloué sont augmentées. L'exemple affiche aussi toutes vos tables de la région actuelle et obtient la description d'une table spécifique. A la fin, l'exemple supprime la table. Note Pour obtenir les instructions pas à pas afin d'exécuter l'exemple de code suivant, consultez Exemples de Code PHP (p. 177). <?php require 'vendor/autoload.php'; date_default_timezone_set('UTC'); use Aws\DynamoDb\Exception\DynamoDbException; $sdk = new Aws\Sdk([ 'region' => 'us-west-2', 'version' => 'latest' ]); $dynamodb = $sdk->createDynamoDb(); $tableName = 'ExampleTable'; echo "# Creating table $tableName...\n"; try { $response = $dynamodb->createTable([ 'TableName' => $tableName, 'AttributeDefinitions' => [ [ 'AttributeName' => 'Id', 'AttributeType' => 'N' ] ], 'KeySchema' => [ [ 'AttributeName' => 'Id', 'KeyType' => 'HASH' //Partition key ] ], 'ProvisionedThroughput' => [ 'ReadCapacityUnits' => 5, 'WriteCapacityUnits' => 6 ] ]); API Version 2012-08-10 203 Amazon DynamoDB Manuel du développeur Utilisation des tables : PHP $dynamodb->waitUntil('TableExists', [ 'TableName' => $tableName, '@waiter' => [ 'delay' => 5, 'maxAttempts' => 20 ] ]); print_r($response->getPath('TableDescription')); echo "table $tableName has been created.\n"; } catch (DynamoDbException $e) { echo $e->getMessage() . "\n"; exit ("Unable to create table $tableName\n"); } #################################################################### # Updating the table echo "# Updating the provisioned throughput of table $tableName.\n"; try { $response = $dynamodb->updateTable([ 'TableName' => $tableName, 'ProvisionedThroughput' => [ 'ReadCapacityUnits' => 6, 'WriteCapacityUnits' => 7 ] ]); $dynamodb->waitUntil('TableExists', [ 'TableName' => $tableName, '@waiter' => [ 'delay' => 5, 'maxAttempts' => 20 ] ]); echo "New provisioned throughput settings:\n"; $response = $dynamodb->describeTable(['TableName' => $tableName]); echo "Read capacity units: " . $response['Table']['ProvisionedThroughput']['ReadCapacityUnits']."\n"; echo "Write capacity units: " . $response['Table']['ProvisionedThroughput']['WriteCapacityUnits']."\n"; } catch (DynamoDbException $e) { echo $e->getMessage() . "\n"; exit ("Unable to update table $tableName\n"); } #################################################################### # Deleting the table try { echo "# Deleting table $tableName...\n"; $response = $dynamodb->deleteTable([ 'TableName' => $tableName]); API Version 2012-08-10 204 Amazon DynamoDB Manuel du développeur Utilisation des tables : PHP $dynamodb->waitUntil('TableNotExists', [ 'TableName' => $tableName, '@waiter' => [ 'delay' => 5, 'maxAttempts' => 20 ] ]); echo "The table has been deleted.\n"; } catch (DynamoDbException $e) { echo $e->getMessage() . "\n"; exit ("Unable to delete table $tableName\n"); } #################################################################### # List all table names for this AWS account, in this region echo "# Listing all of your tables in the current region...\n"; $tables = []; // Walk through table names, two at a time unset($response); do { if (isset($response)) { $params = [ 'Limit' => 2, 'ExclusiveStartTableName' => $response['LastEvaluatedTableName'] ]; }else { $params = ['Limit' => 2]; } $response = $dynamodb->listTables($params); foreach ($response['TableNames'] as $key => $value) { echo "$value\n"; } $tables = array_merge($tables, $response['TableNames']); } while ($response['LastEvaluatedTableName']); // Print total number of tables echo "Total number of tables: "; print_r(count($tables)); echo "\n"; ?> API Version 2012-08-10 205 Amazon DynamoDB Manuel du développeur Utilisation d'éléments Utilisation des éléments dans DynamoDB Rubriques • Présentation (p. 206) • Lecture d'un élément (p. 207) • Ecriture d'un élément (p. 208) • Opérations par lot (p. 208) • Compteurs atomiques (p. 209) • Ecritures conditionnelles (p. 209) • Lecture et écriture d'éléments à l'aide d'expressions (p. 211) • Utilisation d'éléments : Java (p. 231) • Utilisation des éléments : .NET (p. 253) • Utilisation des éléments : PHP (p. 277) Dans DynamoDB, un élément est un ensemble d'attributs. Chaque attribut a un nom et une valeur. Une valeur d'attribut peut être de type scalar, set ou document. Pour de plus amples informations, veuillez consulter Type de données (p. 12). DynamoDB fournit les opérations de lecture et d'écriture des éléments. Pour ces opérations, vous devez spécifier les éléments et les attributs que vous souhaitez utiliser. Lorsque vous écrivez un élément, vous pouvez spécifier une ou plusieurs conditions qui doivent avoir la valeur true. Par exemple, vous pouvez décider que l'écriture ne réussit que si un élément avec la même clé n'existe pas déjà. Cette section décrit comment utiliser les éléments dans Amazon DynamoDB. Y figurent notamment la lecture et l'écriture des éléments, les mises à jour conditionnelles et les compteurs atomiques. Cette section inclut également un exemple de code qui utilise les kits de développement logiciel AWS. Pour connaître les bonnes pratiques, consultez Instructions pour l'utilisation des éléments (p. 583). Présentation Un élément est composé d'un ou de plusieurs attributs. Chaque attribut est composé d'un nom, d'un type de données et d'une valeur. Lorsque vous lisez ou écrivez un élément, les seuls attributs nécessaires sont ceux qui constituent la clé primaire. Important Pour la clé primaire, vous devez fournir tous ses attributs. Par exemple, avec une clé primaire simple, il vous suffit de spécifier la clé de partition. Pour une clé primaire composite (clé de partition et clé de tri), vous devez spécifier à la fois la clé de partition et la clé de tri. Pour de plus amples informations, veuillez consulter Clé primaire (p. 5). A l'exception de la clé primaire, il n'existe pas de schéma prédéfini pour les éléments d'une table. Par exemple, pour stocker les informations sur les produits, vous pouvez créer une table ProductCatalog et stocker différents produits tels que livres et bicyclettes. Le tableau suivant présente deux éléments, un livre et une bicyclette, que vous pouvez stocker dans la table ProductCatalog. Notez que l'exemple utilise la syntaxe JSON pour afficher la valeur d'attribut. Id (clé primaire) 101 Autres attributs { Title = "Book 101 Title" ISBN = "111-1111111111" API Version 2012-08-10 206 Amazon DynamoDB Manuel du développeur Lecture d'un élément Id (clé primaire) Autres attributs Authors = "Author 1" Price = "-2" Dimensions = "8.5 x 11.0 x 0.5" PageCount = "500" InPublication = true ProductCategory = "Book" } 201 { Title = "18-Bicycle 201" Description = "201 description" BicycleType = "Road" Brand = "Brand-Company A" Price = "100" Color = [ "Red", "Black" ] ProductCategory = "Bike" } Un élément peut avoir un nombre quelconque d'attributs, même s'il existe une limite de taille d'élément 400 KB. La taille d'un élément est la somme des longueurs de ses noms d'attribut et de ses valeurs (longueurs binaire et UTF-8) ; elle constitue une aide dans la mesure où vous conservez les noms d'attributs courts. Lecture d'un élément Pour lire un élément à partir d'une table DynamoDB, utilisez l'opération GetItem. Vous devez fournir le nom de la table, ainsi que la clé primaire de l'élément que vous voulez. Vous devez spécifier la totalité de la clé primaire, pas juste une partie. Par exemple, si une table possède une clé primaire composite (clé de partition et clé de tri), vous devez fournir une valeur pour la clé de partition et une valeur pour la clé de tri. Voici les comportements par défaut pour GetItem : • GetItem effectue une lecture cohérente à terme. • GetItem retourne tous les attributs de l'élément. • GetItem ne retourne pas d'informations sur le nombre d'unités de capacité provisionnées qu'elle consomme. GetItem fournit des paramètres facultatifs afin que vous puissiez remplacer ces valeurs par défaut, si nécessaire. Cohérence en lecture DynamoDB gère plusieurs copies de chaque élément afin de garantir la durabilité. Pour chaque demande en écriture réussie, DynamoDB garantit que l'écriture est durable sur plusieurs serveurs. Cependant, la propagation d'une écriture sur toutes les copies prend du temps. Dans DynamoDB, les données sont cohérentes à terme. Cela signifie que si vous écrivez un élément, puis essayez immédiatement de le lire, il se peut que vous ne voyiez pas les résultats de l'écriture précédente. Par défaut, une opération GetItem effectue une lecture cohérente à terme. Le cas échéant, vous pouvez demander à la place une lecture à cohérence forte. Celle-ci consomme des unités supplémentaires de capacité en lecture, mais retourne la version la plus récente de l'élément. API Version 2012-08-10 207 Amazon DynamoDB Manuel du développeur Ecriture d'un élément Une demande GetItem cohérente à terme consomme seulement la moitié des unités de capacité en lecture d'une demande à cohérence forte. Par conséquent, il est préférable de concevoir les applications afin qu'elles utilisent des lectures cohérentes à terme chaque fois que possible. La cohérence à travers toutes les copies des données est généralement atteinte en une seconde. Ecriture d'un élément Pour créer, mettre à jour et supprimer des éléments dans une table DynamoDB, utilisez les opérations suivantes : • PutItem : crée un élément. Si un élément avec la même clé existe déjà dans la table, il est remplacé par le nouvel élément. Vous devez fournir le nom de la table et l'élément que vous souhaitez écrire. • UpdateItem : si l'élément n'existe pas déjà, l'opération crée un élément ; sinon, il modifie les attributs d'un élément existant. Vous devez spécifier le nom de la table et la clé de l'élément que vous voulez modifier. Pour chacun des attributs que vous souhaitez mettre à jour, vous devez fournir les nouvelles valeurs. • DeleteItem : supprime un élément. Vous devez spécifier le nom de la table et la clé de l'élément que vous voulez supprimer. Pour chacune de ces opérations, vous devez spécifier la totalité de la clé primaire, pas simplement une partie. Par exemple, si une table possède une clé primaire composite (clé de partition et clé de tri), vous devez fournir une valeur pour la clé de partition et une valeur pour la clé de tri. Si vous voulez éviter de remplacer ou supprimer accidentellement un élément existant, vous pouvez utiliser une expression conditionnelle avec l'une quelconque de ces opérations. Une expression conditionnelle vous permet de vérifier si une condition est vraie (par exemple, un élément qui existe déjà dans la table) avant de poursuivre l'opération. Pour écrire un élément uniquement s'il n'existe pas déjà, employez PutItem avec une expression conditionnelle qui utilise la fonction attribute_not_exists et le nom de la clé de partition de la table, car un élément qui existe possède une clé de partition. Pour de plus amples informations, veuillez consulter Opérations d'écriture conditionnelle (p. 230). Dans certains cas, vous pouvez vouloir que DynamoDB affiche certaines valeurs d'attribut avant de les modifier ou après. Par exemple, avec une opération UpdateItem, vous pouvez demander que les valeurs d'attribut soient retournées telles qu'elles apparaissaient avant la mise à jour. PutItem, UpdateItem et DeleteItem ont un paramètre ReturnValues, que vous pouvez utiliser pour retourner les valeurs d'attribut avant qu'elle ne soient modifiées ou après. Par défaut, aucune de ces opérations ne retourne d'informations sur le nombre d'unités de capacité provisionnées qu'elle consomme. Vous pouvez utiliser le paramètre ReturnConsumedCapacity pour obtenir ces informations. Opérations par lot Si votre application a besoin de lire plusieurs éléments, vous pouvez utiliser BatchGetItem. Une simple demande BatchGetItem peut extraire jusqu'à 16 MB de données, lesquelles peuvent contenir jusqu'à 100 éléments. En outre, une simple demande BatchGetItem peut extraire les éléments de plusieurs tables. L'opération BatchWriteItem vous permet d'insérer ou de supprimer plusieurs éléments. BatchWriteItem peut écrire jusqu'à 16 MB de données, soit jusqu'à 25 demandes d'insertion ou de suppression. La taille maximale d'un élément est 400 KB. En outre, une même demande BatchWriteItem peut insérer ou supprimer les éléments de plusieurs tables. (Notez que BatchWriteItem ne peut pas mettre à jour les éléments. Pour mettre à jour les éléments, utilisez à la place UpdateItem.) API Version 2012-08-10 208 Amazon DynamoDB Manuel du développeur Compteurs atomiques Un traitement par lots se compose d'une ou de plusieurs demandes. Pour chaque demande, DynamoDB appelle l'opération qui lui est appropriée. Par exemple, si une demande BatchGetItem contient cinq éléments, DynamoDB exécute implicitement cinq opérations GetItem en votre nom. De même, si une demande BatchWriteItem contient deux requêtes d'insertion et quatre requêtes de suppression, DynamoDB exécute implicitement deux demandes PutItem et quatre demandes DeleteItem. Si une demande d'un traitement par lots échoue (par exemple, parce que vous dépasserez les paramètres de débit alloué sur une table), il n'en résulte pas l'échec de la totalité du lot. A la place, l'opération de traitement par lots retourne les clés et les données à partir de la demande ayant échoué, de telle sorte que vous puissiez recommencer l'opération. En général, une opération de traitement par lots n'échoue pas, sauf si toutes les demandes du traitement par lots échouent. Compteurs atomiques DynamoDB prend en charge les compteurs atomiques, où vous utilisez l'opération UpdateItem pour incrémenter ou décrémenter la valeur d'un attribut existant sans interférer avec d'autres demandes d'écriture. (Toutes les demandes d'écriture sont appliquées dans l'ordre dans lequel elles ont été reçues.) Par exemple, une application web peut vouloir gérer un compteur par visiteur de leur propre site. Dans ce cas, l'application doit incrémenter ce compteur quelle que soit sa valeur actuelle. Les mises à jour des compteurs atomiques ne sont pas idempotentes. Cela signifie que le compteur augmente chaque fois que vous appelez UpdateItem. Si vous pensez qu'une demande précédente a échoué, votre application peut recommencer l'opération UpdateItem ; cependant, cela risque de mettre à jour le compteur deux fois. Cela peut être acceptable pour un compteur de site web, parce que vous pouvez accepter de sur-comptabiliser ou sous-comptabiliser légèrement les visiteurs. Cependant, dans une application bancaire, il serait plus sûr d'utiliser une mise à jour conditionnelle plutôt qu'un compteur atomique. Pour mettre à jour un compteur atomique, utilisez une opération UpdateItem avec un attribut de type Number dans le paramètre UpdateExpression et SET en tant qu'action de mise à jour à effectuer. Vous pouvez incrémenter le compteur à l'aide d'un nombre positif ou le décrémenter à l'aide d'un nombre négatif. Pour de plus amples informations, veuillez consulter Incrémentation et décrémentation d'attributs numériques (p. 227). Ecritures conditionnelles Dans un environnement multi-utilisateur, plusieurs clients peuvent accéder au même élément et tentez de modifier ses valeurs d'attribut en même temps. Toutefois, chaque client peut ne pas réaliser que d'autres clients ont pu déjà modifier l'élément. Cela apparaît dans l'illustration suivante où Client 1 et Client 2 ont récupéré une copie d'un élément (Id=1). Client 1 passe le prix de 10 $ à 8 $. Plus tard, Client 2 passe le même prix de l'élément à 12 $ et la modification précédente effectuée par Client 1 est perdue. API Version 2012-08-10 209 Amazon DynamoDB Manuel du développeur Ecritures conditionnelles Pour aider les clients à coordonner les écritures sur les données d'éléments, DynamoDB prend en charge les écritures conditionnelles pour les opérations PutItem, DeleteItem et UpdateItem. Avec une écriture conditionnelle, une opération réussit uniquement si les attributs de l'élément satisfont une ou plusieurs conditions prévues ; sinon, elle retourne une erreur. Par exemple, l'illustration suivante montre Client 1 et Client 2 récupérant une copie d'un élément (Id=1). Client 1 tente d'abord de mettre à jour le prix de l'élément à 8 $, dans l'hypothèse que le prix de l'élément existant sur le serveur soit 10 $. Cette opération aboutit, car l'attente est satisfaite. Client 2 tente ensuite de mettre à jour le prix à 12 $, dans l'hypothèse que le prix de l'élément existant sur le serveur soit 10 $. Cette attente ne peut pas être satisfaite, car le prix est maintenant $8 ; par conséquent, la demande de Client 2 échoue. Notez que les écritures conditionnelles sont idempotentes. Cela signifie que vous pouvez envoyer la même demande d'écriture conditionnelle plusieurs fois, mais que cela n'aura aucun effet supplémentaire sur l'élément après que DynamoDB a effectué la mise à jour spécifiée pour la première fois. Par exemple, supposons que vous émettiez une requête pour mettre à jour le prix d'un livre de 10 %, avec l'espoir que le prix soit actuellement de 20 $. Cependant, avant que vous n'obteniez une réponse, une erreur réseau se produit et vous ne savez pas si votre demande a réussi ou non. Comme une mise à jour conditionnelle est une opération idempotente, vous pouvez envoyer à nouveau la même demande. DynamoDB ne mettra le prix à jour que si le prix actuel est toujours 20 $. Pour demander une opération PutItem, DeleteItem ou UpdateItem conditionnelle, vous spécifiez les conditions dans le paramètre ConditionExpression. ConditionExpression est une chaîne contenant des noms d'attributs, des opérateurs conditionnels et des fonctions intégrées. L'expression entière doit avoir la valeur true ; sinon, l'opération échoue. API Version 2012-08-10 210 Amazon DynamoDB Manuel du développeur Lecture et écriture d'éléments à l'aide d'expressions Tip Pour de plus amples informations, veuillez consulter Opérations d'écriture conditionnelle (p. 230). Si vous spécifiez le paramètre ReturnConsumedCapacity, DynamoDB retourne le nombre d'unités de capacité en écriture qui ont été consommées au cours de l'écriture conditionnelle. (Notez que les opérations d'écriture ne consomment que les unités de capacité en écriture ; elles consomment jamais d'unités de capacité en lecture.) La définition de ReturnConsumedCapacity sur TOTAL retourne la capacité en écriture utilisée pour la table et tous ses index secondaires globaux ; INDEXES retourne uniquement la capacité en écriture utilisée par les index secondaires globaux ; NONE signifie que vous ne voulez pas que soient retournées les statistiques sur les capacités consommées. Si une ConditionExpression est analysée comme false pendant une écriture conditionnelle, DynamoDB continue à utiliser les unités de capacité en écriture de la table : • Si l'élément existe, le nombre d'unités de capacité d'écriture utilisées dépend de la taille de l'élément. (Par exemple, un échec d'écriture conditionnelle d'un élément 1 KB utiliserait une unité de capacité d'écriture ; si l'élément faisait deux fois cette taille, l'échec d'écriture conditionnelle utiliserait deux unités de capacité d'écriture.) • Si l'élément n'existe pas, DynamoDB utilisera une unité de capacité d'écriture. Une écriture conditionnelle ayant échoué retourne une ConditionalCheckFailedException au lieu de la réponse attendue de l'opération d'écriture. Pour cette raison, vous ne recevrez aucune information sur l'unité de capacité en écriture qui a été consommée. Cependant, vous pouvez consulter la métrique ConsumedWriteCapacityUnits de la table dans Amazon CloudWatch afin de déterminer la capacité d'écriture allouée qui a été consommée à partir de la table. Pour plus d'informations, consultez DynamoDB Metrics (p. 503) dans Supervision de Amazon DynamoDB (p. 501). Note Contrairement à un index secondaire global, un index secondaire local partage sa capacité de débit alloué avec sa table. L'activité en lecture et en écriture sur un index secondaire local consomme la capacité de débit alloué à partir de la table. Lecture et écriture d'éléments à l'aide d'expressions Dans DynamoDB, vous utilisez des expressions pour désigner les attributs que vous souhaitez lire à partir d'un élément. Vous utilisez également des expressions lors de l'écriture d'un élément, pour signaler toutes les conditions qui doivent être satisfaites (aussi appelées mise à jour conditionnelle) et pour indiquer comment les attributs doivent être mis à jour. Des exemples de mise à jour remplacent l'attribut par une nouvelle valeur, ou ajoutent de nouvelles données à une liste ou une carte. Cette section décrit les différents types d'expressions qui sont disponibles. Note Pour la compatibilité descendante, DynamoDB prend également en charge des paramètres conditionnels qui n'utilisent pas d'expressions. Pour de plus amples informations, veuillez consulter Paramètres conditionnels hérités (p. 686). Les nouvelles applications doivent utiliser des expressions plutôt que des paramètres hérités. Rubriques • Etude de cas : Un élément ProductCatalog (p. 212) • Accès à des attributs d'élément avec des expressions de projections (p. 213) API Version 2012-08-10 211 Amazon DynamoDB Manuel du développeur Lecture et écriture d'éléments à l'aide d'expressions • Utilisation d'espaces réservés pour valeurs et noms d'attributs (p. 215) • Réalisation d'écritures conditionnelles avec des expressions de condition (p. 217) • Modification d'éléments et d'attributs avec des expressions de mises à jour (p. 224) Etude de cas : Un élément ProductCatalog Dans cette section, nous examinerons un élément dans la table ProductCatalog. (Cette table apparaît dans Exemples de tables et de données (p. 596), ainsi que certains exemples d'éléments.) Voici une représentation de l'élément : { Id: 206, Title: "20-Bicycle 206", Description: "206 description", BicycleType: "Hybrid", Brand: "Brand-Company C", Price: 500, Color: ["Red", "Black"], ProductCategory: "Bike", InStock: true, QuantityOnHand: null, RelatedItems: [ 341, 472, 649 ], Pictures: { FrontView: "http://example.com/products/206_front.jpg", RearView: "http://example.com/products/206_rear.jpg", SideView: "http://example.com/products/206_left_side.jpg" }, ProductReviews: { FiveStar: [ "Excellent! Can't recommend it highly enough! Buy it!", "Do yourself a favor and buy this." ], OneStar: [ "Terrible product! Do not buy this." ] } } Remarques : • La valeur de clé de partition (Id) est 206. Il n'y a aucune clé de tri. • La plupart des attributs ont des types de données scalaires, telles que String, Number, Boolean et Null. • Un attribut (Color) est un ensemble String. • Les attributs suivants sont des types de données de documents : • Une liste de RelatedItems. Chaque élément est un Id pour un produit concerné. • Une carte de Pictures. Chaque élément est une brève description d'une image, accompagnée d'une URL pour le fichier image correspondant. • Une carte de ProductReviews. Chaque élément représente une évaluation et une liste de commentaires correspondant à cette évaluation. À l'origine, cette carte sera remplie avec des commentaires cinq étoiles et une étoile. API Version 2012-08-10 212 Amazon DynamoDB Manuel du développeur Lecture et écriture d'éléments à l'aide d'expressions Accès à des attributs d'élément avec des expressions de projections Pour lire des données depuis une table, vous utilisez des opérations comme GetItem, Query ou Scan. DynamoDB renvoie tous les attributs d'élément par défaut. Pour obtenir seulement quelques-uns et non pas tous les attributs, utilisez une expression de projections. Note Les exemples dans les sections suivantes sont basés sur l'élément ProductCatalog à partir de Etude de cas : Un élément ProductCatalog (p. 212). Rubriques • Expressions de projections (p. 213) • Chemins d'accès du document (p. 213) Expressions de projections Une expression de projections est une chaîne qui identifie les attributs que vous voulez. Pour récupérer un seul attribut, spécifiez son nom. Pour plusieurs attributs, les noms doivent être séparés par des virgules. Voici quelques exemples d'expressions de projections : • Un seul attribut de niveau supérieur. Title • Trois attributs de niveau supérieur. Notez que DynamoDB récupérera tous l'ensemble Color. Title, Price, Color • Quatre attributs de niveau supérieur. Notez que DynamoDB renverra l'ensemble des contenus de RelatedItems et de ProductReviews. Title, Description, RelatedItems, ProductReviews Vous pouvez utiliser n'importe quel nom d'attribut dans une expression de projections, à la condition que le premier caractère soit a-z ou A-Z et que le deuxième caractère (le cas échéant) soit az, A-Z ou 0-9. Si un nom d'attribut ne répond pas à cette exigence, vous devez définir un nom d'attribut d'expression comme un espace réservé. Pour de plus amples informations, veuillez consulter Expression de noms d'attributs (p. 215). Note La manière dont vous spécifiez une expression de projections dépend du langage de programmation que vous utilisez. Pour des exemples de code, consultez la section Guide de démarrage de Amazon DynamoDB pour votre langue. Chemins d'accès du document Outre les attributs de niveau supérieur, les expressions peuvent accéder à des éléments individuels dans n'importe quel attribut de type de document. Pour ce faire, vous devez fournir l'emplacement de l'élément ou le chemin d'accès au document, au sein de l'élément. Le chemin d'accès au document indique à DynamoDB où trouver l'attribut, même s'il est profondément imbriqué dans plusieurs listes et cartes. API Version 2012-08-10 213 Amazon DynamoDB Manuel du développeur Lecture et écriture d'éléments à l'aide d'expressions Pour un attribut de niveau supérieur, le chemin d'accès du document est simplement le nom d'attribut. Pour un attribut imbriqué, vous construisez le chemin d'accès au document à l'aide des opérateurs de déréférençage. Accès à des éléments de liste L'opérateur de déréférençage pour un élément de liste est [n], où n est le numéro d'élément. Des éléments de liste sont de base zéro, donc [0] représente le premier élément dans la liste, [1] représente le deuxième et ainsi de suite : • MyList[0] • AnotherList[12] • ThisList[5][11] L'élément ThisList[5] est lui-même une liste imbriquée. Par conséquent, ThisList[5][11] fait référence au douzième élément dans cette liste. L'index dans un déréférençage de liste doit être un entier non négatif. Par conséquent, les expressions suivantes ne sont pas valides : • MyList[-1] • MyList[0.4] Pour accéder aux éléments de la carte L'opérateur de déréférençage pour un élément de carte est . (un point). Utilisez un point comme séparateur entre des éléments d'une carte : • MyMap.nestedField • MyMap.nestedField.deeplyNestedField Exemples de chemin d'accès au document Voici quelques exemples d'expressions de projections utilisant des chemins d'accès au document. • Le troisième élément de la liste RelatedItems. (N'oubliez pas que les éléments de liste sont de base zéro). RelatedItems[2] • Prix de l'élément, couleur et image vue avant du produit. Price, Color, Pictures.FrontView • Tous les commentaires cinq étoiles. ProductReviews.FiveStar • Le premier des commentaires cinq étoiles. ProductReviews.FiveStar[0] Note La profondeur maximale pour un chemin d'accès au document est 32. Par conséquent, le nombre de déréférençages dans tout chemin d'accès ne peut pas dépasser cette limite. API Version 2012-08-10 214 Amazon DynamoDB Manuel du développeur Lecture et écriture d'éléments à l'aide d'expressions Vous pouvez utiliser n'importe quel nom d'attribut dans un chemin d'accès au document, à la condition que le premier caractère soit a-z ou A-Z et que le deuxième caractère (le cas échéant) soit az, A-Z ou 0-9. Si un nom d'attribut ne répond pas à cette exigence, vous devez définir un nom d'attribut d'expression comme un espace réservé. Pour de plus amples informations, veuillez consulter Expression de noms d'attributs (p. 215). Utilisation d'espaces réservés pour valeurs et noms d'attributs Cette section présente des espaces réservés ou des variables de substitution, que vous pouvez utiliser dans des expressions DynamoDB. Rubriques • Expression de noms d'attributs (p. 215) • Valeurs d'attributs d'expressions (p. 217) Expression de noms d'attributs Dans certains cas, vous pourrez avoir besoin d'écrire une expression contenant un nom d'attribut qui entre en conflit avec un mot réservé DynamoDB. (Pour obtenir la liste complète des mots réservés, consultez Mots réservés dans DynamoDB (p. 676).) Par exemple, l'expression de projections suivante serait non valide car SESSION est un mot réservé : • Classroom, Session, StartTime Pour contourner ce problème, vous pouvez définir un nom d'attribut d'expression. Un nom d'attribut d'expression est un espace réservé que vous utilisez dans l'expression, comme une alternative au nom d'attribut réel. Un nom d'attribut expression doit commencer par un # et être suivi d'un ou de plusieurs caractères alphanumériques. Dans l'expression précédente, vous pouvez remplacer Session par un nom d'attribut d'expression tel que #s. Le # (signe de la livre) est obligatoire et indique qu'il s'agit d'un espace réservé pour un nom d'attribut. L'expression révisée ressemblerait maintenant à ceci : • Classroom, #s, StartTime Tip Si un nom d'attribut commence par un certain nombre ou contient un espace, un caractère spécial ou un mot réservé, vous devez alors utiliser un nom d'attribut d'expression pour remplacer ce nom d'attribut dans l'expression. Dans une expression, un point («. ») est interprété comme un caractère de séparation dans un chemin d'accès de document. Cependant, DynamoDB vous permet également d'utiliser un caractère de point dans le cadre d'un nom d'attribut. Cela peut être ambiguë dans certains cas. Pour illustrer, prenez en compte l'élément suivant dans une table DynamoDB : { Id: 1234, My.Scalar.Message: "Hello", MyMap: { MyKey: "My key value", MyOtherKey: 10 } API Version 2012-08-10 215 Amazon DynamoDB Manuel du développeur Lecture et écriture d'éléments à l'aide d'expressions } Supposons que vous vouliez accéder à My.Scalar.Message à l'aide de l'expression de projections suivante : My.Scalar.Message DynamoDB renvoie un résultat vide, et non la chaîne Hello attendue. Cela est dû au fait que DynamoDB interprète un point dans une expression comme un séparateur de chemin d'accès au document. Dans ce cas, vous devrez définir un nom d'attribut d'expression (tel que #msm) en remplacement de My.Scalar.Message. Vous pouvez ensuite utiliser l'expression de projections suivante : #msm DynamoDB envoie ensuite le résultat souhaité : Hello Tip Un point dans une expression représente un séparateur du chemin d'accès au document. Si un nom d'attribut contient des caractères points, définissez un nom d'attribut d'expression lui correspondant. Vous pouvez ensuite utiliser ce nom dans une expression. Supposons maintenant que vous vouliez accéder à l'attribut embarqué MyMap.MyKey, à l'aide de l'expression de projections suivante : MyMap.MyKey Le résultat serait My key value, ce qui est prévu. Mais que faire si vous avez décidé d'utiliser un nom d'attribut d'expression à la place ? Par exemple, que se passerait-il si vous deviez définir #mmmk pour remplacer MyMap.MyKey ? DynamoDB renvoie un résultat vide, au lieu de la chaîne prévue. C'est parce que DynamoDB interprète un point dans une valeur d'attribut d'expression comme un caractère dans un nom d'attribut. Lorsque DynamoDB évalue le nom d'attribut d'expression #mmmk, il détermine que MyMap.MyKey fait référence à un attribut scalaire, ce qui n'est pas ce qui était prévu. La bonne approche serait de définir les deux noms d'attribut d'expression, un pour chaque élément dans le chemin d'accès au document : • #mm — MyMap • #mk — MyKey Vous pouvez ensuite utiliser l'expression de projections suivante : #mm.#mk DynamoDB envoie ensuite le résultat souhaité : My key value Note Un point dans un nom d'attribut d'expression représente un caractère valide dans un nom d'attribut. Pour accéder à un attribut imbriqué, définissez un nom d'attribut d'expression pour chaque élément dans le chemin d'accès au document. Vous pouvez ensuite utiliser ces noms dans une expression, chaque nom étant séparé par un point. API Version 2012-08-10 216 Amazon DynamoDB Manuel du développeur Lecture et écriture d'éléments à l'aide d'expressions Les noms d'attributs d'expression sont également utiles lorsque vous devez faire référence au même nom d'attribut à plusieurs reprises. Par exemple, imaginons l'expression suivante pour récupérer certains des commentaires d'un élément ProductCatalog : • ProductReviews.FiveStar, ProductReviews.ThreeStar, ProductReviews.OneStar Pour le rendre plus concis, vous pouvez remplacer ProductReviews par un nom d'attribut d'expression tel que #pr. L'expression révisée ressemblerait maintenant à ceci : • #pr.FiveStar, #pr.ThreeStar, #pr.OneStar Si vous avez défini un nom d'attribut d'expression, vous devez l'utiliser systématiquement tout au long de l'expression entière. En outre, vous ne pouvez pas ignorer le symbole #. Note La manière dont vous spécifiez des noms d'attribut d'expression dépend du langage de programmation que vous utilisez. Pour des exemples de code, consultez la section Guide de démarrage de Amazon DynamoDB pour votre langue. Valeurs d'attributs d'expressions Si vous avez besoin comparer un attribut avec une valeur, définissez une valeur d'attribut d'expressions comme un espace réservé. Les valeurs d'attributs d'expressions sont des produits de remplacement pour les valeurs réelles que vous voulez comparer ; valeurs que vous ne connaîtrez peut-être pas avant l'exécution. Une valeur d'attribut d'expression doit commencer par un : et être suivie d'un ou de plusieurs caractères alphanumériques. Par exemple, supposons que vous disposiez d'une application qui indique des produits d'un coût inférieur à une certaine valeur, avec la valeur réelle devant être saisie par l'utilisateur. Vous pouvez définir une valeur d'attribut d'expression, telle que :p, comme un espace réservé. Le : est obligatoire et indique qu'il s'agit d'un espace réservé pour une valeur d'attribut. Une telle expression se présente comme suit : • Price < :p Lors de l'exécution, l'application peut inviter l'utilisateur pour le prix souhaité. Ce prix sera utilisé dans l'expression et DynamoDB permettra de récupérer les résultats souhaités. Si vous avez défini une valeur d'attribut d'expression, vous devez l'utiliser systématiquement tout au long de l'ensemble de l'expression. En outre, vous ne pouvez pas ignorer le symbole :. Note La manière dont vous spécifiez des valeurs d'attribut d'expression dépend du langage de programmation que vous utilisez. Pour des exemples de code, consultez la section Guide de démarrage de Amazon DynamoDB pour votre langue. Réalisation d'écritures conditionnelles avec des expressions de condition Pour rechercher des éléments dans une table, vous utilisez des opérations telles que Query ou Scan. Ces opérations vous permettent de fournir vos propres conditions pour les critères de sélection et de filtrage. DynamoDB va évaluer et renvoyer uniquement les éléments qui correspondent à vos conditions. API Version 2012-08-10 217 Amazon DynamoDB Manuel du développeur Lecture et écriture d'éléments à l'aide d'expressions Pour écrire un élément, vous utilisez des opérations telles que PutItem, UpdateItem et DeleteItem. À l'aide d'expressions conditionnelles avec ces opérations, vous pouvez contrôler comment et dans quelles conditions un élément peut être modifié. Vous pouvez empêcher une mise à jour de se produire si l'élément ne respecte pas une condition préalable. Par exemple, vous pouvez empêcher PutItem de remplacer un élément existant. Note Les exemples dans ces sections sont basés sur l'élément ProductCatalog à partir de Etude de cas : Un élément ProductCatalog (p. 212). Rubriques • Expressions de condition (p. 218) • Référence des expressions de condition (p. 219) Expressions de condition Une expression de condition représente des restrictions à mettre en place lorsque vous lisez et écrivez des éléments dans une table. Une expression de condition est une chaîne à structure libre qui peut contenir des noms d'attributs, des chemins d'accès aux documents, des opérateurs logiques et des fonctions. Pour une liste complète des éléments autorisés dans une expression de condition, consultez la page Référence des expressions de condition (p. 219). Voici quelques exemples d'expressions de condition. Veuillez noter que certaines de ces expressions utilisent des espaces réservés pour les valeurs et les noms d'attributs. Pour de plus amples informations, veuillez consulter Utilisation d'espaces réservés pour valeurs et noms d'attributs (p. 215). • Afin d'éviter à PutItem de remplacer un élément existant, utilisez une expression conditionnelle qui spécifie que la clé de partition de l'élément n'existe pas. Dans la mesure où tous les éléments de la table doivent avoir une clé de partition, cela empêchera n'importe quel élément existant d'être remplacé. Par exemple, si la clé de partition est nommée « ville », vous pouvez utiliser : attribute_not_exists(town) Lorsque cette expression conditionnelle est utilisée avec le PutItem, DynamoDB recherche d'abord un élément dont la clé primaire correspond à celle de l'élément à écrire. Ce n'est que si la recherche ne renvoie aucun résultat qu'aucune clé de partition n'est présente dans le résultat. Sinon, la fonction attribute_not_exists ci-dessus échoue et l'écriture est empêchée. • Tous les éléments qui ont une image RearView. attribute_exists(Pictures.RearView) • Uniquement les éléments qui n'ont pas de commentaires une étoile. Le nom d'attribut d'expression #pr, remplace ProductReviews. attribute_not_exists (#pr.OneStar) Pour plus d'informations sur le caractère #, consultez Expression de noms d'attributs (p. 215). • Comparaisons scalaires simples. :p représente un nombre et :bt représente une chaîne. Price <= :p BicycleType = :bt • Deux conditions qui doivent toutes deux être true. #P et #PC sont des espaces réservés pour les noms d'attribut Price et ProductCategory. :lo et :hi représentent des valeurs de type Number, et :cat1 et :cat2 représentent des valeurs de type String. API Version 2012-08-10 218 Amazon DynamoDB Manuel du développeur Lecture et écriture d'éléments à l'aide d'expressions (#P between :lo and :hi) and (#PC in (:cat1, :cat2)) Vous pouvez utiliser n'importe quel nom d'attribut dans une expression de condition, à la condition que le premier caractère soit a-z ou A-Z et les caractères restants (le cas échéant) soient a-z, AZ ou 0-9. Si un nom d'attribut ne répond pas à cette exigence, vous devez définir un nom d'attribut d'expression comme un espace réservé. Pour de plus amples informations, veuillez consulter Expression de noms d'attributs (p. 215). Référence des expressions de condition Cette section traite des blocs de construction fondamentaux des expressions de condition dans DynamoDB. Note La syntaxe de ConditionExpression est identique à celle du paramètre FilterExpression. FilterExpression permet d''interroger et d'analyser les données ; pour plus d'informations, consultez Filtrage des résultats d'une opération Query ou Scan (p. 292). Rubriques • Syntaxe des expressions de condition (p. 219) • Comparaisons (p. 220) • Fonctions (p. 220) • Evaluations logiques (p. 224) • Parenthèses (p. 224) • Priorité des conditions (p. 224) Syntaxe des expressions de condition Dans le résumé de syntaxe suivant, un opérande peut avoir l'une des valeurs suivantes : • Nom d'attribut de niveau supérieur, tel que Id, Title, Description ou ProductCategory • Chemin d'accès du document qui fait référence à un attribut imbriqué condition-expression ::= operand comparator operand | operand BETWEEN operand AND operand | operand IN ( operand (',' operand (, ...) )) | function | condition AND condition | condition OR condition | NOT condition | ( condition ) comparator ::= = | <> | < | <= | > | >= API Version 2012-08-10 219 Amazon DynamoDB Manuel du développeur Lecture et écriture d'éléments à l'aide d'expressions function ::= attribute_exists (path) | attribute_not_exists (path) | attribute_type (path, type) | begins_with (path, substr) | contains (path, operand) | size (path) Comparaisons Utilisez ces comparateurs pour comparer un opérande par rapport à une plage de valeurs, ou une liste énumérée de valeurs : • a = b : true si a est égal à b • a <> b : true si a n'est pas égal à b • a < b : true si a est inférieur à b • a <= b : true si a est inférieur ou égal à b • a > b : true si a est supérieur à b • a >= b : true si a est supérieur ou égal à b Utilisez les mots clés BETWEEN et IN pour comparer un opérande par rapport à une plage de valeurs, ou une liste énumérée de valeurs : • a BETWEEN b AND c : true si a est supérieur ou égal à b, et inférieur ou égal à c. • a IN (b, c, d) : true si a est égal à l'une des valeurs de la liste (par exemple, b, c ou d). La liste peut contenir jusqu'à 100 valeurs séparées par des virgules. Fonctions Utilisez les fonctions suivantes pour déterminer si un attribut existe dans un élément, ou pour évaluer la valeur d'un attribut. Les noms de ces fonctions sont sensibles à la casse. Pour un attribut imbriqué, vous devez fournir le chemin d'accès complet ; pour plus d'informations, consultez Chemins d'accès du document (p. 213). Fonction Description attribute_exists (path) True si l'élément contienne l'attribut spécifié par path. Exemple : Vérifier si un élément de la table Products a une image de vue de côté. • attribute_exists (Pictures.SideView) attribute_not_exists (path) True si l'attribut spécifié par path n'existe pas dans l'élément. Exemple : Vérifier si un élément possède un attribut Manufacturer • attribute_not_exists (Manufacturer) attribute_type (path, type) True si l'attribut à l'emplacement spécifié est d'un type de données particulier. Le paramètre type doit avoir l'une des valeurs suivantes : API Version 2012-08-10 220 Amazon DynamoDB Manuel du développeur Lecture et écriture d'éléments à l'aide d'expressions Fonction Description • S — String • • • • • SS : String Set N : Number NS : Number Set B : Binary BS : Binary Set • BOOL : Boolean • NULL — Null • L — List • M : Map Vous devez utiliser une valeur d'attribut expression pour le paramètre type. Exemple : Vérifier si l'attribut QuantityOnHand est de type List (liste). Dans cet exemple, :v_sub est un espace réservé pour la chaîne L. • attribute_type (ProductReviews.FiveStar, :v_sub) Vous devez utiliser une valeur d'attribut expression pour le second paramètre. begins_with (path, substr) True si l'attribut spécifié par path commence par une sous-chaîne particulière. Exemple : Vérifier si les tout premiers caractères de l'URL de l'image vue avant sont http://. • begins_with (Pictures.FrontView, :v_sub) La valeur d'attribut expression :v_sub est un espace réservé pour http://. API Version 2012-08-10 221 Amazon DynamoDB Manuel du développeur Lecture et écriture d'éléments à l'aide d'expressions Fonction Description contains (path, operand) True si l'attribut spécifié par path est : • une chaîne qui contient une sous-chaîne particulière. • un ensemble qui contient un élément particulier au sein de l'ensemble. Dans les deux cas, operand doit être une chaîne. Le chemin d'accès et l'opérande doivent être distincts ; autrement dit, contains (a, a) retourne une erreur. Exemple : Vérifier si l'attribut Brand contient la sous-chaîne Company. • contains (Brand, :v_sub) La valeur d'attribut expression :v_sub est un espace réservé pour Company. Exemple : Vérifier si le produit est disponible en rouge. • contains (Color, :v_sub) La valeur d'attribut expression :v_sub est un espace réservé pour Red. API Version 2012-08-10 222 Amazon DynamoDB Manuel du développeur Lecture et écriture d'éléments à l'aide d'expressions Fonction Description size (path) Renvoie un nombre représentant la taille d'un attribut. Voici les types de données valides à utiliser avec size. Si l'attribut est de type String (chaîne), size retourne la longueur de la chaîne. Exemple : Vérifier si la chaîne Brand est inférieure ou égale à 20 caractères. La valeur d'attribut expression :v_sub est un espace réservé pour 20. • size (Brand) <= :v_sub Si l'attribut est de type Binary (binaire), sizerenvoie le nombre d'octets de la valeur d'attribut. Exemple : supposons que l'élément ProductCatalog ait un attribut binaire nommé VideoClip, qui contient une courte vidéo du produit en cours d'utilisation. L'expression suivante vérifie si VideoClip dépasse 64 000 octets. La valeur d'attribut expression :v_sub est un espace réservé pour 64000. • size(VideoClip) > :v_sub Si l'attribut est un type de données Set (ensemble), size retourne le nombre d'éléments dans l'ensemble. Exemple : Vérifier si le produit est disponible dans plusieurs couleurs. La valeur d'attribut expression :v_sub est un espace réservé pour 1. • size (Color) < :v_sub Si l'attribut est de type List ou Map, size retourne le nombre d'éléments enfants. Exemple : Vérifier si le nombre de révisions OneStar a dépassé un certain seuil. La valeur d'attribut expression :v_sub est un espace réservé pour 3. • size(ProductReviews.OneStar) > :v_sub API Version 2012-08-10 223 Amazon DynamoDB Manuel du développeur Lecture et écriture d'éléments à l'aide d'expressions Evaluations logiques Utilisez les mots clés AND, OR et NOT pour effectuer les évaluations logiques. Dans la liste suivante, a et b représentent les conditions à évaluer. • a AND b : true si a et b ont tous deux la valeur true. • a OR b : true si a ou b (ou les deux) ont la valeur true. • NOT a : true si a a la valeur false ; false si a a la valeur true. Parenthèses Utilisez les parenthèses pour modifier la priorité d'une évaluation logique. Par exemple, supposons que les conditions a et b sont true, et que cette condition c a la valeur false. L'expression suivante a la valeur true : • a OR b AND c Toutefois, si vous placez une condition entre parenthèses, elle est évaluée en premier. Par exemple, l'expression suivante a la valeur false : • (a OR b) AND c Note Vous pouvez imbriquer les parenthèses dans une expression. Les parenthèses les plus intérieures sont évaluées en premier. Priorité des conditions DynamoDB évalue les conditions de gauche à droite en utilisant les règles de priorité suivantes : • = <> < <= > >= • IN • BETWEEN • attribute_exists attribute_not_exists begins_with contains • Parenthèses • NOT • AND • OR Modification d'éléments et d'attributs avec des expressions de mises à jour Pour supprimer un élément à partir d'une table, utilisez l'opération DeleteItem. Vous devez fournir la clé de l'élément que vous souhaitez supprimer. Pour mettre à jour un élément existant dans une table, utilisez l'opération UpdateItem. Vous devez fournir la clé de l'élément que vous souhaitez mettre à jour. Vous devez également fournir une expression de mise à jour, ce qui indique les attributs que vous voulez modifier et les valeurs que vous souhaitez leur attribuer. Pour de plus amples informations, veuillez consulter Expressions de mise à jour (p. 225). API Version 2012-08-10 224 Amazon DynamoDB Manuel du développeur Lecture et écriture d'éléments à l'aide d'expressions Les opérations DeleteItem et UpdateItem prennent en charge des écritures conditionnelles, où vous fournissez une expression de condition pour indiquer les conditions devant être satisfaites pour que l'opération aboutisse. Pour de plus amples informations, veuillez consulter Opérations d'écriture conditionnelle (p. 230). Si DynamoDB modifie un élément avec succès, la confirmation se fait via un code d'état HTTP 200 (OK). Aucune donnée supplémentaire n'est renvoyée dans la réponse. Cependant, vous pouvez demander à ce que l'élément ou ses attributs soient renvoyés. Vous pouvez les demander à mesure qu'ils apparaissent avant ou après une mise à jour. Pour de plus amples informations, veuillez consulter Valeurs renvoyées (p. 231). Note Les exemples dans les sections suivantes sont basés sur l'élément ProductCatalog à partir de Etude de cas : Un élément ProductCatalog (p. 212). Rubriques • Expressions de mise à jour (p. 225) • Opérations d'écriture conditionnelle (p. 230) • Valeurs renvoyées (p. 231) Expressions de mise à jour Une expression de mise à jour spécifie les attributs que vous voulez modifier, ainsi que de nouvelles valeurs pour ces attributs. Une expression de mise à jour spécifie également comment modifier les attributs ; par exemple, en définissant une valeur scalaire ou en supprimant des éléments dans une liste ou sur une carte. C'est une chaîne à structure libre qui peut contenir des noms d'attributs, des chemins d'accès au document, des opérateurs et des fonctions. Elle contient également des mots clés qui indiquent comment modifier des attributs. Les opérations PutItem, UpdateItem et DeleteItem nécessitent une valeur de clé primaire et modifieront uniquement l'élément avec cette clé. Si vous souhaitez effectuer une mise à jour conditionnelle, vous devez fournir une expression de mise à jour et une expression de condition. L'expression de condition spécifie la ou les conditions devant être satisfaites afin que la mise à jour aboutisse. Voici un récapitulatif de syntaxe des expressions de mise à jour : update-expression ::= SET set-action , ... | REMOVE remove-action , ... | ADD add-action , ... | DELETE delete-action , ... Une expression de mise à jour se compose de sections. Chaque section commence par un mot-clé SET, REMOVE, ADD ou DELETE. Vous pouvez inclure une de ces sections dans une expression de mise à jour dans n'importe quel ordre. Toutefois, chaque mot-clé de section peut n'apparaître qu'une seule fois. Vous pouvez modifier plusieurs attributs simultanément. Voici quelques exemples d'expressions de mise à jour : • • • • SET list[0] = :val1 REMOVE #m.nestedField1, #m.nestedField2 ADD aNumber :val2, anotherNumber :val3 DELETE aSet :val4 L'exemple suivant montre une expression de mise à jour unique avec plusieurs sections : API Version 2012-08-10 225 Amazon DynamoDB Manuel du développeur Lecture et écriture d'éléments à l'aide d'expressions • SET list[0] = :val1 REMOVE #m.nestedField1, #m.nestedField2 ADD aNumber :val2, anotherNumber :val3 DELETE aSet :val4 Vous pouvez utiliser n'importe quel nom d'attribut dans une expression de mise à jour, à la condition que le premier caractère soit a-z ou A-Z et que le deuxième caractère (le cas échéant) soit az, A-Z ou 0-9. Si un nom d'attribut ne répond pas à cette exigence, vous devez définir un nom d'attribut d'expression comme un espace réservé. Pour de plus amples informations, veuillez consulter Expression de noms d'attributs (p. 215). Pour spécifier une valeur littérale dans une expression de mise à jour, vous utilisez des valeurs d'attributs d'expressions. Pour de plus amples informations, veuillez consulter Valeurs d'attributs d'expressions (p. 217). Rubriques • SET (p. 226) • REMOVE (p. 228) • ADD (p. 229) • DELETE (p. 230) SET Utilisez l'action SET dans une expression de mise à jour pour ajouter un ou plusieurs attributs et des valeurs à un élément. Si l'un de ces attribut existe déjà, il est remplacé par les nouvelles valeurs. Cependant, notez que vous pouvez également utiliser SET pour ajouter ou soustraire un attribut qui est de type Number. Pour affecter SET à plusieurs attributs, séparez-les par des virgules. Dans le récapitulatif de la syntaxe suivante : • L'élément chemin est le chemin d'accès au document pour l'élément. Pour de plus amples informations, veuillez consulter Chemins d'accès du document (p. 213). • Un élément opérande peut être un chemin d'accès au document pour un élément ou une fonction. Pour de plus amples informations, veuillez consulter Fonctions de mise à jour des attributs (p. 227). set-action ::= path = value value ::= operand | operand '+' operand | operand '-' operand operand ::= path | function Voici quelques exemples d'expressions de mise à jour à l'aide de l'action SET. • Les exemples suivants mettent à jour les attributs Brand et Price. La valeur d'attribut d'expression :b est une chaîne et :p est un nombre. SET Brand = :b, Price = :p • L'exemple suivant met à jour un attribut dans la liste RelatedItems. La valeur d'attribut d'expression :ri est un nombre. API Version 2012-08-10 226 Amazon DynamoDB Manuel du développeur Lecture et écriture d'éléments à l'aide d'expressions SET RelatedItems[0] = :ri • L'exemple suivant met à jour des attributs de carte imbriqués. Le nom d'attribut d'expression #pr est ProductReviews ; les valeurs d'attributs :r1 et :r2 sont des chaînes. SET #pr.FiveStar[0] = :r1, #pr.FiveStar[1] = :r2 Incrémentation et décrémentation d'attributs numériques Vous pouvez ajouter ou soustraire depuis un attribut numérique existant. Pour ce faire, utilisez les opérateurs + (plus) et - (moins). L'exemple suivant diminue la valeur Price d'un élément. La valeur d'attribut d'expression :p est un nombre. • SET Price = Price - :p Afin d'accroître Price, utilisez l'opérateur + à la place. Utilisation de SET avec des éléments de listes Lorsque vous utilisez SET pour mettre à jour un élément de la liste, le contenu de cet élément est remplacé par les nouvelles données que vous spécifiez. Si l'élément n'existe pas déjà, SET ajoute le nouvel élément à la fin de la grappe. Si vous ajoutez plusieurs éléments dans une seule opération SET, les éléments sont triés dans l'ordre par numéro d'élément. Par exemple, consultez la liste suivante : MyNumbers: { ["Zero","One","Two","Three","Four"] } La liste contient des éléments [0], [1], [2], [3], [4]. Utilisons à présent l'action SET pour ajouter deux nouveaux éléments : set MyNumbers[8]="Eight", MyNumbers[10] = "Ten" La liste contient maintenant des éléments [0], [1], [2], [3], [4], [5], [6], avec les données suivantes à chaque élément : MyNumbers: { ["Zero","One","Two","Three","Four","Eight","Ten"] } Note Les nouveaux éléments sont ajoutés à la fin de la liste et se verront attribuer les numéros d'élément disponibles suivants. Fonctions de mise à jour des attributs L'action SET prend en charge les fonctions suivantes : • if_not_exists (path, operand) – Si l'élément ne contient pas un attribut au chemin spécifié, alors if_not_exists évalue sur opérande ; sinon, il évalue sur chemin. Vous pouvez utiliser cette fonction pour éviter de remplacer un attribut déjà présent dans l'élément. • list_append (operand, operand)– Cette fonction évalue en fonction d'une liste à laquelle un nouvel élément a été ajouté. Le nouvel élément doit être contenu dans une liste, par exemple, pour ajouter 2 à une liste, l'opérande serait [2]. Vous pouvez ajouter le nouvel élément au début ou à la fin de la liste en inversant l'ordre des opérandes. API Version 2012-08-10 227 Amazon DynamoDB Manuel du développeur Lecture et écriture d'éléments à l'aide d'expressions Important Les noms de ces fonctions sont sensibles à la casse. Voici quelques exemples d'utilisation de l'action SET avec ces fonctions. • Si l'attribut existe déjà, l'exemple suivant ne fait rien. Sinon, il définit l'attribut sur une valeur par défaut. SET Price = if_not_exists(Price, 100) • L'exemple suivant ajoute un nouvel élément à la lise de commentaires FiveStar. Le nom d'attribut d'expression #pr est ProductReviews ; la valeur d'attribut :r est une liste à un seul élément. Si la liste contenait auparavant deux éléments, [0] et [1], alors le nouvel élément sera [2]. SET #pr.FiveStar = list_append(#pr.FiveStar, :r) • L'exemple suivant ajoute un autre élément à la liste de commentaires FiveStar, mais cette foisci, l'élément sera ajouté au début de la liste à [0]. Tous les autres éléments dans la liste seront déplacés d'une position. SET #pr.FiveStar = list_append(:r, #pr.FiveStar) REMOVE Utilisez l'action REMOVE dans une expression de mise à jour pour supprimer un ou plusieurs attributs d'un élément. Afin d'effectuer plusieurs opérations REMOVE, séparez-les par des virgules. Ce qui suit est un résumé de la syntaxe pour REMOVE dans une expression de mise à jour. Le seul opérande est le chemin d'accès au document pour l'attribut que vous souhaitez supprimer : remove-action ::= path Voici un exemple d'une expression de mise à jour à l'aide de l'action REMOVE. Plusieurs attributs sont supprimés de l'élément : • REMOVE Title, RelatedItems[2], Pictures.RearView Utilisation de REMOVE avec des éléments de liste Lorsque vous supprimez un élément de liste existant, les éléments restants sont déplacés. Par exemple, consultez la liste suivante : • MyNumbers: { ["Zero","One","Two","Three","Four"] } La liste contient des éléments [0], [1], [2], [3] et [4]. Utilisons à présent l'action REMOVE pour supprimer deux des éléments : • REMOVE MyNumbers[1], MyNumbers[3] Les autres éléments sont déplacés vers la droite, entraînant une liste avec des éléments [0], [1] et [2], avec les données suivantes à chaque élément : • MyNumbers: { ["Zero","Two","Four"] } API Version 2012-08-10 228 Amazon DynamoDB Manuel du développeur Lecture et écriture d'éléments à l'aide d'expressions Note Si vous utilisez REMOVE pour supprimer un élément inexistant après le dernier élément de la liste, rien ne se passe : il n'y a pas de données à supprimer. Par exemple, l'expression suivante n'a aucun effet sur la liste MyNumbers : • REMOVE MyNumbers[11] ADD Important L'action ADD prend uniquement en charge Number et définit des types de données. En général, nous recommandons d'utiliser SET plutôt que ADD. Utilisez l'action ADD dans une expression de mise à jour pour réaliser l'une des opérations suivantes : • Si l'attribut n'existe pas déjà, ajoutez le nouvel attribut et sa ou ses valeurs à l'élément. • Si l'attribut existe déjà, alors le comportement de ADD dépend du type de données de l'attribut : • Si l'attribut est un nombre et que la valeur que vous ajoutez est également un nombre, alors la valeur est ajoutée mathématiquement à l'attribut existant. (Si la valeur est un nombre négatif, alors elle est soustraite de l'attribut existant.) • Si l'attribut est un ensemble, et que la valeur que vous ajoutez est également un ensemble, alors la valeur est ajoutée à l'ensemble existant. Afin d'effectuer plusieurs opérations ADD, séparez-les par des virgules. Dans le récapitulatif de la syntaxe suivante : • L'élément path est le chemin d'accès au document pour un attribut. L'attribut doit être un nombre ou un type de données défini. • L'élément value est un nombre que vous voulez ajouter à l'attribut (pour les types de données Number), ou un ensemble à ajouter à l'attribut (pour des types définis). add-action ::= path value Voici quelques exemples d'expressions de mise à jour à l'aide de l'action add. • L'exemple suivant augmente d'un certain nombre. La valeur d'attribut d'expression :n est un nombre, et cette valeur sera ajoutée à Price. ADD Price :n • L'exemple suivant ajoute une ou plusieurs valeurs à l'ensemble Color. La valeur d'attribut d'expression :c est un ensemble String. ADD Color :c API Version 2012-08-10 229 Amazon DynamoDB Manuel du développeur Lecture et écriture d'éléments à l'aide d'expressions DELETE Important L'action DELETE prend uniquement en charge des types de données définis. Utilisez l'action DELETE dans une expression de mise à jour pour supprimer un élément d'un jeu. Afin d'effectuer plusieurs opérations DELETE, séparez-les par des virgules. Dans le récapitulatif de la syntaxe suivante : • L'élément path est le chemin d'accès au document pour un attribut. L'attribut doit être un type de données défini. • L'élément value est le ou les éléments dans le jeu que vous souhaitez supprimer. delete-action ::= path value L'exemple suivant supprime un élément du jeu Color à l'aide de l'action DELETE. La valeur d'attribut d'expression :c est un ensemble String. DELETE Color :c Opérations d'écriture conditionnelle Pour effectuer une suppression conditionnelle, utilisez une opération DeleteItem avec une expression de condition. L'expression de condition doit avoir la valeur true afin que l'opération aboutisse. Dans le cas contraire, l'opération échoue. Supposons que vous souhaitiez supprimer un élément, mais uniquement si aucun élément n'est associé. Vous pouvez pour cela utiliser l'expression suivante : • Expression de condition : attribute_not_exists(RelatedItems) Pour effectuer une mise à jour conditionnelle, utilisez une opération UpdateItem avec une expression de mise à jour et une expression de condition. L'expression de condition doit avoir la valeur true afin que l'opération aboutisse. Dans le cas contraire, l'opération échoue. Supposons que vous vouliez augmenter le prix d'un élément d'un certain montant, défini comme :amt, mais uniquement si le résultat ne dépasse pas un prix maximum. Vous pouvez le faire en calculant le prix actuel le plus élevé qui autoriserait l'augmentation, en soustrayant l'augmentation :amt du maximum. Définissez le résultat en tant que :limit, puis utilisez l'expression conditionnelle suivante : • Expression de condition : Price <= :limit) • Expression de mise à jour : SET Price = Price + :amt Supposons à présent que vous vouliez définir une image vue avant d'un élément, mais uniquement si cet élément n'a pas déjà une telle image (vous voulez éviter de remplacer tout élément existant). Vous pouvez pour cela utiliser les expressions suivantes : • Expression de mise à jour : SET Pictures.FrontView = :myURL (Supposons que :myURL soit l'emplacement d'une image de l'élément, comme http://example.com/ picture.jpg.) API Version 2012-08-10 230 Amazon DynamoDB Manuel du développeur Utilisation d'éléments : Java • Expression de condition : attribute_not_exists(Pictures.FrontView) Valeurs renvoyées Lorsque vous effectuez une opération DeleteItem ou UpdateItem, DynamoDB peut éventuellement renvoyer tout ou partie des éléments de la réponse. Pour ce faire, vous définissez le paramètre ReturnValues. La valeur par défaut pour ReturnValues est NONE, donc aucune donnée ne sera renvoyée. Vous pouvez modifier ce comportement comme décrit ci-dessous. Suppression d'un élément Dans une opération DeleteItem, vous pouvez définir ReturnValues sur ALL_OLD. Cela conduit DynamoDB à renvoyer l'élément entier, tel qu'il s'affichait avant l'opération de suppression. Mise à jour d'un élément Dans une opération UpdateItem, vous pouvez définir ReturnValues sur l'un des éléments suivants : • ALL_OLD – L'élément complet est renvoyé, comme il s'affichait avant la mise à jour. • ALL_NEW – L'élément entier est renvoyé, tel qu'il s'affiche après la mise à jour. • UPDATED_OLD – Seules les valeurs que vous avez mises à jour sont renvoyées, telles qu'elles s'affichent avant la mise à jour. • UPDATED_NEW – Seules les valeurs que vous avez mises à jour sont retournées, telles qu'elles s'affichent après la mise à jour. Utilisation d'éléments : Java Rubriques • Positionnement d'un élément (p. 231) • Obtention d'un élément (p. 234) • Ecriture par lots : insertion et suppression de plusieurs éléments (p. 237) • Batch Get : obtention de plusieurs éléments (p. 238) • Mise à jour d'un élément (p. 239) • Suppression d'un élément (p. 241) • Exemple : opérations CRUD à l'aide de l'API Document AWS SDK for Java (p. 241) • Exemple : opérations par lots à l'aide de l'API Document AWS SDK for Java (p. 246) • Exemple : gestion d'attributs de type binaire à l'aide de l'API Document AWS SDK for Java (p. 250) Vous pouvez utiliser l'API Document AWS SDK for Java pour effectuer des opérations CRUD (création, lecture, mise à jour et suppression) classiques sur des éléments dans une table. Note Le SDK pour Java fournit également un modèle de persistance d'objet, ce qui vous permet de mapper vos classes côté client sur des tables DynamoDB. Cette approche peut réduire la quantité de code que vous avez à écrire. Pour de plus amples informations, veuillez consulter Java : DynamoDBMapper (p. 79). Positionnement d'un élément La méthode putItem stocke un élément dans une table. Si l'élément existe, il remplace la totalité de l'élément. Au lieu de remplacer l'élément entier, si vous souhaitez mettre à jour uniquement des API Version 2012-08-10 231 Amazon DynamoDB Manuel du développeur Utilisation d'éléments : Java attributs spécifiques, vous pouvez utiliser la méthode updateItem. Pour de plus amples informations, veuillez consulter Mise à jour d'un élément (p. 239). Procédez comme suit : 1. Créez une instance de la classe DynamoDB. 2. Créez une instance de la classe Table pour représenter la table que vous souhaitez utiliser. 3. Création d'une instance de la classe Item pour représenter le nouvel élément. Vous devez spécifier la clé primaire du nouvel élément et de ses attributs. 4. Appelez la méthode putItemde l'objet Table, à l'aide de l'Item que vous avez créé à l'étape précédente. L'extrait de code Java suivant illustre les tâches précédentes. L'extrait écrit un nouvel élément bicyclette dans la table ProductCatalog. (Il s'agit du même élément qui est décrit dans Etude de cas : Un élément ProductCatalog (p. 212).) DynamoDB dynamoDB = new DynamoDB(new AmazonDynamoDBClient( new ProfileCredentialsProvider())); Table table = dynamoDB.getTable("ProductCatalog"); // Build a list of related items List<Number> relatedItems = new ArrayList<Number>(); relatedItems.add(341); relatedItems.add(472); relatedItems.add(649); //Build a map of product pictures Map<String, String> pictures = new HashMap<String, String>(); pictures.put("FrontView", "http://example.com/products/206_front.jpg"); pictures.put("RearView", "http://example.com/products/206_rear.jpg"); pictures.put("SideView", "http://example.com/products/206_left_side.jpg"); //Build a map of product reviews Map<String, List<String>> reviews = new HashMap<String, List<String>>(); List<String> fiveStarReviews = new ArrayList<String>(); fiveStarReviews.add("Excellent! Can't recommend it highly enough! fiveStarReviews.add("Do yourself a favor and buy this"); reviews.put("FiveStar", fiveStarReviews); Buy it!"); List<String> oneStarReviews = new ArrayList<String>(); oneStarReviews.add("Terrible product! Do not buy this."); reviews.put("OneStar", oneStarReviews); // Build the item Item item = new Item() .withPrimaryKey("Id", 206) .withString("Title", "20-Bicycle 206") .withString("Description", "206 description") .withString("BicycleType", "Hybrid") .withString("Brand", "Brand-Company C") .withNumber("Price", 500) .withStringSet("Color", new HashSet<String>(Arrays.asList("Red", "Black"))) .withString("ProductCategory", "Bike") API Version 2012-08-10 232 Amazon DynamoDB Manuel du développeur Utilisation d'éléments : Java .withBoolean("InStock", true) .withNull("QuantityOnHand") .withList("RelatedItems", relatedItems) .withMap("Pictures", pictures) .withMap("Reviews", reviews); // Write the item to the table PutItemOutcome outcome = table.putItem(item); Dans l'exemple précédent, l'élément a des attributs qui sont scalaires (String, Number, Boolean, Null), des jeux (String Set) et des types de documents (List, Map). Spécification de paramètres facultatifs En même temps que les paramètres requis, vous pouvez également spécifier les paramètres facultatifs de la méthode putItem. Par exemple, l'extrait de code Java suivant utilise un paramètre facultatif pour spécifier une condition pour le chargement de l'élément. Si la condition que vous spécifiez n'est pas remplie, alors SDK AWS Java lève une ConditionalCheckFailedException. L'extrait de code spécifie les paramètres facultatifs suivants dans la méthode putItem : • Une ConditionExpression qui définit les conditions de la requête. L'extrait définit la condition selon laquelle l'élément existant ayant la même clé primaire est remplacé uniquement s'il a un attribut ISBN qui correspond à une valeur spécifique. • Une carte pour ExpressionAttributeValues qui sera utilisée dans la condition. Dans ce cas, une seule substitution est nécessaire : l'espace réservé :val dans l'expression de condition est remplacé lors de l'exécution par la valeur ISBN réelle à vérifier. L'exemple suivant ajoute un nouvel élément livre à l'aide de ces paramètres facultatifs. Item item = new Item() .withPrimaryKey("Id", 104) .withString("Title", "Book 104 Title") .withString("ISBN", "444-4444444444") .withNumber("Price", 20) .withStringSet("Authors", new HashSet<String>(Arrays.asList("Author1", "Author2"))); Map<String, Object> expressionAttributeValues = new HashMap<String, Object>(); expressionAttributeValues.put(":val", "444-4444444444"); PutItemOutcome outcome = table.putItem( item, "ISBN = :val", // ConditionExpression parameter null, // ExpressionAttributeNames parameter - we're not using it for this example expressionAttributeValues); PutItem et Documents JSON Vous pouvez stocker un document JSON comme un attribut dans une table DynamoDB. Pour ce faire, utilisez la méthode withJSON d'élément. Cette méthode analyse le document JSON et mappe chaque élément avec un type de données DynamoDB natif. Supposons que vous vouliez stocker le document JSON suivant, contenant des fournisseurs qui peuvent exécuter des commandes pour un produit spécifique : API Version 2012-08-10 233 Amazon DynamoDB Manuel du développeur Utilisation d'éléments : Java { "V01": { "Name": "Acme Books", "Offices": [ "Seattle" ] }, "V02": { "Name": "New Publishers, Inc.", "Offices": ["London", "New York" ] }, "V03": { "Name": "Better Buy Books", "Offices": [ "Tokyo", "Los Angeles", "Sydney" ] } } Vous pouvez utiliser la méthode withJSON pour stocker cela dans la table ProductCatalog, dans un attribut Map nommé VendorInfo. L'extrait de code Java suivant montre comment procéder. // Convert the document into a String. Must escape all double-quotes. String vendorDocument = "{" + " \"V01\": {" + " \"Name\": \"Acme Books\"," + " \"Offices\": [ \"Seattle\" ]" + " }," + " \"V02\": {" + " \"Name\": \"New Publishers, Inc.\"," + " \"Offices\": [ \"London\", \"New York\"" + "]" + "}," + " \"V03\": {" + " \"Name\": \"Better Buy Books\"," + "\"Offices\": [ \"Tokyo\", \"Los Angeles\", \"Sydney\"" + " ]" + " }" + " }"; Item item = new Item() .withPrimaryKey("Id", 210) .withString("Title", "Book 210 Title") .withString("ISBN", "210-2102102102") .withNumber("Price", 30) .withJSON("VendorInfo", vendorDocument); PutItemOutcome outcome = table.putItem(item); Obtention d'un élément Pour récupérer un élément unique, utilisez la méthode getItem d'un objet Table. Procédez comme suit : 1. Créez une instance de la classe DynamoDB. 2. Créez une instance de la classe Table pour représenter la table que vous souhaitez utiliser. 3. Appelez la méthode getItem de l'instance Table. Vous devez spécifier la clé primaire de l'élément que vous souhaitez récupérer. API Version 2012-08-10 234 Amazon DynamoDB Manuel du développeur Utilisation d'éléments : Java L'extrait de code Java suivant illustre les étapes précédentes. L'extrait de code obtient l'élément qui possède la clé de partition spécifiée. DynamoDB dynamoDB = new DynamoDB(new AmazonDynamoDBClient( new ProfileCredentialsProvider())); Table table = dynamoDB.getTable("ProductCatalog"); Item item = table.getItem("Id", 101); Spécification de paramètres facultatifs En même temps que les paramètres requis, vous pouvez également spécifier les paramètres facultatifs pour la méthode getItem. Par exemple, l'extrait de code Java suivant utilise une méthode facultative pour récupérer uniquement une liste précise d'attributs et spécifier des lectures fortement cohérentes. (Pour en savoir plus sur la cohérence en lecture, consultez Cohérence en lecture (p. 16).) Vous pouvez utiliser une ProjectionExpression pour récupérer uniquement certains attributs ou éléments, plutôt qu'un élément entier. Une ProjectionExpression peut spécifier des attributs de niveau supérieur ou imbriqués, à l'aide de chemins d'accès au document. Pour plus d'informations, consultez Expressions de projections (p. 213) et Chemins d'accès du document (p. 213). Les paramètres de la méthode getItem ne vous permettent pas de spécifier la cohérence des lectures. Cependant, vous pouvez créer un GetItemSpec, qui fournit un accès complet à toutes les entrées vers l'opération GetItem de bas niveau. L'exemple de code ci-dessous crée une GetItemSpec et utilise cette spécification comme entrée de la méthode getItem. GetItemSpec spec = new GetItemSpec() .withPrimaryKey("Id", 206) .withProjectionExpression("Id, Title, RelatedItems[0], Reviews.FiveStar") .withConsistentRead(true); Item item = table.getItem(spec); System.out.println(item.toJSONPretty()); Tip Pour imprimer un Item dans un format contrôlable de visu, utilisez la méthode toJSONPretty. Le résultat de l'exemple ci-dessus ressemble à ceci : { "RelatedItems" : [ 341 ], "Reviews" : { "FiveStar" : [ "Excellent! Can't recommend it highly enough! it!", "Do yourself a favor and buy this" ] }, "Id" : 206, "Title" : "20-Bicycle 206" Buy } GetItem et Documents JSON Dans la section PutItem et Documents JSON (p. 233), nous avons stocké un document JSON dans un attribut Map nommé VendorInfo. Vous pouvez utiliser la méthode getItem pour récupérer API Version 2012-08-10 235 Amazon DynamoDB Manuel du développeur Utilisation d'éléments : Java l'ensemble du document au format JSON ou utiliser la notation de chemin d'accès du document pour récupérer uniquement certains des éléments dans le document. L'extrait de code Java suivant illustre ces techniques. GetItemSpec spec = new GetItemSpec() .withPrimaryKey("Id", 210); System.out.println("All vendor info:"); spec.withProjectionExpression("VendorInfo"); System.out.println(table.getItem(spec).toJSON()); System.out.println("A single vendor:"); spec.withProjectionExpression("VendorInfo.V03"); System.out.println(table.getItem(spec).toJSON()); System.out.println("First office location for this vendor:"); spec.withProjectionExpression("VendorInfo.V03.Offices[0]"); System.out.println(table.getItem(spec).toJSON()); Le résultat de l'exemple ci-dessus ressemble à ceci : All vendor info: {"VendorInfo":{"V03":{"Name":"Better Buy Books","Offices":["Tokyo","Los Angeles","Sydney"]},"V02":{"Name":"New Publishers, Inc.","Offices": ["London","New York"]},"V01":{"Name":"Acme Books","Offices":["Seattle"]}}} A single vendor: {"VendorInfo":{"V03":{"Name":"Better Buy Books","Offices":["Tokyo","Los Angeles","Sydney"]}}} First office location for a single vendor: {"VendorInfo":{"V03":{"Offices":["Tokyo"]}}} Tip Vous pouvez utiliser la méthode toJSON pour convertir n'importe quel élément (ou ses attributs) en une chaîne au format JSON. L'extrait de code suivant récupère plusieurs attributs de niveau supérieur et imbriqués et affiche les résultats au format JSON : GetItemSpec spec = new GetItemSpec() .withPrimaryKey("Id", 210) .withProjectionExpression("VendorInfo.V01, Title, Price"); Item item = table.getItem(spec); System.out.println(item.toJSON()); Le résultat se présente comme suit : {"VendorInfo":{"V01":{"Name":"Acme Books","Offices": ["Seattle"]}},"Price":30,"Title":"Book 210 Title"} API Version 2012-08-10 236 Amazon DynamoDB Manuel du développeur Utilisation d'éléments : Java Ecriture par lots : insertion et suppression de plusieurs éléments L'écriture par lots fait référence à l'insertion et la suppression de plusieurs éléments dans un lot. La méthode batchWriteItem vous permet d'insérer et de supprimer plusieurs éléments d'une ou de plusieurs tables en un seul appel. Voici les étapes permettant d'insérer ou de supprimer plusieurs éléments à l'aide de l'API de document AWS SDK for Java. 1. Créez une instance de la classe DynamoDB. 2. Créez une instance de la classe TableWriteItems qui décrit toutes les opérations d'insertion et de suppression pour une table. Si vous souhaitez écrire à plusieurs tables dans une opération unique d'écriture par lots, vous devez créer une instance TableWriteItems par table. 3. Appelez la méthode batchWriteItem en fournissant le ou les objets TableWriteItems que vous avez créés à l'étape précédente. 4. Traitez la réponse. Vous devez vérifier si des éléments de requêtes non traités ont été renvoyés dans la réponse. Cela peut se produire si vous atteignez la limite de débit allouée ou une autre erreur temporaire. En outre, DynamoDB limite la taille de la requête et le nombre d'opérations que vous pouvez spécifier dans une requête. Si vous dépassez ces limites, DynamoDB rejette la requête. Pour de plus amples informations, veuillez consulter Limites dans DynamoDB (p. 564). L'extrait de code Java suivant illustre les étapes précédentes. L'exemple effectue une opération batchWriteItem sur deux tables : Forum et Thread. Les objets TableWriteItems correspondants permettent de définir les actions suivantes : • Insérer un élément dans la table Forum. • Insérer et supprimer un élément de la table Thread Le code appelle ensuite batchWriteItem pour effectuer l'opération. DynamoDB dynamoDB = new DynamoDB(new AmazonDynamoDBClient( new ProfileCredentialsProvider())); TableWriteItems forumTableWriteItems = new TableWriteItems("Forum") .withItemsToPut( new Item() .withPrimaryKey("Name", "Amazon RDS") .withNumber("Threads", 0)); TableWriteItems threadTableWriteItems = new TableWriteItems(Thread) .withItemsToPut( new Item() .withPrimaryKey("ForumName","Amazon RDS","Subject","Amazon RDS Thread 1") .withHashAndRangeKeysToDelete("ForumName","Some partition key value", "Amazon S3", "Some sort key value"); BatchWriteItemOutcome outcome = dynamoDB.batchWriteItem(forumTableWriteItems, threadTableWriteItems); // Code for checking unprocessed items is omitted in this example Pour obtenir un exemple pratique, consultez Exemple : opérations d'écriture par lots à l'aide de l'API Document AWS SDK for Java (p. 246). API Version 2012-08-10 237 Amazon DynamoDB Manuel du développeur Utilisation d'éléments : Java Batch Get : obtention de plusieurs éléments La méthode batchGetItem vous permet de récupérer plusieurs éléments d'une ou de plusieurs tables. Pour récupérer un seul élément, vous pouvez utiliser la méthode getItem. Procédez comme suit : 1. Créez une instance de la classe DynamoDB. 2. Créez une instance de la classe TableKeysAndAttributes qui décrit une liste de valeurs de clé primaire à récupérer dans une table. Si vous souhaitez lire depuis plusieurs tables dans une opération unique d'obtention par lots, vous devez créer une instance TableKeysAndAttributes par table. 3. Appelez la méthode batchGetItem en fournissant le ou les objets TableKeysAndAttributes que vous avez créés à l'étape précédente. L'extrait de code Java suivant illustre les étapes précédentes. L'exemple récupère deux éléments dans la table Forum et trois éléments dans la table Thread. DynamoDB dynamoDB = new DynamoDB(new AmazonDynamoDBClient( new ProfileCredentialsProvider())); TableKeysAndAttributes forumTableKeysAndAttributes = new TableKeysAndAttributes(forumTableName); forumTableKeysAndAttributes.addHashOnlyPrimaryKeys("Name", "Amazon S3", "Amazon DynamoDB"); TableKeysAndAttributes threadTableKeysAndAttributes = new TableKeysAndAttributes(threadTableName); threadTableKeysAndAttributes.addHashAndRangePrimaryKeys("ForumName", "Subject", "Amazon DynamoDB","DynamoDB Thread 1", "Amazon DynamoDB","DynamoDB Thread 2", "Amazon S3","S3 Thread 1"); BatchGetItemOutcome outcome = dynamoDB.batchGetItem( forumTableKeysAndAttributes, threadTableKeysAndAttributes); for (String tableName : outcome.getTableItems().keySet()) { System.out.println("Items in table " + tableName); List<Item> items = outcome.getTableItems().get(tableName); for (Item item : items) { System.out.println(item); } } Spécification de paramètres facultatifs En même temps que les paramètres requis, vous pouvez également spécifier des paramètres facultatifs lorsque vous utilisez batchGetItem. Par exemple, vous pouvez fournir une ProjectionExpression avec chaque TableKeysAndAttributes que vous définissez. Cela vous permet de spécifier les attributs que vous souhaitez récupérer à partir de la table. L'extrait de code suivant récupère deux éléments de la table Forum. Le paramètre withProjectionExpression spécifie que seuls les attributs Threads doivent être récupérés. API Version 2012-08-10 238 Amazon DynamoDB Manuel du développeur Utilisation d'éléments : Java TableKeysAndAttributes forumTableKeysAndAttributes = new TableKeysAndAttributes("Forum") .withProjectionExpression("Threads"); forumTableKeysAndAttributes.addHashOnlyPrimaryKeys("Name", "Amazon S3", "Amazon DynamoDB"); BatchGetItemOutcome outcome = dynamoDB.batchGetItem(forumTableKeysAndAttributes); Mise à jour d'un élément La méthode updateItem d'un objet Table peut mettre à jour les valeurs d'attribut existantes, ajouter de nouveaux attributs ou supprimer des attributs d'un élément existant. La méthode updateItem se comporte comme suit : • Si un élément n'existe pas (aucun élément dans la table avec la clé primaire spécifiée), updateItem ajoute un nouvel élément à la table • Si un élément existe, updateItem effectue la mise à jour comme indiqué par le paramètre UpdateExpression : Note Il est également possible de « mettre à jour » un élément à l'aide de putItem. Par exemple, si vous appelez putItem pour ajouter un élément à la table, mais qu'il y a déjà un élément avec la clé primaire spécifiée, putItem remplacera l'élément entier. S'il y a des attributs dans l'élément existant qui ne sont pas spécifiés dans l'entrée, putItem va supprimer ces attributs de l'élément. En général, nous vous recommandons d'utiliser updateItem chaque fois que vous voulez modifier des attributs d'élément. La méthode updateItem modifiera uniquement les attributs d'élément que vous spécifiez dans l'entrée et les autres attributs de l'élément demeureront inchangés. Procédez comme suit : 1. Créez une instance de la classe Table pour représenter la table que vous souhaitez utiliser. 2. Appelez la méthode updateTable de l'instance Table. Vous devez spécifier la clé primaire de l'élément que vous souhaitez récupérer, avec une UpdateExpression qui décrit les attributs à modifier et comment les modifier. L'extrait de code Java suivant illustre les tâches précédentes. L'extrait met à jour un élément livre dans la table ProductCatalog. Il ajoute un nouvel auteur à l'ensemble Authors et supprime l'attribut ISBN existant. Il permet également de réduire le prix d'un niveau. Une carte ExpressionAttributeValues est utilisée dans UpdateExpression. Les espaces réservés :val1 et :val2 seront remplacés lors de l'exécution avec les valeurs réelles pour Authors et Price. DynamoDB dynamoDB = new DynamoDB(new AmazonDynamoDBClient( new ProfileCredentialsProvider())); Table table = dynamoDB.getTable("ProductCatalog"); API Version 2012-08-10 239 Amazon DynamoDB Manuel du développeur Utilisation d'éléments : Java Map<String, String> expressionAttributeNames = new HashMap<String, String>(); expressionAttributeNames.put("#A", "Authors"); expressionAttributeNames.put("#P", "Price"); expressionAttributeNames.put("#I", "ISBN"); Map<String, Object> expressionAttributeValues = new HashMap<String, Object>(); expressionAttributeValues.put(":val1", new HashSet<String>(Arrays.asList("Author YY","Author ZZ"))); expressionAttributeValues.put(":val2", 1); //Price UpdateItemOutcome outcome = table.updateItem( "Id", // key attribute name 101, // key attribute value "add #A :val1 set #P = #P - :val2 remove #I", // UpdateExpression expressionAttributeNames, expressionAttributeValues); Spécification de paramètres facultatifs Avec les paramètres requis, vous pouvez également spécifier des paramètres facultatifs pour la méthode updateItem, y compris une condition devant être satisfaite afin que la mise à jour puisse se produire. Si la condition que vous spécifiez n'est pas remplie, alors SDK AWS Java lève une ConditionalCheckFailedException. Par exemple, l'extrait de code Java suivant met à jour de façon conditionnelle le prix d'un élément « book » avec la valeur 25. Il spécifie une ConditionExpression indiquant que le prix doit être mis à jour uniquement si le prix existant est 20. Table table = dynamoDB.getTable("ProductCatalog"); Map<String, String> expressionAttributeNames = new HashMap<String, String>(); expressionAttributeNames.put("#P", "Price"); Map<String, Object> expressionAttributeValues = new HashMap<String, Object>(); expressionAttributeValues.put(":val1", 25); // update Price to 25... expressionAttributeValues.put(":val2", 20); //...but only if existing Price is 20 UpdateItemOutcome outcome = table.updateItem( new PrimaryKey("Id",101), "set #P = :val1", // UpdateExpression "#P = :val2", // ConditionExpression expressionAttributeNames, expressionAttributeValues); Compteur atomique Vous pouvez utiliser updateItem pour implémenter un compteur atomique, où vous incrémentez ou décrémentez la valeur d'un attribut existant sans interférer avec d'autres demandes d'écriture. Pour incrémenter un compteur atomique, utilisez une UpdateExpression avec une action set pour ajouter une valeur numérique à un attribut existant de type Number. L'extrait de code suivant illustre cette action, en incrémentant l'attribut Quantity d'une unité. Il démontre également l'utilisation du paramètre ExpressionAttributeNames dans une UpdateExpression. Table table = dynamoDB.getTable("ProductCatalog"); API Version 2012-08-10 240 Amazon DynamoDB Manuel du développeur Utilisation d'éléments : Java Map<String,String> expressionAttributeNames = new HashMap<String,String>(); expressionAttributeNames.put("#p", "PageCount"); Map<String,Object> expressionAttributeValues = new HashMap<String,Object>(); expressionAttributeValues.put(":val", 1); UpdateItemOutcome outcome = table.updateItem( "Id", 121, "set #p = #p + :val", expressionAttributeNames, expressionAttributeValues); Suppression d'un élément La méthode deleteItem supprime un élément d'une table. Vous devez fournir la clé primaire de l'élément que vous souhaitez supprimer. Procédez comme suit : 1. Créez une instance du client DynamoDB. 2. Appelez la méthode deleteItem en fournissant la clé de l'élément que vous souhaitez supprimer. L'extrait de code Java suivant illustre ces tâches. DynamoDB dynamoDB = new DynamoDB(new AmazonDynamoDBClient( new ProfileCredentialsProvider())); Table table = dynamoDB.getTable("ProductCatalog"); DeleteItemOutcome outcome = table.deleteItem("Id", 101); Spécification de paramètres facultatifs Vous pouvez spécifier des paramètres facultatifs pour deleteItem. Par exemple, l'extrait de code Java suivant comprend une ConditionExpression, indiquant qu'un élément livre dans ProductCatalog peut être supprimé uniquement si le livre n'est plus en publication (l'attribut InPublication est false). Map<String,Object> expressionAttributeValues = new HashMap<String,Object>(); expressionAttributeValues.put(":val", false); DeleteItemOutcome outcome = table.deleteItem("Id",103, "InPublication = :val", null, // ExpressionAttributeNames - not used in this example expressionAttributeValues); Exemple : opérations CRUD à l'aide de l'API Document AWS SDK for Java L'exemple de code suivant illustre les opérations CRUD sur un élément. L'exemple crée un élément, le récupère, exécute plusieurs mises à jour et supprime finalement l'élément. Note Le SDK pour Java fournit également un modèle de persistance d'objet, ce qui vous permet de mapper vos classes côté client sur des tables DynamoDB. Cette approche peut réduire la API Version 2012-08-10 241 Amazon DynamoDB Manuel du développeur Utilisation d'éléments : Java quantité de code que vous avez à écrire. Pour de plus amples informations, veuillez consulter Java : DynamoDBMapper (p. 79). Note Cet exemple de code suppose que vous ayez déjà chargé des données dans DynamoDB pour votre compte en suivant les instructions de la section Création de tables et chargement d'exemples de données (p. 167). Pour obtenir les instructions pas à pas afin d'exécuter l'exemple suivant, consultez Exemples de Code Java (p. 173). // Copyright 2012-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. // Licensed under the Apache License, Version 2.0. package com.amazonaws.codesamples.document; import import import import import java.io.IOException; java.util.Arrays; java.util.HashMap; java.util.HashSet; java.util.Map; import import import import import import import import import import import import com.amazonaws.auth.profile.ProfileCredentialsProvider; com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient; com.amazonaws.services.dynamodbv2.document.DeleteItemOutcome; com.amazonaws.services.dynamodbv2.document.DynamoDB; com.amazonaws.services.dynamodbv2.document.Item; com.amazonaws.services.dynamodbv2.document.Table; com.amazonaws.services.dynamodbv2.document.UpdateItemOutcome; com.amazonaws.services.dynamodbv2.document.spec.DeleteItemSpec; com.amazonaws.services.dynamodbv2.document.spec.UpdateItemSpec; com.amazonaws.services.dynamodbv2.document.utils.NameMap; com.amazonaws.services.dynamodbv2.document.utils.ValueMap; com.amazonaws.services.dynamodbv2.model.ReturnValue; public class DocumentAPIItemCRUDExample { static DynamoDB dynamoDB = new DynamoDB(new AmazonDynamoDBClient( new ProfileCredentialsProvider())); static String tableName = "ProductCatalog"; public static void main(String[] args) throws IOException { createItems(); retrieveItem(); // Perform various updates. updateMultipleAttributes(); updateAddNewAttribute(); updateExistingAttributeConditionally(); // Delete the item. deleteItem(); API Version 2012-08-10 242 Amazon DynamoDB Manuel du développeur Utilisation d'éléments : Java } private static void createItems() { Table table = dynamoDB.getTable(tableName); try { Item item = new Item() .withPrimaryKey("Id", 120) .withString("Title", "Book 120 Title") .withString("ISBN", "120-1111111111") .withStringSet( "Authors", new HashSet<String>(Arrays.asList("Author12", "Author22"))) .withNumber("Price", 20) .withString("Dimensions", "8.5x11.0x.75") .withNumber("PageCount", 500) .withBoolean("InPublication", false) .withString("ProductCategory", "Book"); table.putItem(item); item = new Item() .withPrimaryKey("Id", 121) .withString("Title", "Book 121 Title") .withString("ISBN", "121-1111111111") .withStringSet( "Authors", new HashSet<String>(Arrays.asList("Author21", "Author 22"))) .withNumber("Price", 20) .withString("Dimensions", "8.5x11.0x.75") .withNumber("PageCount", 500) .withBoolean("InPublication", true) .withString("ProductCategory", "Book"); table.putItem(item); } catch (Exception e) { System.err.println("Create items failed."); System.err.println(e.getMessage()); } } private static void retrieveItem() { Table table = dynamoDB.getTable(tableName); try { Item item = table.getItem("Id", 120, "Id, ISBN, Title, Authors", null); System.out.println("Printing item after retrieving it...."); System.out.println(item.toJSONPretty()); } catch (Exception e) { System.err.println("GetItem failed."); System.err.println(e.getMessage()); } } API Version 2012-08-10 243 Amazon DynamoDB Manuel du développeur Utilisation d'éléments : Java private static void updateAddNewAttribute() { Table table = dynamoDB.getTable(tableName); try { Map<String, String> expressionAttributeNames = new HashMap<String, String>(); expressionAttributeNames.put("#na", "NewAttribute"); UpdateItemSpec updateItemSpec = new UpdateItemSpec() .withPrimaryKey("Id", 121) .withUpdateExpression("set #na = :val1") .withNameMap(new NameMap() .with("#na", "NewAttribute")) .withValueMap(new ValueMap() .withString(":val1", "Some value")) .withReturnValues(ReturnValue.ALL_NEW); UpdateItemOutcome outcome = table.updateItem(updateItemSpec); // Check the response. System.out.println("Printing item after adding new attribute..."); System.out.println(outcome.getItem().toJSONPretty()); } catch (Exception e) { System.err.println("Failed to add new attribute in " + tableName); System.err.println(e.getMessage()); } } private static void updateMultipleAttributes() { Table table = dynamoDB.getTable(tableName); try { UpdateItemSpec updateItemSpec = new UpdateItemSpec() .withPrimaryKey("Id", 120) .withUpdateExpression("add #a :val1 set #na=:val2") .withNameMap(new NameMap() .with("#a", "Authors") .with("#na", "NewAttribute")) .withValueMap(new ValueMap() .withStringSet(":val1", "Author YY", "Author ZZ") .withString(":val2", "someValue")) .withReturnValues(ReturnValue.ALL_NEW); UpdateItemOutcome outcome = table.updateItem(updateItemSpec); // Check the response. System.out .println("Printing item after multiple attribute update..."); System.out.println(outcome.getItem().toJSONPretty()); } catch (Exception e) { System.err.println("Failed to update multiple attributes in " API Version 2012-08-10 244 Amazon DynamoDB Manuel du développeur Utilisation d'éléments : Java + tableName); System.err.println(e.getMessage()); } } private static void updateExistingAttributeConditionally() { Table table = dynamoDB.getTable(tableName); try { // Specify the desired price (25.00) and also the condition (price = // 20.00) UpdateItemSpec updateItemSpec = new UpdateItemSpec() .withPrimaryKey("Id", 120) .withReturnValues(ReturnValue.ALL_NEW) .withUpdateExpression("set #p = :val1") .withConditionExpression("#p = :val2") .withNameMap(new NameMap() .with("#p", "Price")) .withValueMap(new ValueMap() .withNumber(":val1", 25) .withNumber(":val2", 20)); UpdateItemOutcome outcome = table.updateItem(updateItemSpec); // Check the response. System.out .println("Printing item after conditional update to new attribute..."); System.out.println(outcome.getItem().toJSONPretty()); } catch (Exception e) { System.err.println("Error updating item in " + tableName); System.err.println(e.getMessage()); } } private static void deleteItem() { Table table = dynamoDB.getTable(tableName); try { DeleteItemSpec deleteItemSpec = new DeleteItemSpec() .withPrimaryKey("Id", 120) .withConditionExpression("#ip = :val") .withNameMap(new NameMap() .with("#ip", "InPublication")) .withValueMap(new ValueMap() .withBoolean(":val", false)) .withReturnValues(ReturnValue.ALL_OLD); DeleteItemOutcome outcome = table.deleteItem(deleteItemSpec); // Check the response. API Version 2012-08-10 245 Amazon DynamoDB Manuel du développeur Utilisation d'éléments : Java System.out.println("Printing item that was deleted..."); System.out.println(outcome.getItem().toJSONPretty()); } catch (Exception e) { System.err.println("Error deleting item in " + tableName); System.err.println(e.getMessage()); } } } Exemple : opérations par lots à l'aide de l'API Document AWS SDK for Java Rubriques • Exemple : opérations d'écriture par lots à l'aide de l'API Document AWS SDK for Java (p. 246) • Exemple : opérations Get par lots à l'aide de l'API Document AWS SDK for Java (p. 248) Cette section fournit des exemples d'opération d'écriture par lots et d'obtention par lots à l'aide de l'API Document AWS SDK for Java. Note Le SDK pour Java fournit également un modèle de persistance d'objet, ce qui vous permet de mapper vos classes côté client sur des tables DynamoDB. Cette approche peut réduire la quantité de code que vous avez à écrire. Pour de plus amples informations, veuillez consulter Java : DynamoDBMapper (p. 79). Exemple : opérations d'écriture par lots à l'aide de l'API Document AWS SDK for Java L'exemple de code Java suivant utilise la méthode batchWriteItem pour exécuter les opérations « put » et « delete » suivantes : • Insérer un élément dans la table Forum. • Insérer un élément et supprimer un élément de la table Thread. Vous pouvez spécifier n'importe quel nombre de requêtes put et delete sur une ou plusieurs tables lors de la création de votre demande d'écriture par lots. Cependant, batchWriteItem limite la taille d'une demande d'écriture par lots et le nombre d'opérations « put » et « delete » d'une même opération d'écriture par lots. Si votre demande dépasse ces limites, elle est rejetée. Si votre table n'a pas suffisamment de débit alloué pour traiter cette demande, les éléments non traités de la demande sont renvoyés dans la réponse. L'exemple suivant vérifie la réponse pour voir si elle a des éléments de demande non traités. Si tel est le cas, une boucle est parcourue et la demande batchWriteItem est renvoyée avec les articles non traités de la demande. Si vous avez suivi la section Création de tables et chargement d'exemples de données (p. 167), vous devez déjà avoir créé les tables Forum et Thread. Vous pouvez aussi créer ces tables et charger des exemples de données par programmation. Pour de plus amples informations, veuillez consulter Création d'exemples de table et de chargement de données à l'aide du kit de développement (SDK) AWS pour Java (p. 607). Pour obtenir les instructions pas à pas afin de tester l'exemple suivant, consultez Exemples de Code Java (p. 173). API Version 2012-08-10 246 Amazon DynamoDB Manuel du développeur Utilisation d'éléments : Java // Copyright 2012-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. // Licensed under the Apache License, Version 2.0. package com.amazonaws.codesamples.document; import import import import import java.io.IOException; java.util.Arrays; java.util.HashSet; java.util.List; java.util.Map; import import import import import import import com.amazonaws.auth.profile.ProfileCredentialsProvider; com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient; com.amazonaws.services.dynamodbv2.document.BatchWriteItemOutcome; com.amazonaws.services.dynamodbv2.document.DynamoDB; com.amazonaws.services.dynamodbv2.document.Item; com.amazonaws.services.dynamodbv2.document.TableWriteItems; com.amazonaws.services.dynamodbv2.model.WriteRequest; public class DocumentAPIBatchWrite { static DynamoDB dynamoDB = new DynamoDB(new AmazonDynamoDBClient( new ProfileCredentialsProvider())); static String forumTableName = "Forum"; static String threadTableName = "Thread"; public static void main(String[] args) throws IOException { writeMultipleItemsBatchWrite(); } private static void writeMultipleItemsBatchWrite() { try { // Add a new item to Forum TableWriteItems forumTableWriteItems = new TableWriteItems(forumTableName) //Forum .withItemsToPut(new Item() .withPrimaryKey("Name", "Amazon RDS") .withNumber("Threads", 0)); // Add a new item, and delete an existing item, from Thread // This table has a partition key and range key, so need to specify both of them TableWriteItems threadTableWriteItems = new TableWriteItems(threadTableName) .withItemsToPut(new Item() .withPrimaryKey("ForumName","Amazon RDS","Subject","Amazon RDS Thread 1") .withString("Message", "ElastiCache Thread 1 message") .withStringSet("Tags", new HashSet<String>( Arrays.asList("cache", "in-memory")))) .withHashAndRangeKeysToDelete("ForumName","Subject", "Amazon S3", "S3 Thread 100"); System.out.println("Making the request."); API Version 2012-08-10 247 Amazon DynamoDB Manuel du développeur Utilisation d'éléments : Java BatchWriteItemOutcome outcome = dynamoDB.batchWriteItem(forumTableWriteItems, threadTableWriteItems); do { // Check for unprocessed keys which could happen if you exceed provisioned throughput Map<String, List<WriteRequest>> unprocessedItems = outcome.getUnprocessedItems(); if (outcome.getUnprocessedItems().size() == 0) { System.out.println("No unprocessed items found"); } else { System.out.println("Retrieving the unprocessed items"); outcome = dynamoDB.batchWriteItemUnprocessed(unprocessedItems); } } while (outcome.getUnprocessedItems().size() > 0); } catch (Exception e) { System.err.println("Failed to retrieve items: "); e.printStackTrace(System.err); } } } Exemple : opérations Get par lots à l'aide de l'API Document AWS SDK for Java L'exemple de code Java suivant utilise la méthode batchGetItem pour récupérer plusieurs éléments des tables Forum et Thread. La demande BatchGetItemRequest spécifie les noms de table et une liste des clés pour chaque élément à obtenir. L'exemple traite la réponse en imprimant les éléments récupérés. Note Cet exemple de code suppose que vous ayez déjà chargé des données dans DynamoDB pour votre compte en suivant les instructions de la section Création de tables et chargement d'exemples de données (p. 167). Pour obtenir les instructions pas à pas afin d'exécuter l'exemple suivant, consultez Exemples de Code Java (p. 173). // Copyright 2012-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. // Licensed under the Apache License, Version 2.0. package com.amazonaws.codesamples.document; import java.io.IOException; import java.util.List; import java.util.Map; import com.amazonaws.auth.profile.ProfileCredentialsProvider; API Version 2012-08-10 248 Amazon DynamoDB Manuel du développeur Utilisation d'éléments : Java import import import import import import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient; com.amazonaws.services.dynamodbv2.document.BatchGetItemOutcome; com.amazonaws.services.dynamodbv2.document.DynamoDB; com.amazonaws.services.dynamodbv2.document.Item; com.amazonaws.services.dynamodbv2.document.TableKeysAndAttributes; com.amazonaws.services.dynamodbv2.model.KeysAndAttributes; public class DocumentAPIBatchGet { static DynamoDB dynamoDB = new DynamoDB(new AmazonDynamoDBClient( new ProfileCredentialsProvider())); static String forumTableName = "Forum"; static String threadTableName = "Thread"; public static void main(String[] args) throws IOException { retrieveMultipleItemsBatchGet(); } private static void retrieveMultipleItemsBatchGet() { try { TableKeysAndAttributes forumTableKeysAndAttributes = new TableKeysAndAttributes(forumTableName); //Add a partition key forumTableKeysAndAttributes.addHashOnlyPrimaryKeys("Name", "Amazon S3", "Amazon DynamoDB"); TableKeysAndAttributes threadTableKeysAndAttributes = new TableKeysAndAttributes(threadTableName); //Add a partition key and a sort key threadTableKeysAndAttributes.addHashAndRangePrimaryKeys("ForumName", "Subject", "Amazon DynamoDB","DynamoDB Thread 1", "Amazon DynamoDB","DynamoDB Thread 2", "Amazon S3","S3 Thread 1"); System.out.println("Making the request."); BatchGetItemOutcome outcome = dynamoDB.batchGetItem(forumTableKeysAndAttributes, threadTableKeysAndAttributes); Map<String, KeysAndAttributes> unprocessed = null; do { for (String tableName : outcome.getTableItems().keySet()) { System.out.println("Items in table " + tableName); List<Item> items = outcome.getTableItems().get(tableName); for (Item item : items) { System.out.println(item.toJSONPretty()); } } API Version 2012-08-10 249 Amazon DynamoDB Manuel du développeur Utilisation d'éléments : Java // Check for unprocessed keys which could happen if you exceed provisioned // throughput or reach the limit on response size. unprocessed = outcome.getUnprocessedKeys(); if (unprocessed.isEmpty()) { System.out.println("No unprocessed keys found"); } else { System.out.println("Retrieving the unprocessed keys"); outcome = dynamoDB.batchGetItemUnprocessed(unprocessed); } } while (!unprocessed.isEmpty()); } catch (Exception e) { System.err.println("Failed to retrieve items."); System.err.println(e.getMessage()); } } } Exemple : gestion d'attributs de type binaire à l'aide de l'API Document AWS SDK for Java L'exemple de code Java suivant illustre la gestion des attributs de type binaire. L'exemple ajoute un élément à la table de la réponse. L'élément inclut un attribut de type binaire (ExtendedMessage) qui stocke les données compressées. Ensuite, l'exemple récupère l'élément et imprime toutes les valeurs d'attribut. Pour illustrer ce propos, l'exemple utilise la classe GZIPOutputStream pour compresser un exemple de flux et l'assigner à l'attribut ExtendedMessage. Lorsque l'attribut binaire est récupéré, il est décompressé à l'aide de la classe GZIPInputStream. Note Le SDK pour Java fournit également un modèle de persistance d'objet, ce qui vous permet de mapper vos classes côté client sur des tables DynamoDB. Cette approche peut réduire la quantité de code que vous avez à écrire. Pour de plus amples informations, veuillez consulter Java : DynamoDBMapper (p. 79). Si vous avez suivi la section Création de tables et chargement d'exemples de données (p. 167), vous devez déjà avoir créé la table Reply. Vous pouvez également créer ces tables par programmation. Pour de plus amples informations, veuillez consulter Création d'exemples de table et de chargement de données à l'aide du kit de développement (SDK) AWS pour Java (p. 607). Pour obtenir les instructions pas à pas afin de tester l'exemple suivant, consultez Exemples de Code Java (p. 173). // Copyright 2012-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. // Licensed under the Apache License, Version 2.0. package com.amazonaws.codesamples.document; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; API Version 2012-08-10 250 Amazon DynamoDB Manuel du développeur Utilisation d'éléments : Java import import import import import import import java.io.IOException; java.nio.ByteBuffer; java.text.SimpleDateFormat; java.util.Date; java.util.TimeZone; java.util.zip.GZIPInputStream; java.util.zip.GZIPOutputStream; import import import import import import com.amazonaws.auth.profile.ProfileCredentialsProvider; com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient; com.amazonaws.services.dynamodbv2.document.DynamoDB; com.amazonaws.services.dynamodbv2.document.Item; com.amazonaws.services.dynamodbv2.document.Table; com.amazonaws.services.dynamodbv2.document.spec.GetItemSpec; public class DocumentAPIItemBinaryExample { static DynamoDB dynamoDB = new DynamoDB(new AmazonDynamoDBClient( new ProfileCredentialsProvider())); static String tableName = "Reply"; static SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MMdd'T'HH:mm:ss.SSS'Z'"); public static void main(String[] args) throws IOException { try { // Format the primary key values String threadId = "Amazon DynamoDB#DynamoDB Thread 2"; dateFormatter.setTimeZone(TimeZone.getTimeZone("UTC")); String replyDateTime = dateFormatter.format(new Date()); // Add a new reply with a binary attribute type createItem(threadId, replyDateTime); // Retrieve the reply with a binary attribute type retrieveItem(threadId, replyDateTime); // clean up by deleting the item deleteItem(threadId, replyDateTime); } catch (Exception e) { System.err.println("Error running the binary attribute type example: " + e); e.printStackTrace(System.err); } } public static void createItem(String threadId, String replyDateTime) throws IOException { Table table = dynamoDB.getTable(tableName); // Craft a long message String messageInput = "Long message to be compressed in a lengthy forum reply"; // Compress the long message API Version 2012-08-10 251 Amazon DynamoDB Manuel du développeur Utilisation d'éléments : Java ByteBuffer compressedMessage = compressString(messageInput.toString()); table.putItem(new Item() .withPrimaryKey("Id", threadId) .withString("ReplyDateTime", replyDateTime) .withString("Message", "Long message follows") .withBinary("ExtendedMessage", compressedMessage) .withString("PostedBy", "User A")); } public static void retrieveItem(String threadId, String replyDateTime) throws IOException { Table table = dynamoDB.getTable(tableName); GetItemSpec spec = new GetItemSpec() .withPrimaryKey("Id", threadId, "ReplyDateTime", replyDateTime) .withConsistentRead(true); Item item = table.getItem(spec); // Uncompress the reply message and print String uncompressed = uncompressString(ByteBuffer.wrap(item.getBinary("ExtendedMessage"))); System.out.println("Reply message:\n" + " Id: " + item.getString("Id") + "\n" + " ReplyDateTime: " + item.getString("ReplyDateTime") + "\n" + " PostedBy: " + item.getString("PostedBy") + "\n" + " Message: " + item.getString("Message") + "\n" + " ExtendedMessage (uncompressed): " + uncompressed + "\n"); } public static void deleteItem(String threadId, String replyDateTime) { Table table = dynamoDB.getTable(tableName); table.deleteItem("Id", threadId, "ReplyDateTime", replyDateTime); } private static ByteBuffer compressString(String input) throws IOException { // Compress the UTF-8 encoded String into a byte[] ByteArrayOutputStream baos = new ByteArrayOutputStream(); GZIPOutputStream os = new GZIPOutputStream(baos); os.write(input.getBytes("UTF-8")); os.close(); baos.close(); byte[] compressedBytes = baos.toByteArray(); // The following code writes the compressed bytes to a ByteBuffer. // A simpler way to do this is by simply calling ByteBuffer.wrap(compressedBytes); // However, the longer form below shows the importance of resetting the position of the buffer // back to the beginning of the buffer if you are writing bytes directly to it, since the SDK API Version 2012-08-10 252 Amazon DynamoDB Manuel du développeur Utilisation des éléments : .NET // will consider only the bytes after the current position when sending data to DynamoDB. // Using the "wrap" method automatically resets the position to zero. ByteBuffer buffer = ByteBuffer.allocate(compressedBytes.length); buffer.put(compressedBytes, 0, compressedBytes.length); buffer.position(0); // Important: reset the position of the ByteBuffer to the beginning return buffer; } private static String uncompressString(ByteBuffer input) throws IOException { byte[] bytes = input.array(); ByteArrayInputStream bais = new ByteArrayInputStream(bytes); ByteArrayOutputStream baos = new ByteArrayOutputStream(); GZIPInputStream is = new GZIPInputStream(bais); int chunkSize = 1024; byte[] buffer = new byte[chunkSize]; int length = 0; while ((length = is.read(buffer, 0, chunkSize)) != -1) { baos.write(buffer, 0, length); } String result = new String(baos.toByteArray(), "UTF-8"); is.close(); baos.close(); bais.close(); return result; } } Utilisation des éléments : .NET Rubriques • Positionnement d'un élément (p. 254) • Obtention d'un élément (p. 255) • Mise à jour d'un élément (p. 257) • Compteur atomique (p. 259) • Suppression d'un élément (p. 259) • Ecriture par lots : insertion et suppression de plusieurs éléments (p. 260) • Batch Get : obtention de plusieurs éléments (p. 262) • Exemple : opérations CRUD à l'aide du kit SDK AWS pour les API de bas niveau .NET (p. 264) • Exemple : opérations de traitement par lots à l'aide des API de bas niveau du SDK AWS pour .NET (p. 268) • Exemple : gestion des attributs de type Binary (binaire) à l'aide de l'API de bas niveau du kit SDK AWS pour .NET (p. 274) Vous pouvez utiliser le kit SDK AWS pour API de bas niveau .NET afin d'exécuter des opérations CRUD classiques sur un élément d'une table. API Version 2012-08-10 253 Amazon DynamoDB Manuel du développeur Utilisation des éléments : .NET Voici les étapes courantes que vous suivez pour effectuer les opérations CRUD à l'aide de l'API de bas niveau .NET. 1. Créez une instance de la classe AmazonDynamoDBClient (le client). 2. Fournir les paramètres requis propres à l'opération dans un objet de requête correspondant. Par exemple, utilisez l'objet de demande PutItemRequest lors du chargement d'un élément et utilisez l'objet de demande GetItemRequest lors de l'extraction d'un élément existant. Vous pouvez utiliser l'objet de demande pour fournir aussi bien les paramètres obligatoires que ceux facultatifs. 3. Exécuter la méthode appropriée fournie par le client en passant l'objet de demande que vous avez créé à l'étape précédente. Le client AmazonDynamoDBClient fournit les méthodes PutItem, GeItem, UpdateItem et DeleteItem pour les opérations CRUD. Positionnement d'un élément La méthode PutItem charge un élément sur une table. Si l'élément existe, il remplace la totalité de l'élément. Note Au lieu de remplacer l'élément entier, si vous souhaitez mettre à jour uniquement des attributs spécifiques, vous pouvez utiliser la méthode UpdateItem. Pour de plus amples informations, veuillez consulter Mise à jour d'un élément (p. 257). Voici les étapes à suivre pour charger un élément à l'aide de l'API de bas niveau du SDK .NET. 1. Créez une instance de la classe AmazonDynamoDBClient. 2. Fournir les paramètres requis en créant une instance de la classe PutItemRequest. Pour placer un élément, vous devez fournir le nom de la table et l'élément. 3. Exécutez la méthode PutItem en fournissant l'objet PutItemRequest que vous avez créé à l'étape précédente. L'extrait de code C# suivant illustre les étapes précédentes. L'exemple charge un élément sur la table ProductCatalog. AmazonDynamoDBClient client = new AmazonDynamoDBClient(); string tableName = "ProductCatalog"; var request = new PutItemRequest { TableName = tableName, Item = new Dictionary<string, AttributeValue>() { { "Id", new AttributeValue { N = "201" }}, { "Title", new AttributeValue { S = "Book 201 Title" }}, { "ISBN", new AttributeValue { S = "11-11-11-11" }}, { "Price", new AttributeValue { S = "20.00" }}, { "Authors", new AttributeValue { SS = new List<string>{"Author1", "Author2"} } } API Version 2012-08-10 254 Amazon DynamoDB Manuel du développeur Utilisation des éléments : .NET } }; client.PutItem(request); Dans l'exemple précédent, vous chargez un élément « book » qui comporte les attributs Id, Title, ISBN et Authors. Notez que l'Id est un attribut de type numérique et que tous les autres attributs sont de type String (chaîne). Authors est un ensemble de type String. Spécification de paramètres facultatifs Vous pouvez également fournir des paramètres facultatifs à l'aide de l'objet PutItemRequest comme illustré dans l'extrait de code C# suivant. L'échantillon spécifie les paramètres facultatifs suivants : • ExpressionAttributeNames, ExpressionAttributeValues et ConditionExpression spécifient que l'élément ne peut être remplacé que si l'élément existant a un attribut ISBN avec une valeur spécifique. • ReturnValues : paramètre pour demander l'ancien élément dans la réponse. var request = new PutItemRequest { TableName = tableName, Item = new Dictionary<string, AttributeValue>() { { "Id", new AttributeValue { N = "104" }}, { "Title", new AttributeValue { S = "Book 104 Title" }}, { "ISBN", new AttributeValue { S = "444-4444444444" }}, { "Authors", new AttributeValue { SS = new List<string>{"Author3"}}} }, // Optional parameters. ExpressionAttributeNames = new Dictionary<string,string>() { {"#I", "ISBN"} }, ExpressionAttributeValues = new Dictionary<string, AttributeValue>() { {":isbn",new AttributeValue {S = "444-4444444444"}} }, ConditionExpression = "#I = :isbn" }; var response = client.PutItem(request); Pour plus d'informations, consultez PutItem. Obtention d'un élément La méthode GetItem récupère un élément. Note Pour récupérer plusieurs éléments, vous pouvez utiliser la méthode BatchGetItem. Pour de plus amples informations, veuillez consulter Batch Get : obtention de plusieurs éléments (p. 262). Voici les étapes pour récupérer un élément existant à l'aide de l'API de bas niveau du SDK .NET. API Version 2012-08-10 255 Amazon DynamoDB Manuel du développeur Utilisation des éléments : .NET 1. Créez une instance de la classe AmazonDynamoDBClient. 2. Fournir les paramètres requis en créant une instance de la classe GetItemRequest. Pour obtenir un élément, vous devez fournir le nom de la table et la clé primaire de l'élément. 3. Exécutez la méthode GetItem en fournissant l'objet GetItemRequest que vous avez créé à l'étape précédente. L'extrait de code C# suivant illustre les étapes précédentes. L'exemple récupère un élément de la table ProductCatalog. AmazonDynamoDBClient client = new AmazonDynamoDBClient(); string tableName = "ProductCatalog"; var request = new GetItemRequest { TableName = tableName, Key = new Dictionary<string,AttributeValue>() { { "Id", new AttributeValue { N = "202" } } }, }; var response = client.GetItem(request); // Check the response. var result = response.GetItemResult; var attributeMap = result.Item; // Attribute list in the response. Spécification de paramètres facultatifs Vous pouvez également fournir des paramètres facultatifs à l'aide de l'objet GetItemRequest comme illustré dans l'extrait de code C# suivant. L'échantillon spécifie les paramètres facultatifs suivants : • ProjectionExpression : paramètre pour spécifier les attributs à récupérer. • ConsistentRead : paramètre pour exécuter une lecture à cohérence forte. Pour en savoir plus sur la cohérence, consultez Cohérence en lecture (p. 16). AmazonDynamoDBClient client = new AmazonDynamoDBClient(); string tableName = "ProductCatalog"; var request = new GetItemRequest { TableName = tableName, Key = new Dictionary<string,AttributeValue>() { { "Id", new AttributeValue { N = "202" } } }, // Optional parameters. ProjectionExpression = "Id, ISBN, Title, Authors", ConsistentRead = true }; var response = client.GetItem(request); // Check the response. var result = response.GetItemResult; var attributeMap = result.Item; Pour plus d'informations, consultez GetItem. API Version 2012-08-10 256 Amazon DynamoDB Manuel du développeur Utilisation des éléments : .NET Mise à jour d'un élément La méthode UpdateItem met à jour un élément existant s'il est présent. Vous pouvez utiliser l'opération UpdateItem pour mettre à jour les valeurs des attributs existants, ajouter de nouveaux attributs ou en supprimer de la collection existante. Si l'élément qui possède la clé primaire spécifiée est introuvable, un nouvel élément est ajouté. L'opération UpdateItem utilise les directives suivantes : • Si l'élément n'existe pas, UpdateItem ajoute un nouvel élément à l'aide de la clé primaire spécifiée dans l'entrée. • Si l'élément existe, UpdateItem applique les mises à jour comme suit : • Remplace les valeurs d'attribut existantes par les valeurs de la mise à jour. • Si l'attribut que vous fournissez en entrée n'existe pas, un nouvel attribut est ajouté à l'élément. • Si l'attribut en entrée a la valeur null, il est supprimé s'il est présent. • Si vous utilisez ADD pour Action, vous pouvez ajouter des valeurs à un ensemble existant (String Set ou Number Set) ou mathématiquement ajouter (utilisez un nombre positif) ou soustraire (utilisez un nombre négatif) à partir de la valeur d'attribut numérique existante. Note L'opération PutItem peut également exécuter une mise à jour. Pour de plus amples informations, veuillez consulter Positionnement d'un élément (p. 254). Par exemple, si vous appelez PutItem pour charger un élément et que la clé primaire existe, l'opération PutItem remplace la totalité de l'élément. Notez que, s'il existe des attributs dans l'élément existant et qu'ils ne sont pas spécifiés en entrée, l'opération PutItem les supprime. Cependant, UpdateItem ne met à jour que les attributs spécifiés en entrée et tous les autres attributs existants de cet élément demeurent inchangés. Voici les étapes à suivre pour mettre à jour un élément existant à l'aide de l'API de bas niveau du SDK .NET. 1. Créez une instance de la classe AmazonDynamoDBClient. 2. Fournir les paramètres requis en créant une instance de la classe UpdateItemRequest. C'est l'objet de la demande dans laquelle vous décrivez toutes les mises à jour, comme ajouter des attributs, mettre à jour des attributs existants ou en supprimer. Pour supprimer un attribut existant, spécifiez le nom d'attribut avec la valeur null. 3. Exécutez la méthode UpdateItem en fournissant l'objet UpdateItemRequest que vous avez créé à l'étape précédente. L'extrait de code C# suivant illustre les étapes précédentes. L'exemple met à jour un élément « book » dans la table ProductCatalog. Il ajoute un nouvel auteur à la collection Authors et supprime l'attribut ISBN existant. Il permet également de réduire le prix d'un niveau. AmazonDynamoDBClient client = new AmazonDynamoDBClient(); string tableName = "ProductCatalog"; var request = new UpdateItemRequest { TableName = tableName, Key = new Dictionary<string,AttributeValue>() { { "Id", new AttributeValue { N = "202" } } }, API Version 2012-08-10 257 Amazon DynamoDB Manuel du développeur Utilisation des éléments : .NET ExpressionAttributeNames = new Dictionary<string,string>() { {"#A", "Authors"}, {"#P", "Price"}, {"#NA", "NewAttribute"}, {"#I", "ISBN"} }, ExpressionAttributeValues = new Dictionary<string, AttributeValue>() { {":auth",new AttributeValue { SS = {"Author YY","Author ZZ"}}}, {":p",new AttributeValue {N = "1"}}, {":newattr",new AttributeValue {S = "someValue"}}, }, // This expression does the following: // 1) Adds two new authors to the list // 2) Reduces the price // 3) Adds a new attribute to the item // 4) Removes the ISBN attribute from the item UpdateExpression = "ADD #A :auth SET #P = #P - :p, #NA = :newattr REMOVE #I" }; var response = client.UpdateItem(request); Spécification de paramètres facultatifs Vous pouvez également fournir des paramètres facultatifs à l'aide de l'objet UpdateItemRequest comme illustré dans l'extrait de code C# suivant. Il spécifie les paramètres facultatifs suivants : • ExpressionAttributeValues et ConditionExpression pour spécifier que le prix peut être mis à jour uniquement si le prix existant est égal à 20.00. • ReturnValues : paramètre pour demander l'élément mis à jour dans la réponse. AmazonDynamoDBClient client = new AmazonDynamoDBClient(); string tableName = "ProductCatalog"; var request = new UpdateItemRequest { Key = new Dictionary<string,AttributeValue>() { { "Id", new AttributeValue { N = "202" } } }, // Update price only if the current price is 20.00. ExpressionAttributeNames = new Dictionary<string,string>() { {"#P", "Price"} }, ExpressionAttributeValues = new Dictionary<string, AttributeValue>() { {":newprice",new AttributeValue {N = "22"}}, {":currprice",new AttributeValue {N = "20"}} }, UpdateExpression = "SET #P = :newprice", ConditionExpression = "#P = :currprice", TableName = tableName, ReturnValues = "ALL_NEW" // Return all the attributes of the updated item. }; API Version 2012-08-10 258 Amazon DynamoDB Manuel du développeur Utilisation des éléments : .NET var response = client.UpdateItem(request); Pour plus d'informations, voir UpdateItem. Compteur atomique Vous pouvez utiliser updateItem pour implémenter un compteur atomique, où vous incrémentez ou décrémentez la valeur d'un attribut existant sans interférer avec d'autres demandes d'écriture. Pour mettre à jour un compteur atomique, utilisez updateItem avec un attribut de type Number (numérique) dans le paramètre UpdateExpression, et ADD comme Action. L'extrait de code suivant illustre cette action, en incrémentant l'attribut Quantity d'une unité. AmazonDynamoDBClient client = new AmazonDynamoDBClient(); string tableName = "ProductCatalog"; var request = new UpdateItemRequest { Key = new Dictionary<string, AttributeValue>() { { "Id", new AttributeValue { N = "121" } } }, ExpressionAttributeNames = new Dictionary<string, string>() { {"#Q", "Quantity"} }, ExpressionAttributeValues = new Dictionary<string, AttributeValue>() { {":incr",new AttributeValue {N = "1"}} }, UpdateExpression = "SET #Q = #Q + :incr", TableName = tableName }; var response = client.UpdateItem(request); Suppression d'un élément La méthode DeleteItem supprime un élément d'une table. Voici les étapes à suivre pour supprimer un élément à l'aide de l'API de bas niveau du SDK .NET. 1. Créez une instance de la classe AmazonDynamoDBClient. 2. Fournir les paramètres requis en créant une instance de la classe DeleteItemRequest. Pour supprimer un élément, le nom de table et la clé primaire de l'élément sont obligatoires. 3. Exécutez la méthode DeleteItem en fournissant l'objet DeleteItemRequest que vous avez créé à l'étape précédente. AmazonDynamoDBClient client = new AmazonDynamoDBClient(); string tableName = "ProductCatalog"; var request = new DeleteItemRequest { TableName = tableName, Key = new Dictionary<string,AttributeValue>() { { "Id", new AttributeValue { N = "201" } } }, API Version 2012-08-10 259 Amazon DynamoDB Manuel du développeur Utilisation des éléments : .NET }; var response = client.DeleteItem(request); Spécification de paramètres facultatifs Vous pouvez également fournir des paramètres facultatifs à l'aide de l'objet DeleteItemRequest comme illustré dans l'extrait de code C# suivant. Il spécifie les paramètres facultatifs suivants : • ExpressionAttributeValues et ConditionExpression pour spécifier que l'élément livre ne peut être supprimé que s'il n'est plus publié (la valeur de l'attribut InPublication est false). • ReturnValues : paramètre pour demander l'élément supprimé dans la réponse. var request = new DeleteItemRequest { TableName = tableName, Key = new Dictionary<string,AttributeValue>() { { "Id", new AttributeValue { N = "201" } } }, // Optional parameters. ReturnValues = "ALL_OLD", ExpressionAttributeNames = new Dictionary<string, string>() { {"#IP", "InPublication"} }, ExpressionAttributeValues = new Dictionary<string, AttributeValue>() { {":inpub",new AttributeValue {BOOL = false}} }, ConditionExpression = "#IP = :inpub" }; var response = client.DeleteItem(request); Pour plus d'informations, voir DeleteItem. Ecriture par lots : insertion et suppression de plusieurs éléments L'écriture par lots fait référence à l'insertion et la suppression de plusieurs éléments dans un lot. La méthode BatchWriteItem vous permet d'insérer et de supprimer plusieurs éléments d'une ou de plusieurs tables en un seul appel. Voici les étapes pour récupérer plusieurs éléments à l'aide de l'API de bas niveau du SDK .NET. 1. Créez une instance de la classe AmazonDynamoDBClient. 2. Décrivez toutes les opérations « put » et « delete » en créant une instance de la classe BatchWriteItemRequest. 3. Exécutez la méthode BatchWriteItem en fournissant l'objet BatchWriteItemRequest que vous avez créé à l'étape précédente. 4. Traitez la réponse. Vous devez vérifier si des éléments de requêtes non traités ont été renvoyés dans la réponse. Cela peut se produire si vous atteignez la limite de débit allouée ou une autre erreur temporaire. En outre, DynamoDB limite la taille de la requête et le nombre d'opérations que vous pouvez spécifier dans une requête. Si vous dépassez ces limites, DynamoDB rejette la requête. Pour plus d'informations, consultez BatchWriteItem. API Version 2012-08-10 260 Amazon DynamoDB Manuel du développeur Utilisation des éléments : .NET L'extrait de code C# suivant illustre les étapes précédentes. L'exemple crée un BatchWriteItemRequest pour exécuter les opérations d'écriture suivantes : • Placer un élément dans la table Forum • Placer et supprimer un élément de la table Thread Le code exécute ensuite BatchWriteItem pour effectuer une opération de traitement par lots. AmazonDynamoDBClient client = new AmazonDynamoDBClient(); string table1Name = "Forum"; string table2Name = "Thread"; var request = new BatchWriteItemRequest { RequestItems = new Dictionary<string, List<WriteRequest>> { { table1Name, new List<WriteRequest> { new WriteRequest { PutRequest = new PutRequest { Item = new Dictionary<string,AttributeValue> { { "Name", new AttributeValue { S = "Amazon S3 forum" } }, { "Threads", new AttributeValue { N = "0" }} } } } } } , { table2Name, new List<WriteRequest> { new WriteRequest { PutRequest = new PutRequest { Item = new Dictionary<string,AttributeValue> { { "ForumName", new AttributeValue { S = "Amazon S3 forum" } }, { "Subject", new AttributeValue { S = "My sample question" } }, { "Message", new AttributeValue { S = "Message Text." } }, { "KeywordTags", new AttributeValue { SS = new List<string> { "Amazon S3", "Bucket" } } } } } }, new WriteRequest { DeleteRequest = new DeleteRequest { Key = new Dictionary<string,AttributeValue>() { API Version 2012-08-10 261 Amazon DynamoDB Manuel du développeur Utilisation des éléments : .NET { "ForumName", new AttributeValue { S = "Some forum name" } }, { "Subject", new AttributeValue { S = "Some subject" } } } } } } } } }; response = client.BatchWriteItem(request); Pour obtenir un exemple pratique, consultez Exemple : opérations de traitement par lots à l'aide des API de bas niveau du SDK AWS pour .NET (p. 268). Batch Get : obtention de plusieurs éléments La méthode BatchGetItem vous permet de récupérer plusieurs éléments d'une ou de plusieurs tables. Note Pour récupérer un seul élément, vous pouvez utiliser la méthode GetItem. Voici les étapes pour récupérer plusieurs éléments à l'aide de l'API de bas niveau du SDK .NET. 1. Créez une instance de la classe AmazonDynamoDBClient. 2. Fournir les paramètres requis en créant une instance de la classe BatchGetItemRequest. Pour récupérer plusieurs éléments, le nom de la table et la liste des valeurs de clé primaire sont obligatoires. 3. Exécutez la méthode BatchGetItem en fournissant l'objet BatchGetItemRequest que vous avez créé à l'étape précédente. 4. Traitez la réponse. Vous devez vérifier s'il existe des clés non traités, ce qui peut se produire si vous atteignez la limite de débit alloué ou autre erreur temporaire. L'extrait de code C# suivant illustre les étapes précédentes. L'exemple récupère les éléments de deux tables, Forum et Thread. La demande spécifie deux éléments de la table Forum et trois éléments de la table Thread. La réponse inclut les éléments des deux tables. Le code montre comment vous pouvez traiter la réponse. AmazonDynamoDBClient client = new AmazonDynamoDBClient(); string table1Name = "Forum"; string table2Name = "Thread"; var request = new BatchGetItemRequest { RequestItems = new Dictionary<string, KeysAndAttributes>() { { table1Name, new KeysAndAttributes { Keys = new List<Dictionary<string, AttributeValue>>() { new Dictionary<string, AttributeValue>() API Version 2012-08-10 262 Amazon DynamoDB Manuel du développeur Utilisation des éléments : .NET { { "Name", new AttributeValue { S = "DynamoDB" } } }, new Dictionary<string, AttributeValue>() { { "Name", new AttributeValue { S = "Amazon S3" } } } } } }, { table2Name, new KeysAndAttributes { Keys = new List<Dictionary<string, AttributeValue>>() { new Dictionary<string, AttributeValue>() { { "ForumName", new AttributeValue { S = "DynamoDB" } }, { "Subject", new AttributeValue { S = "DynamoDB Thread 1" } } }, new Dictionary<string, AttributeValue>() { { "ForumName", new AttributeValue { S = "DynamoDB" } }, { "Subject", new AttributeValue { S = "DynamoDB Thread 2" } } }, new Dictionary<string, AttributeValue>() { { "ForumName", new AttributeValue { S = "Amazon S3" } }, { "Subject", new AttributeValue { S = "Amazon S3 Thread 1" } } } } } } } }; var response = client.BatchGetItem(request); // Check the response. var result = response.BatchGetItemResult; var responses = result.Responses; // The attribute list in the response. var table1Results = responses[table1Name]; Console.WriteLine("Items in table {0}" + table1Name); foreach (var item1 in table1Results.Items) { PrintItem(item1); } var table2Results = responses[table2Name]; Console.WriteLine("Items in table {1}" + table2Name); foreach (var item2 in table2Results.Items) { PrintItem(item2); } // Any unprocessed keys? could happen if you exceed ProvisionedThroughput or some other error. API Version 2012-08-10 263 Amazon DynamoDB Manuel du développeur Utilisation des éléments : .NET Dictionary<string, KeysAndAttributes> unprocessedKeys = result.UnprocessedKeys; foreach (KeyValuePair<string, KeysAndAttributes> pair in unprocessedKeys) { Console.WriteLine(pair.Key, pair.Value); } Spécification de paramètres facultatifs Vous pouvez également fournir des paramètres facultatifs à l'aide de l'objet BatchGetItemRequest comme illustré dans l'extrait de code C# suivant. L'exemple de code récupère deux éléments de la table Forum. Il spécifie le paramètre facultatif suivant : • ProjectionExpression : paramètre pour spécifier les attributs à récupérer. AmazonDynamoDBClient client = new AmazonDynamoDBClient(); string table1Name = "Forum"; var request = new BatchGetItemRequest { RequestItems = new Dictionary<string, KeysAndAttributes>() { { table1Name, new KeysAndAttributes { Keys = new List<Dictionary<string, AttributeValue>>() { new Dictionary<string, AttributeValue>() { { "Name", new AttributeValue { S = "DynamoDB" } } }, new Dictionary<string, AttributeValue>() { { "Name", new AttributeValue { S = "Amazon S3" } } } } }, // Optional - name of an attribute to retrieve. ProjectionExpression = "Title" } } }; var response = client.BatchGetItem(request); Pour plus d'informations, consultez BatchGetItem. Exemple : opérations CRUD à l'aide du kit SDK AWS pour les API de bas niveau .NET L'exemple de code C# suivant illustre les opérations CRUD sur un élément. L'exemple ajoute un élément à la table ProductCatalog, le récupère, exécute différentes mises à jour et, enfin, supprime l'élément. Si vous avez suivi les étapes de Création de tables et chargement d'exemples de données (p. 167), la table ProductCatalog est déjà créée. Vous pouvez aussi créer ces exemples de API Version 2012-08-10 264 Amazon DynamoDB Manuel du développeur Utilisation des éléments : .NET table par programmation. Pour de plus amples informations, veuillez consulter Création d'exemples de table et de chargement de données à l'aide du kit de développement (SDK) AWS pour .NET (p. 615). Pour obtenir les instructions pas à pas afin de tester l'exemple suivant, consultez Exemples de code .NET (p. 175). using using using using using using System; System.Collections.Generic; Amazon.DynamoDBv2; Amazon.DynamoDBv2.Model; Amazon.Runtime; Amazon.SecurityToken; namespace com.amazonaws.codesamples { class LowLevelItemCRUDExample { private static string tableName = "ProductCatalog"; private static AmazonDynamoDBClient client = new AmazonDynamoDBClient(); static void Main(string[] args) { try { CreateItem(); RetrieveItem(); // Perform various updates. UpdateMultipleAttributes(); UpdateExistingAttributeConditionally(); // Delete item. DeleteItem(); Console.WriteLine("To continue, press Enter"); Console.ReadLine(); } catch (Exception e) { Console.WriteLine(e.Message); Console.WriteLine("To continue, press Enter"); Console.ReadLine(); } } private static void CreateItem() { var request = new PutItemRequest { TableName = tableName, Item = new Dictionary<string, AttributeValue>() { { "Id", new AttributeValue { N = "1000" }}, { "Title", new AttributeValue { S = "Book 201 Title" }}, { "ISBN", new AttributeValue { S = "11-11-11-11" }}, { "Authors", new AttributeValue { SS = new List<string>{"Author1", "Author2" }}}, { "Price", new AttributeValue { N = "20.00" }}, API Version 2012-08-10 265 Amazon DynamoDB Manuel du développeur Utilisation des éléments : .NET { "Dimensions", new AttributeValue { S = "8.5x11.0x.75" }}, { "InPublication", new AttributeValue { BOOL = false } } } }; client.PutItem(request); } private static void RetrieveItem() { var request = new GetItemRequest { TableName = tableName, Key = new Dictionary<string, AttributeValue>() { { "Id", new AttributeValue { N = "1000" } } }, ProjectionExpression = "Id, ISBN, Title, Authors", ConsistentRead = true }; var response = client.GetItem(request); // Check the response. var attributeList = response.Item; // attribute list in the response. Console.WriteLine("\nPrinting item after retrieving it ............"); PrintItem(attributeList); } private static void UpdateMultipleAttributes() { var request = new UpdateItemRequest { Key = new Dictionary<string, AttributeValue>() { { "Id", new AttributeValue { N = "1000" } } }, // Perform the following updates: // 1) Add two new authors to the list // 1) Set a new attribute // 2) Remove the ISBN attribute ExpressionAttributeNames = new Dictionary<string,string>() { {"#A","Authors"}, {"#NA","NewAttribute"}, {"#I","ISBN"} }, ExpressionAttributeValues = new Dictionary<string, AttributeValue>() { {":auth",new AttributeValue {SS = {"Author YY", "Author ZZ"}}}, {":new",new AttributeValue {S = "New Value"}} }, UpdateExpression = "ADD #A :auth SET #NA = :new REMOVE #I", TableName = tableName, API Version 2012-08-10 266 Amazon DynamoDB Manuel du développeur Utilisation des éléments : .NET ReturnValues = "ALL_NEW" // Give me all attributes of the updated item. }; var response = client.UpdateItem(request); // Check the response. var attributeList = response.Attributes; // attribute list in the response. // print attributeList. Console.WriteLine("\nPrinting item after multiple attribute update ............"); PrintItem(attributeList); } private static void UpdateExistingAttributeConditionally() { var request = new UpdateItemRequest { Key = new Dictionary<string, AttributeValue>() { { "Id", new AttributeValue { N = "1000" } } }, ExpressionAttributeNames = new Dictionary<string,string>() { {"#P", "Price"} }, ExpressionAttributeValues = new Dictionary<string, AttributeValue>() { {":newprice",new AttributeValue {N = "22.00"}}, {":currprice",new AttributeValue {N = "20.00"}} }, // This updates price only if current price is 20.00. UpdateExpression = "SET #P = :newprice", ConditionExpression = "#P = :currprice", TableName = tableName, ReturnValues = "ALL_NEW" // Give me all attributes of the updated item. }; var response = client.UpdateItem(request); // Check the response. var attributeList = response.Attributes; // attribute list in the response. Console.WriteLine("\nPrinting item after updating price value conditionally ............"); PrintItem(attributeList); } private static void DeleteItem() { var request = new DeleteItemRequest { TableName = tableName, Key = new Dictionary<string, AttributeValue>() { { "Id", new AttributeValue { N = "1000" } } }, API Version 2012-08-10 267 Amazon DynamoDB Manuel du développeur Utilisation des éléments : .NET // Return the entire item as it appeared before the update. ReturnValues = "ALL_OLD", ExpressionAttributeNames = new Dictionary<string,string>() { {"#IP", "InPublication"} }, ExpressionAttributeValues = new Dictionary<string, AttributeValue>() { {":inpub",new AttributeValue {BOOL = false}} }, ConditionExpression = "#IP = :inpub" }; var response = client.DeleteItem(request); // Check the response. var attributeList = response.Attributes; // Attribute list in the response. // Print item. Console.WriteLine("\nPrinting item that was just deleted ............"); PrintItem(attributeList); } private static void PrintItem(Dictionary<string, AttributeValue> attributeList) { foreach (KeyValuePair<string, AttributeValue> kvp in attributeList) { string attributeName = kvp.Key; AttributeValue value = kvp.Value; Console.WriteLine( attributeName + " " + (value.S == null ? "" : "S=[" + (value.N == null ? "" : "N=[" + (value.SS == null ? "" : "SS=[" value.SS.ToArray()) + "]") + (value.NS == null ? "" : "NS=[" value.NS.ToArray()) + "]") ); } value.S + "]") + value.N + "]") + + string.Join(",", + string.Join(",", Console.WriteLine("************************************************"); } } } Exemple : opérations de traitement par lots à l'aide des API de bas niveau du SDK AWS pour .NET Rubriques • Exemple : opération d'écriture par lots à l'aide du kit SDK AWS pour les API de bas niveau .NET (p. 269) API Version 2012-08-10 268 Amazon DynamoDB Manuel du développeur Utilisation des éléments : .NET • Exemple : opération d'obtention par lots à l'aide du kit SDK AWS pour les API de bas niveau .NET (p. 272) Cette section fournit des exemples d'opérations de traitement par lots, telles que l'écriture par lots et l'obtention par lots, que DynamoDB prend en charge. Exemple : opération d'écriture par lots à l'aide du kit SDK AWS pour les API de bas niveau .NET L'exemple de code C# suivant utilise la méthode BatchWriteItem pour exécuter les opérations « put » et « delete » suivantes : • Insérer un élément dans la table Forum. • Insérer un élément et supprimer un élément de la table Thread. Vous pouvez spécifier n'importe quel nombre de requêtes put et delete sur une ou plusieurs tables lors de la création de votre demande d'écriture par lots. Cependant, la demande DynamoDB BatchWriteItem limite la taille d'une demande d'écriture par lots et le nombre d'opérations « put » et « delete » d'une même opération d'écriture par lots. Pour plus d'informations, consultez BatchWriteItem. Si votre demande dépasse ces limites, elle est rejetée. Si votre table n'a pas suffisamment de débit alloué pour traiter cette demande, les éléments non traités de la demande sont renvoyés dans la réponse. L'exemple suivant vérifie la réponse pour voir si elle a des éléments de demande non traités. Si tel est le cas, une boucle est parcourue et la demande BatchWriteItem est renvoyée avec les articles non traités de la demande. Si vous avez suivi les étapes de Création de tables et chargement d'exemples de données (p. 167), les tables Forum et Thread sont déjà créées. Vous pouvez aussi créer ces exemples de tables et charger les exemples de données par programmation. Pour de plus amples informations, veuillez consulter Création d'exemples de table et de chargement de données à l'aide du kit de développement (SDK) AWS pour .NET (p. 615). Pour obtenir les instructions pas à pas afin de tester l'exemple suivant, consultez Exemples de code .NET (p. 175). using using using using using System; System.Collections.Generic; Amazon.DynamoDBv2; Amazon.DynamoDBv2.Model; Amazon.Runtime; namespace com.amazonaws.codesamples { class LowLevelBatchWrite { private static string table1Name = "Forum"; private static string table2Name = "Thread"; private static AmazonDynamoDBClient client = new AmazonDynamoDBClient(); static void Main(string[] args) { try { TestBatchWrite(); } API Version 2012-08-10 269 Amazon DynamoDB Manuel du développeur Utilisation des éléments : .NET catch (AmazonServiceException e) { Console.WriteLine(e.Message); } catch (Exception e) { Console.WriteLine(e.Message); } Console.WriteLine("To continue, press Enter"); Console.ReadLine(); } private static void TestBatchWrite() { var request = new BatchWriteItemRequest { ReturnConsumedCapacity = "TOTAL", RequestItems = new Dictionary<string, List<WriteRequest>> { { table1Name, new List<WriteRequest> { new WriteRequest { PutRequest = new PutRequest { Item = new Dictionary<string, AttributeValue> { { "Name", new AttributeValue { S = "S3 forum" } }, { "Threads", new AttributeValue { N = "0" }} } } } } }, { table2Name, new List<WriteRequest> { new WriteRequest { PutRequest = new PutRequest { Item = new Dictionary<string, AttributeValue> { { "ForumName", new AttributeValue { S = "S3 forum" } }, { "Subject", new AttributeValue { S = "My sample question" } }, { "Message", new AttributeValue { S = "Message Text." } }, { "KeywordTags", new AttributeValue { SS = new List<string> { "S3", "Bucket" } } } } } }, new WriteRequest { // For the operation to delete an item, if you provide a primary key value // that does not exist in the table, there is no error, it is just a no-op. DeleteRequest = new DeleteRequest { Key = new Dictionary<string, AttributeValue>() API Version 2012-08-10 270 Amazon DynamoDB Manuel du développeur Utilisation des éléments : .NET { { "ForumName", new AttributeValue { S = "Some partition key value" } }, { "Subject", new AttributeValue { S = "Some sort key value" } } } } } } } } }; CallBatchWriteTillCompletion(request); } private static void CallBatchWriteTillCompletion(BatchWriteItemRequest request) { BatchWriteItemResponse response; int callCount = 0; do { Console.WriteLine("Making request"); response = client.BatchWriteItem(request); callCount++; // Check the response. var tableConsumedCapacities = response.ConsumedCapacity; var unprocessed = response.UnprocessedItems; Console.WriteLine("Per-table consumed capacity"); foreach (var tableConsumedCapacity in tableConsumedCapacities) { Console.WriteLine("{0} - {1}", tableConsumedCapacity.TableName, tableConsumedCapacity.CapacityUnits); } Console.WriteLine("Unprocessed"); foreach (var unp in unprocessed) { Console.WriteLine("{0} - {1}", unp.Key, unp.Value.Count); } Console.WriteLine(); // For the next iteration, the request will have unprocessed items. request.RequestItems = unprocessed; } while (response.UnprocessedItems.Count > 0); Console.WriteLine("Total # of batch write API calls made: {0}", callCount); } } } API Version 2012-08-10 271 Amazon DynamoDB Manuel du développeur Utilisation des éléments : .NET Exemple : opération d'obtention par lots à l'aide du kit SDK AWS pour les API de bas niveau .NET L'exemple de code C# suivant utilise la méthode BatchGetItem pour récupérer plusieurs éléments des tables Forum et Thread. La demande BatchGetItemRequest spécifie les noms de table et la liste des clés primaires de chaque table. L'exemple traite la réponse en imprimant les éléments récupérés. Si vous avez suivi les étapes de Création de tables et chargement d'exemples de données (p. 167), ces tables ont déjà été créées avec des exemples de données. Vous pouvez aussi créer ces exemples de tables et charger les exemples de données par programmation. Pour de plus amples informations, veuillez consulter Création d'exemples de table et de chargement de données à l'aide du kit de développement (SDK) AWS pour .NET (p. 615). Pour obtenir les instructions pas à pas afin de tester l'exemple suivant, consultez Exemples de code .NET (p. 175). using using using using using System; System.Collections.Generic; Amazon.DynamoDBv2; Amazon.DynamoDBv2.Model; Amazon.Runtime; namespace com.amazonaws.codesamples { class LowLevelBatchGet { private static string table1Name = "Forum"; private static string table2Name = "Thread"; private static AmazonDynamoDBClient client = new AmazonDynamoDBClient(); static void Main(string[] args) { try { RetrieveMultipleItemsBatchGet(); Console.WriteLine("To continue, press Enter"); Console.ReadLine(); } catch (AmazonServiceException e) { Console.WriteLine(e.Message); } catch (Exception e) { Console.WriteLine(e.Message); } } private static void RetrieveMultipleItemsBatchGet() { var request = new BatchGetItemRequest { RequestItems = new Dictionary<string, KeysAndAttributes>() { { table1Name, new KeysAndAttributes { Keys = new List<Dictionary<string, AttributeValue>>() API Version 2012-08-10 272 Amazon DynamoDB Manuel du développeur Utilisation des éléments : .NET { new { { }, new { { } Dictionary<string, AttributeValue>() "Name", new AttributeValue { S = "Amazon DynamoDB" } } Dictionary<string, AttributeValue>() "Name", new AttributeValue { S = "Amazon S3" } } } } }, { table2Name, new KeysAndAttributes { Keys = new List<Dictionary<string, AttributeValue>>() { new Dictionary<string, AttributeValue>() { { "ForumName", new AttributeValue { S = "Amazon DynamoDB" } }, { "Subject", new AttributeValue { S = "DynamoDB Thread 1" } } }, new Dictionary<string, AttributeValue>() { { "ForumName", new AttributeValue { S = "Amazon DynamoDB" } }, { "Subject", new AttributeValue { S = "DynamoDB Thread 2" } } }, new Dictionary<string, AttributeValue>() { { "ForumName", new AttributeValue { S = "Amazon S3" } }, { "Subject", new AttributeValue { S = "S3 Thread 1" } } } } } } } }; BatchGetItemResponse response; do { Console.WriteLine("Making request"); response = client.BatchGetItem(request); // Check the response. var responses = response.Responses; // Attribute list in the response. foreach (var tableResponse in responses) { var tableResults = tableResponse.Value; Console.WriteLine("Items retrieved from table {0}", tableResponse.Key); foreach (var item1 in tableResults) API Version 2012-08-10 273 Amazon DynamoDB Manuel du développeur Utilisation des éléments : .NET { PrintItem(item1); } } // Any unprocessed keys? could happen if you exceed ProvisionedThroughput or some other error. Dictionary<string, KeysAndAttributes> unprocessedKeys = response.UnprocessedKeys; foreach (var unprocessedTableKeys in unprocessedKeys) { // Print table name. Console.WriteLine(unprocessedTableKeys.Key); // Print unprocessed primary keys. foreach (var key in unprocessedTableKeys.Value.Keys) { PrintItem(key); } } request.RequestItems = unprocessedKeys; } while (response.UnprocessedKeys.Count > 0); } private static void PrintItem(Dictionary<string, AttributeValue> attributeList) { foreach (KeyValuePair<string, AttributeValue> kvp in attributeList) { string attributeName = kvp.Key; AttributeValue value = kvp.Value; Console.WriteLine( attributeName + " " + (value.S == null ? "" : "S=[" + (value.N == null ? "" : "N=[" + (value.SS == null ? "" : "SS=[" value.SS.ToArray()) + "]") + (value.NS == null ? "" : "NS=[" value.NS.ToArray()) + "]") ); } value.S + "]") + value.N + "]") + + string.Join(",", + string.Join(",", Console.WriteLine("************************************************"); } } } Exemple : gestion des attributs de type Binary (binaire) à l'aide de l'API de bas niveau du kit SDK AWS pour .NET L'exemple de code C# suivant illustre la gestion d'attributs de type Binary (binaire). L'exemple ajoute un élément à la table de la réponse. L'élément inclut un attribut de type binaire (ExtendedMessage) qui stocke les données compressées. Ensuite, l'exemple récupère l'élément et imprime toutes les valeurs d'attribut. Pour illustrer ce propos, l'exemple utilise la classe GZipStream pour compresser un API Version 2012-08-10 274 Amazon DynamoDB Manuel du développeur Utilisation des éléments : .NET exemple de flux et l'assigner à l'attribut ExtendedMessage, puis le décompresse lors de l'affichage de la valeur de l'attribut. Si vous avez suivi les étapes de Création de tables et chargement d'exemples de données (p. 167), la table Reply est déjà créée. Vous pouvez aussi créer ces exemples de table par programmation. Pour de plus amples informations, veuillez consulter Création d'exemples de table et de chargement de données à l'aide du kit de développement (SDK) AWS pour .NET (p. 615). Pour obtenir les instructions pas à pas afin de tester l'exemple suivant, consultez Exemples de code .NET (p. 175). using using using using using using using System; System.Collections.Generic; System.IO; System.IO.Compression; Amazon.DynamoDBv2; Amazon.DynamoDBv2.Model; Amazon.Runtime; namespace com.amazonaws.codesamples { class LowLevelItemBinaryExample { private static string tableName = "Reply"; private static AmazonDynamoDBClient client = new AmazonDynamoDBClient(); static void Main(string[] args) { // Reply table primary key. string replyIdPartitionKey = "Amazon DynamoDB#DynamoDB Thread 1"; string replyDateTimeSortKey = Convert.ToString(DateTime.UtcNow); try { CreateItem(replyIdPartitionKey, replyDateTimeSortKey); RetrieveItem(replyIdPartitionKey, replyDateTimeSortKey); // Delete item. DeleteItem(replyIdPartitionKey, replyDateTimeSortKey); Console.WriteLine("To continue, press Enter"); Console.ReadLine(); } catch (AmazonDynamoDBException e) { Console.WriteLine(e.Message); } catch (AmazonServiceException e) { Console.WriteLine(e.Message); } catch (Exception e) { Console.WriteLine(e.Message); } } private static void CreateItem(string partitionKey, string sortKey) { MemoryStream compressedMessage = ToGzipMemoryStream("Some long extended message to compress."); var request = new PutItemRequest { TableName = tableName, Item = new Dictionary<string, AttributeValue>() { { "Id", new AttributeValue { S = partitionKey }}, API Version 2012-08-10 275 Amazon DynamoDB Manuel du développeur Utilisation des éléments : .NET { "ReplyDateTime", new AttributeValue { S = sortKey }}, { "Subject", new AttributeValue { S = "Binary type " }}, { "Message", new AttributeValue { S = "Some message about the binary type" }}, { "ExtendedMessage", new AttributeValue { B = compressedMessage }} } }; client.PutItem(request); } private static void RetrieveItem(string partitionKey, string sortKey) { var request = new GetItemRequest { TableName = tableName, Key = new Dictionary<string, AttributeValue>() { { "Id", new AttributeValue { S = partitionKey } }, { "ReplyDateTime", new AttributeValue { S = sortKey } } }, ConsistentRead = true }; var response = client.GetItem(request); // Check the response. var attributeList = response.Item; // attribute list in the response. Console.WriteLine("\nPrinting item after retrieving it ............"); PrintItem(attributeList); } private static void DeleteItem(string partitionKey, string sortKey) { var request = new DeleteItemRequest { TableName = tableName, Key = new Dictionary<string, AttributeValue>() { { "Id", new AttributeValue { S = partitionKey } }, { "ReplyDateTime", new AttributeValue { S = sortKey } } } }; var response = client.DeleteItem(request); } private static void PrintItem(Dictionary<string, AttributeValue> attributeList) { foreach (KeyValuePair<string, AttributeValue> kvp in attributeList) { string attributeName = kvp.Key; AttributeValue value = kvp.Value; Console.WriteLine( attributeName + " " + (value.S == null ? "" : "S=[" + value.S + "]") + API Version 2012-08-10 276 Amazon DynamoDB Manuel du développeur Utilisation des éléments : PHP (value.N == null ? "" : "N=[" + value.N + "]") + (value.SS == null ? "" : "SS=[" + string.Join(",", value.SS.ToArray()) + "]") + (value.NS == null ? "" : "NS=[" + string.Join(",", value.NS.ToArray()) + "]") + (value.B == null ? "" : "B=[" + FromGzipMemoryStream(value.B) + "]") ); } Console.WriteLine("************************************************"); } private static MemoryStream ToGzipMemoryStream(string value) { MemoryStream output = new MemoryStream(); using (GZipStream zipStream = new GZipStream(output, CompressionMode.Compress, true)) using (StreamWriter writer = new StreamWriter(zipStream)) { writer.Write(value); } return output; } private static string FromGzipMemoryStream(MemoryStream stream) { using (GZipStream zipStream = new GZipStream(stream, CompressionMode.Decompress)) using (StreamReader reader = new StreamReader(zipStream)) { return reader.ReadToEnd(); } } } } Utilisation des éléments : PHP Rubriques • Positionnement d'un élément (p. 278) • Obtention d'un élément (p. 279) • Ecriture par lots : insertion et suppression de plusieurs éléments (p. 280) • Batch Get : obtention de plusieurs éléments (p. 281) • Mise à jour d'un élément (p. 283) • Compteur atomique (p. 284) • Suppression d'un élément (p. 285) • Exemple : opérations CRUD à l'aide du SDK AWS pour les API de bas niveau PHP (p. 286) • Exemple : Opérations de traitement par lots à l'aide du kit SDK AWS pour PHP (p. 289) Vous pouvez utiliser le kit SDK AWS pour PHP afin d'exécuter des opérations CRUD classiques sur un élément d'une table. Les opérations SDK sont mappées aux actions de bas niveau sous-jacentes API Version 2012-08-10 277 Amazon DynamoDB Manuel du développeur Utilisation des éléments : PHP exposées dans DynamoDB. Pour de plus amples informations, veuillez consulter Exemples de Code PHP (p. 177). Voici les étapes courantes que vous suivez pour effectuer les opérations CRUD à l'aide du SDK AWS pour PHP. 1. Créer une instance du client DynamoDB. 2. Fournir les paramètres d'une opération DynamoDB, y compris les paramètres facultatifs. 3. Charger la réponse à partir de DynamoDB dans une variable locale pour votre application. Positionnement d'un élément La fonction PHP putItem charge un élément sur une table. Si l'élément existe, il remplace la totalité de l'élément. Au lieu de remplacer l'élément entier, si vous souhaitez mettre à jour uniquement des attributs spécifiques, vous pouvez utiliser la fonction updateItem. Pour de plus amples informations, veuillez consulter Mise à jour d'un élément (p. 283). L'exemple de code PHP suivant illustre les tâches précédentes. Le code charge un élément sur la table ProductCatalog. Note Cet exemple de code suppose que vous ayez déjà chargé des données dans DynamoDB pour votre compte en suivant les instructions de la section Création de tables et chargement d'exemples de données (p. 167). Sinon, vous pouvez charger les données en utilisant les instructions de la rubrique Création d'exemples de table et de chargement de données à l'aide du kit de développement (SDK) AWS pour PHP (p. 624). Pour obtenir les instructions pas à pas afin d'exécuter l'exemple suivant, consultez Exemples de Code PHP (p. 177). require 'vendor/autoload.php'; $sdk = new Aws\Sdk([ 'region' => 'us-west-2', 'version' => 'latest' ]); $dynamodb = $sdk->createDynamoDb(); $response = $dynamodb->putItem([ 'TableName' => 'ProductCatalog', 'Item' => [ 'Id' => ['N' => '104' ], // Primary Key 'Title' => ['S' => 'Book 104 Title' ], 'ISBN' => ['S' => '111-1111111111' ], 'Price' => ['N' => '25' ], 'Authors' => ['SS' => ['Author1', 'Author2'] ] ] ]); print_r($response); Spécification de paramètres facultatifs En même temps que les paramètres requis, vous pouvez également spécifier les paramètres facultatifs de la fonction putItem. Par exemple, l'extrait de code PHP suivant utilise un paramètre facultatif pour API Version 2012-08-10 278 Amazon DynamoDB Manuel du développeur Utilisation des éléments : PHP spécifier une condition pour le chargement de l'élément. Si la condition que vous spécifiez n'est pas remplie, le kit SDK AWS pour PHP lève une exception ConditionalCheckFailedException. Le code spécifie les paramètres facultatifs suivants pourputItem : • Un paramètre ConditionExpression qui définit les conditions de la demande, telles que la condition que l'élément existant ne soit remplacé que s'il comporte un attribut ISBN égal à une valeur spécifique. • La valeur ALL_OLD du paramètre ReturnValue qui fournit toutes les valeurs d'attribut pour l'élément avant l'opération PutItem. Dans ce cas, l'élément le plus ancien n'a que deux auteurs et les nouvelles valeurs de l'élément incluent trois auteurs. $tableName = 'ProductCatalog'; $result = $dynamodb->putItem ([ 'TableName' => $tableName, 'Item' => [ 'Id' => [ 'N' => '104' ], // Primary Key 'Title' => [ 'S' => 'Book 104 Title' ], 'ISBN' => [ 'S' => '333-3333333333' ], 'Price' => [ 'N' => '2000' ], 'Authors' => [ 'SS' => [ 'Author1', 'Author2', 'Author3' ] ] ], 'ExpressionAttributeNames' => [ '#I' => 'ISBN'] , 'ExpressionAttributeValues' => [ ':val1' => ['S' => '333-3333333333']] , 'ConditionExpression' => '#I = :val1', 'ReturnValues' => 'ALL_OLD' ]); print_r ($result); Pour plus d'informations, consultez PutItem. Obtention d'un élément La fonction getItem récupère un seul élément. Pour récupérer plusieurs éléments, vous pouvez utiliser la méthode batchGetItem (voir Batch Get : obtention de plusieurs éléments (p. 281)). L'exemple de code PHP suivant illustre les étapes précédentes. Le code obtient l'élément qui possède la clé de partition spécifiée. Note Cet exemple de code suppose que vous ayez déjà chargé des données dans DynamoDB pour votre compte en suivant les instructions de la section Création de tables et chargement d'exemples de données (p. 167). Sinon, vous pouvez charger les données en utilisant les instructions de la rubrique Création d'exemples de table et de chargement de données à l'aide du kit de développement (SDK) AWS pour PHP (p. 624). Pour obtenir les instructions pas à pas afin d'exécuter l'exemple suivant, consultez Exemples de Code PHP (p. 177). API Version 2012-08-10 279 Amazon DynamoDB Manuel du développeur Utilisation des éléments : PHP $response = $dynamodb->getItem([ 'TableName' => 'ProductCatalog', 'Key' => [ 'Id' => [ 'N' => '104' ] ] ]); print_r ($response['Item']); Spécification de paramètres facultatifs En même temps que les paramètres requis, vous pouvez également spécifier des paramètres facultatifs pour la fonction getItem. Par exemple, l'extrait de code PHP suivant utilise une méthode facultative pour récupérer uniquement une liste spécifique d'attributs et demande une valeur de retour à cohérence forte. Le code spécifie les paramètres facultatifs suivants : • Une liste spécifique de noms d'attributs, dont Id et Authors. • Une valeur booléenne qui demande une valeur en lecture à cohérence forte. Les résultats en lecture sont par défaut cohérents à terme. Vous pouvez demander à ce qu'ils soient à cohérence forte. Pour en savoir plus sur la cohérence en lecture, consultez Cohérence en lecture (p. 16). $response = $dynamodb->getItem([ 'TableName' => 'ProductCatalog', 'Key' => [ 'Id' => ['N' => '104'], ], 'ProjectionExpression' => 'Id, Authors', 'ConsistentRead' => true ]); Pour plus d'informations, consultez GetItem. Ecriture par lots : insertion et suppression de plusieurs éléments La fonction batchWriteItem du kit SDK AWS pour PHP vous permet d'insérer ou de supprimer plusieurs éléments de différentes tables avec une seule demande. L'extrait de code PHP suivant effectue les opérations d'écriture suivantes : • Insérer un élément dans la table Forum. • Insérer et supprimer un élément dans la table Thread. Pour plus d'informations, consultez BatchWriteItem. Note Cet exemple de code suppose que vous ayez déjà chargé des données dans DynamoDB pour votre compte en suivant les instructions de la section Création de tables et chargement d'exemples de données (p. 167). Sinon, vous pouvez charger les données en utilisant les instructions de la rubrique Création d'exemples de table et de chargement de données à l'aide du kit de développement (SDK) AWS pour PHP (p. 624). Pour obtenir les instructions pas à pas afin d'exécuter l'exemple suivant, consultez Exemples de Code PHP (p. 177). API Version 2012-08-10 280 Amazon DynamoDB Manuel du développeur Utilisation des éléments : PHP $tableNameOne = 'Forum'; $tableNameTwo = 'Thread'; $response = $dynamodb->batchWriteItem([ 'RequestItems' => [ $tableNameOne => [ [ 'PutRequest' => [ 'Item' => [ 'Name' => ['S' => 'Amazon S3 Forum'], 'Threads' => ['N' => '0'] ]] ] ], $tableNameTwo => [ [ 'PutRequest' => [ 'Item' => [ 'ForumName' => ['S' => 'Amazon S3 Forum'], 'Subject' => ['S' => 'My sample question'], 'Message'=> ['S' => 'Message Text.'], 'KeywordTags'=>['SS' => ['Amazon S3', 'Bucket']] ]] ], [ 'DeleteRequest' => [ 'Key' => [ 'ForumName' =>['S' => 'Some partition key value'], 'Subject' => ['S' => 'Some sort key value'] ]] ] ] ] ]); print_r ($response['Item']); Batch Get : obtention de plusieurs éléments La fonction batchGetItem du kit SDK AWS pour PHP vous permet de récupérer différents éléments d'une ou de plusieurs tables. Pour récupérer un seul élément, vous pouvez utiliser la méthode getItem. L'extrait de code PHP suivant extrait deux éléments de la table Forum et trois éléments de la table Thread. Note Cet exemple de code suppose que vous ayez déjà chargé des données dans DynamoDB pour votre compte en suivant les instructions de la section Création de tables et chargement d'exemples de données (p. 167). Sinon, vous pouvez charger les données en utilisant les instructions de la rubrique Création d'exemples de table et de chargement de données à l'aide du kit de développement (SDK) AWS pour PHP (p. 624). Pour obtenir les instructions pas à pas afin d'exécuter l'exemple suivant, consultez Exemples de Code PHP (p. 177). API Version 2012-08-10 281 Amazon DynamoDB Manuel du développeur Utilisation des éléments : PHP date_default_timezone_set('UTC'); $sevenDaysAgo = date('Y-m-d H:i:s', strtotime('-7 days')); $twentyOneDaysAgo = date('Y-m-d H:i:s', strtotime('-21 days')); $response = $dynamodb->batchGetItem([ 'RequestItems' => [ 'Forum' => [ 'Keys' => [ [ 'Name' => [ 'S' => 'DynamoDB' ] ] ] ], 'Reply' => [ 'Keys' => [ [ 'Id' => [ 'S' => 'DynamoDB#DynamoDB Thread 2'], 'ReplyDateTime' => [ 'S' => $sevenDaysAgo], ], [ 'Id' => [ 'S' => 'DynamoDB#DynamoDB Thread 2'], 'ReplyDateTime' => [ 'S' => $twentyOneDaysAgo], ], ] ] ] ]); print_r($response['Responses']); Spécification de paramètres facultatifs En même temps que les paramètres requis, vous pouvez également spécifier des paramètres facultatifs pour la fonction batchGetItem. Par exemple, vous pouvez spécifier une liste d'attributs pour récupérer, comme illustré dans l'extrait de code PHP suivant. Le code extrait deux éléments de la table Forum et utilise le paramètre ProjectionExpression pour récupérer le nombre de threads de chaque table : $response = $dynamodb->batchGetItem([ 'RequestItems' => [ 'Forum' => [ 'Keys' => [ [ 'Name' => [ 'S' => 'Amazon S3' ] ], [ 'Name' => [ 'S' => 'DynamoDB' ] ] ], 'ProjectionExpression' => 'Threads' ], ] ]); print_r($response); Pour plus d'informations, consultez BatchGetItem. API Version 2012-08-10 282 Amazon DynamoDB Manuel du développeur Utilisation des éléments : PHP Mise à jour d'un élément Utilisez la fonction updateItem pour mettre à jour les valeurs d'attribut existantes, ajouter de nouveaux attributs à la collection existante ou supprimer des attributs de la collection existante. La fonction updateItem utilise les directives suivantes : • Si un élément n'existe pas, la fonction updateItem ajoute un nouvel élément à l'aide de la clé primaire spécifiée dans l'entrée. • Si un élément existe, la fonction updateItem applique les mises à jour comme suit : • Remplace les valeurs d'attribut existantes par les valeurs de la mise à jour. • Si l'attribut que vous fournissez en entrée n'existe pas, un nouvel attribut est ajouté à l'élément. • Si vous utilisez ADD pour Action, vous pouvez ajouter des valeurs à un ensemble existant (String Set ou Number Set) ou mathématiquement ajouter (utilisez un nombre positif) ou soustraire (utilisez un nombre négatif) à partir de la valeur d'attribut numérique existante. Note La fonction putItem (Positionnement d'un élément (p. 278)) met également à jour les éléments. Par exemple, si vous utilisez putItem pour charger un élément et que la clé primaire existe, l'opération remplace la totalité de l'élément. S'il existe des attributs dans l'élément existant et que ceux-ci ne sont pas spécifiés en entrée, l'opération putItem les supprime. Cependant, updateItem ne met à jour que les attributs spécifiés en entrée, de telle sorte que tous les autres attributs existants de cet élément demeurent inchangés. L'extrait de code PHP suivant met à jour un élément « book » de la table ProductCatalog. Il ajoute un nouvel auteur à l'ensemble Authors et supprime l'attribut ISBN existant. Il permet également de réduire le prix d'un niveau. Note Cet exemple de code suppose que vous ayez déjà chargé des données dans DynamoDB pour votre compte en suivant les instructions de la section Création de tables et chargement d'exemples de données (p. 167). Sinon, vous pouvez charger les données en utilisant les instructions de la rubrique Création d'exemples de table et de chargement de données à l'aide du kit de développement (SDK) AWS pour PHP (p. 624). Pour obtenir les instructions pas à pas afin d'exécuter l'exemple suivant, consultez Exemples de Code PHP (p. 177). $response = $dynamodb->updateItem([ 'TableName' => 'ProductCatalog', 'Key' => [ 'Id' => [ 'N' => '201' ] ], 'ExpressionAttributeValues' => [ ':val1' => [ 'S' => 'Author YY', 'S' => 'Author ZZ'], ':val2' => ['N' => '1'] ] , 'UpdateExpression' => 'set Authors = :val1, Price = Price - :val2 remove ISBN' ]); API Version 2012-08-10 283 Amazon DynamoDB Manuel du développeur Utilisation des éléments : PHP print_r($response); Spécification de paramètres facultatifs En même temps que les paramètres requis, vous pouvez aussi spécifier des paramètres facultatifs pour la fonction updateItem, y compris une valeur prévue qu'un attribut doit avoir si la mise à jour doit se produire. Si la condition que vous spécifiez n'est pas remplie, le kit SDK AWS pour PHP lève une exception ConditionalCheckFailedException. Par exemple, l'extrait de code PHP suivant met à jour de façon conditionnelle le prix d'un élément « book » avec la valeur 25. Il spécifie les paramètres facultatifs suivants : • Un paramètre ConditionExpression qui définit la condition selon laquelle le prix doit être mis à jour uniquement si le prix existant est 20.00. • Une valeur ALL_NEW pour le paramètre ReturnValues qui spécifie que la réponse doit inclure toutes les valeurs d'attribut de l'élément après la mise à jour. $response = $dynamodb->updateItem([ 'TableName' => 'ProductCatalog', 'Key' => [ 'Id' => [ 'N' => '201' ] ], 'ExpressionAttributeValues' => [ ':val1' => ['N' => '22'], ':val2' => ['N' => '20'] ] , 'UpdateExpression' => 'set Price = :val1', 'ConditionExpression' => 'Price = :val2', 'ReturnValues' => 'ALL_NEW' ]); print_r($response); Pour plus d'informations, voir UpdateItem>. Compteur atomique Vous pouvez utiliser updateItem pour implémenter un compteur atomique, où vous incrémentez ou décrémentez la valeur d'un attribut existant sans interférer avec d'autres demandes d'écriture. Pour mettre à jour un compteur atomique, utilisez updateItem avec un UpdateExpression approprié. L'extrait de code suivant illustre cette action, en incrémentant l'attribut Quantity d'une unité. $response = $dynamodb->updateItem([ 'TableName' => 'ProductCatalog', 'Key' => [ 'Id' => ['N' => '201'] ], 'ExpressionAttributeValues' => [ ':val1' => ['N' => '1'] ] , 'UpdateExpression' => 'set Quantity = Quantity + :val1', 'ReturnValues' => 'ALL_NEW' ]); API Version 2012-08-10 284 Amazon DynamoDB Manuel du développeur Utilisation des éléments : PHP print_r($response['Attributes']); Suppression d'un élément La fonction deleteItem supprime un élément d'une table. Note Cet exemple de code suppose que vous ayez déjà chargé des données dans DynamoDB pour votre compte en suivant les instructions de la section Création de tables et chargement d'exemples de données (p. 167). Sinon, vous pouvez charger les données en utilisant les instructions de la rubrique Création d'exemples de table et de chargement de données à l'aide du kit de développement (SDK) AWS pour PHP (p. 624). Pour obtenir les instructions pas à pas afin d'exécuter l'exemple suivant, consultez Exemples de Code PHP (p. 177). $response = $dynamodb->deleteItem([ 'TableName' => 'ProductCatalog', 'Key' => [ 'Id' => [ 'N' => '101' ] ] ]); print_r($response); Spécification de paramètres facultatifs En même temps que les paramètres requis, vous pouvez également spécifier des paramètres facultatifs pour la fonction deleteItem. Par exemple, l'extrait de code PHP suivant spécifie les paramètres facultatifs suivants : • Un paramètre Expected spécifiant que l'élément Book avec la valeur d'Id « 103 » de la table ProductCatalog ne doit être supprimé que si le livre n'est plus publié. Plus précisément, le livre doit être supprimé si l'attribut InPublication a la valeur false. • Une valeur d'énumération RETURN_ALL_OLD pour le paramètre ReturnValues demande que la réponse inclue l'élément qui a été supprimé et ses attributs avant la suppression. $$tableName = 'ProductCatalog'; $response = $dynamodb->deleteItem ([ 'TableName' => $tableName, 'Key' => [ 'Id' => [ 'N' => '103' ] ], 'ExpressionAttributeValues' => [ ':val1' => ['BOOL' => false] ], 'ConditionExpression' => 'InPublication = :val1', 'ReturnValues' => 'ALL_OLD' ]); API Version 2012-08-10 285 Amazon DynamoDB Manuel du développeur Utilisation des éléments : PHP print_r($response); Pour plus d'informations, voir DeleteItem. Exemple : opérations CRUD à l'aide du SDK AWS pour les API de bas niveau PHP L'exemple de code PHP suivant illustre les opérations CRUD (créer, lire, mettre à jour et supprimer) sur un élément. L'exemple crée un élément, le récupère, exécute plusieurs mises à jour et supprime finalement l'élément. Note Pour obtenir les instructions pas à pas sur le test de l'exemple de code suivant, consultez Exemples de Code PHP (p. 177). <?php require 'vendor/autoload.php'; date_default_timezone_set('UTC'); use Aws\DynamoDb\Exception\DynamoDbException; $sdk = new Aws\Sdk([ 'region' => 'us-west-2', 'version' => 'latest' ]); $dynamodb = $sdk->createDynamoDb(); $tableName = 'ProductCatalog'; // ################################################################### // Adding data to the table echo "# Adding data to table $tableName...\n"; $response = $dynamodb->putItem([ 'TableName' => $tableName, 'Item' => [ 'Id' => ['N' => '120'], 'Title' => ['S' => 'Book 120 Title'], 'ISBN' => ['S' => '120-1111111111'], 'Authors' => ['SS' => ['Author12', 'Author22']], 'Price' => ['N' => '20'], 'Category' => ['S' => 'Book'], 'Dimensions' => ['S' => '8.5x11.0x.75'], 'InPublication' => ['BOOL' => false], ], 'ReturnConsumedCapacity' => 'TOTAL' ]); echo "Consumed capacity: " . $response ["ConsumedCapacity"] ["CapacityUnits"] . "\n"; API Version 2012-08-10 286 Amazon DynamoDB Manuel du développeur Utilisation des éléments : PHP $response = $dynamodb->putItem([ 'TableName' => $tableName, 'Item' => [ 'Id' => ['N' => '121'], 'Title' => ['S' => 'Book 121 Title'], 'ISBN' => ['S' => '121-1111111111'], 'Authors' => ['SS' => ['Author21', 'Author22']], 'Price' => ['N' => '20'], 'Category' => ['S' => 'Book'], 'Dimensions' => ['S' => '8.5x11.0x.75'], 'InPublication' => ['BOOL' => true], ], 'ReturnConsumedCapacity' => 'TOTAL' ]); echo "Consumed capacity: " . $response ["ConsumedCapacity"] ["CapacityUnits"] . "\n"; // ################################################################### // Getting an item from the table echo "\n\n"; echo "# Getting an item from table $tableName...\n"; $response = $dynamodb->getItem ([ 'TableName' => $tableName, 'ConsistentRead' => true, 'Key' => [ 'Id' => [ 'N' => '120' ] ], 'ProjectionExpression' => 'Id, ISBN, Title, Authors' ] ); print_r ( $response ['Item'] ); // ################################################################### // Updating item attributes echo "\n\n"; echo "# Updating an item and returning the whole new item in table $tableName...\n"; $response = $dynamodb->updateItem ( [ 'TableName' => $tableName, 'Key' => [ 'Id' => [ 'N' => '120' //was 121 ] ], 'ExpressionAttributeNames' => [ '#NA' => 'NewAttribute', '#A' => 'Authors' ], 'ExpressionAttributeValues' => [ ':val1' => ['S' => 'Some Value'], ':val2' => ['SS' => ['Author YY','Author ZZ']] ] , 'UpdateExpression' => 'set #NA = :val1, #A = :val2', API Version 2012-08-10 287 Amazon DynamoDB Manuel du développeur Utilisation des éléments : PHP 'ReturnValues' => 'ALL_NEW' ]); print_r ( $response ['Attributes'] ); // ################################################################### // Conditionally updating the Price attribute, only if it has not changed. echo "\n\n"; echo "# Updating an item attribute only if it has not changed in table $tableName...\n"; $response = $dynamodb->updateItem ( [ 'TableName' => $tableName, 'Key' => [ 'Id' => [ 'N' => '121' ] ], 'ExpressionAttributeNames' => [ '#P' => 'Price' ], 'ExpressionAttributeValues' => [ ':val1' => ['N' => '25'], ':val2' => ['N' => '20'], ], 'UpdateExpression' => 'set #P = :val1', 'ConditionExpression' => '#P = :val2', 'ReturnValues' => 'ALL_NEW' ]); print_r ( $response ['Attributes'] ); // ################################################################### // Deleting an item echo "\n\n"; echo "# Deleting an item and returning its previous values from in table $tableName...\n"; $response = $dynamodb->deleteItem ( [ 'TableName' => $tableName, 'Key' => [ 'Id' => [ 'N' => '121' ] ], 'ReturnValues' => 'ALL_OLD' ]); print_r ( $response ['Attributes']); ?> API Version 2012-08-10 288 Amazon DynamoDB Manuel du développeur Utilisation des éléments : PHP Exemple : Opérations de traitement par lots à l'aide du kit SDK AWS pour PHP Exemple : Opération d'écriture par lots à l'aide du SDK AWS pour PHP L'exemple de code PHP suivant exécute les tâches suivantes : • Insère un élément dans la table Forum. • Insère et supprime un élément dans la table Thread. Pour en savoir plus sur le traitement par lots des opérations d'écriture, consultez Ecriture par lots : insertion et suppression de plusieurs éléments (p. 280). Cet exemple de code présume que vous avez suivi les étapes de Création de tables et chargement d'exemples de données (p. 167) et créé les tables Forum et Thread. Sinon, vous pouvez charger les données par programmation en utilisant les instructions de la rubrique Création d'exemples de table et de chargement de données à l'aide du kit de développement (SDK) AWS pour PHP (p. 624). Note Pour obtenir les instructions pas à pas sur le test de l'exemple de code suivant, consultez Exemples de Code PHP (p. 177). <?php require 'vendor/autoload.php'; date_default_timezone_set('UTC'); use Aws\DynamoDb\Exception\DynamoDbException; $sdk = new Aws\Sdk([ 'region' => 'us-west-2', 'version' => 'latest' ]); $dynamodb = $sdk->createDynamoDb(); $tableNameOne = 'Forum'; $tableNameTwo = 'Thread'; $response = $dynamodb->batchWriteItem([ 'RequestItems' => [ $tableNameOne => [ [ 'PutRequest' => [ 'Item' => [ 'Name' => ['S' => 'Amazon S3 Forum'], 'Threads' => ['N' => '0'] ]] ] ], $tableNameTwo => [ [ 'PutRequest' => [ 'Item' => [ API Version 2012-08-10 289 Amazon DynamoDB Manuel du développeur Utilisation des requêtes et des analyses 'ForumName' => ['S' => 'Amazon S3 Forum'], 'Subject' => ['S' => 'My sample question'], 'Message'=> ['S' => 'Message Text.'], 'KeywordTags'=>['SS' => ['Amazon S3', 'Bucket']] ]] ], [ 'DeleteRequest' => [ 'Key' => [ 'ForumName' =>['S' => 'Some partition key value'], 'Subject' => ['S' => 'Some sort key value'] ]] ] ] ] ]); print_r($response); ?> Utilisation des requêtes et des analyses Rubriques • Interrogation (p. 291) • Analyser (p. 292) • Filtrage des résultats d'une opération Query ou Scan (p. 292) • Unités de capacité consommées par les opérations Query et Scan (p. 293) • Pagination des résultats (p. 293) • Limite (p. 294) • Comptabilisation des éléments d'une réponse (p. 294) • Cohérence en lecture (p. 295) • Performances des opérations Query et Scan (p. 295) • Analyse en parallèle (p. 296) • Interrogation dans DynamoDB (p. 298) • Analyse dans DynamoDB (p. 314) En plus de l'utilisation des clés primaires pour accéder aux éléments, Amazon DynamoDB propose également deux opérations pour explorer les données : Query et Scan. Tip Vous pouvez interroger ou analyser un index secondaire de la même manière que vous interrogez une table. Pour ce faire, vous devez fournir IndexName et TableName en tant que paramètres de Query ou Scan. Pour de plus amples informations, veuillez consulter Amélioration de l'accès aux données avec les index secondaires (p. 337). Pour connaître les bonnes pratiques, consultez Consignes pour interrogation et analyse (p. 588). API Version 2012-08-10 290 Amazon DynamoDB Manuel du développeur Interrogation Interrogation Une opération Query recherche les éléments d'une table ou d'un index secondaire à l'aide des valeurs d'attribut de clé primaire uniquement. Vous devez fournir un nom de clé de partition et une valeur à rechercher. Vous pouvez le cas échéant fournir un nom de clé de tri et une valeur, et utiliser un opérateur de comparaison pour affiner les résultats de recherche. Par défaut, une opération Query retourne tous les attributs de données des éléments avec les clés primaires spécifiées ; cependant, vous pouvez utiliser le paramètre ProjectionExpression de telle sorte que l'opération Query retourne uniquement certains des attributs, plutôt que leur totalité. Dans une opération Query, vous utilisez le paramètre KeyConditionExpression afin de déterminer les éléments à lire depuis la table ou l'index. Vous devez spécifier le nom de la clé de partition et la valeur comme condition d'égalité. Le cas échéant, vous pouvez fournir une deuxième condition pour la clé de tri (si elle est présente). La condition de la clé de tri doit être l'un des opérateurs de comparaison suivants : • a = b : true si l'attribut a est égal à la valeur b • a < b : true si a est inférieur à b • a <= b : true si a est inférieur ou égal à b • a > b : true si a est supérieur à b • a >= b : true si a est supérieur ou égal à b • a BETWEEN b AND c : true si a est supérieur ou égal à b, et inférieur ou égal à c. La fonction suivante est également prise en charge : • begins_with (a, substr) : true si la valeur d'attribut a commence par une sous-chaîne particulière. Voici quelques exemples d'expressions de condition de clé. Notez que ces expressions utilisent des espaces réservés (tels que :name et :subj) au lieu de valeurs réelles. Pour plus d'informations, consultez Expression de noms d'attributs (p. 215) et Valeurs d'attributs d'expressions (p. 217). • Interrogez la table Thread pour un ForumName (clé de partition) particulier. Tous les éléments ayant cette valeur ForumName sont lus par la requête, car la clé de tri (Subject) n'est pas incluse dans KeyConditionExpression. ForumName = :name • Interrogez la table Thread en quête d'un ForumName (clé de partition) particulier, mais cette fois ne retournez que les éléments avec un Subject (clé de tri) donné. Forum = :name and Subject = :subj • Interrogez la table Reply en quête d'un Id (clé de partition) particulier, mais retournez uniquement les éléments dont ReplyDateTime (clé de tri) commence par certains caractères. Id = :id and begins_with(ReplyDateTime, :dt) Vous pouvez utiliser n'importe quel nom dans une expression de condition de clé, sous réserve que le premier caractère soit a-z ou A-Z et que le deuxième caractère (s'il existe) soit a-z, A-Z ou 0-9. En outre, le nom d'attribut ne doit pas être un mot réservé DynamoDB. (Pour en obtenir la liste complète, consultez Mots réservés dans DynamoDB (p. 676).) Si un nom d'attribut ne répond pas à ces exigences, vous devez définir un nom d'attribut d'expression comme espace réservé. Pour de plus amples informations, veuillez consulter Expression de noms d'attributs (p. 215). Pour les éléments avec une valeur de clé de partition donnée, DynamoDB stocke ces éléments proches les uns des autres, triés par valeur de clé de tri. Dans une opération Query, DynamoDB API Version 2012-08-10 291 Amazon DynamoDB Manuel du développeur Analyser récupère les éléments en ordre trié, puis traite les éléments à l'aide d'une KeyConditionExpression et d'une FilterExpression éventuellement présente. Alors seulement les résultats de Query sont renvoyés au client. Une opération Query retourne toujours un ensemble de résultats. Si aucun élément correspondant n'est trouvé, le jeu de résultats est vide. Les résultats de Query sont toujours triés sur la valeur de la clé de tri. Si le type de données de la clé de tri est Number, les résultats sont retournés dans l'ordre numérique ; sinon, les résultats sont retournés dans l'ordre des octets UTF-8. Par défaut, l'ordre de tri est croissant. Pour inverser l'ordre, définissez le paramètre ScanIndexForward sur false. Une seule opération Query ou Scan peut extraire un maximum de 1 MB de données. Cette limite s'applique avant qu'une FilterExpression ne soit appliquée aux résultats. Si LastEvaluatedKey est présent dans la réponse et n'a pas la valeur null, vous devez paginer le jeu de résultats (voir Pagination des résultats (p. 293)). Analyser Une opération Scan lit tous les éléments d'une table ou d'un index secondaire. Par défaut, une opération Scan retourne tous les attributs de données pour chaque élément de la table ou de l'index. Vous pouvez utiliser le paramètre ProjectionExpression de telle sorte que Scan retourne uniquement certains des attributs, plutôt que leur totalité. Scan retourne toujours un jeu de résultats. Si aucun élément correspondant n'est trouvé, le jeu de résultats est vide. Une seule demande Scan peut extraire un maximum de 1 MB de données ; DynamoDB peut le cas échéant appliquer une expression de filtre à ces données, en affinant les résultats avant qu'ils ne soient renvoyés à l'utilisateur. (Pour plus d'informations sur les filtres, consultez Filtrage des résultats d'une opération Query ou Scan (p. 292).) Filtrage des résultats d'une opération Query ou Scan Avec une opération Query ou Scan, vous pouvez fournir une expression de filtre facultative pour affiner les résultats qui vous sont retournés. Une expression de filtre vous permet d'appliquer des conditions aux données une fois qu'elles ont été interrogées ou analysées, mais avant qu'elles ne vous soient retournées. Seuls les éléments qui satisfont vos conditions sont retournés. Voici quelques exemples d'expressions de filtre. Notez que ces expressions utilisent des espaces réservés (tels que :num et :name) au lieu de valeurs réelles. Pour plus d'informations, consultez Expression de noms d'attributs (p. 215) et Valeurs d'attributs d'expressions (p. 217). • Interrogez la table Thread en quête d'un ForumName (clé de partition) particulier et d'un Subject (clé de tri). Parmi les éléments trouvés, ne renvoyez que les threads de discussion les plus courants : par exemple, les threads ayant plus qu'un certain nombre de Views. #V > :num Notez que Views étant un mot réservé en DynamoDB (voir Mots réservés dans DynamoDB (p. 676)), nous utilisons un nom d'attribut d'expression comme substitution. • Analysez la table Thread et retournez uniquement les derniers éléments publiés par un utilisateur particulier. LastPostedBy = :name API Version 2012-08-10 292 Amazon DynamoDB Manuel du développeur Unités de capacité consommées par les opérations Query et Scan Note La syntaxe de FilterExpression est identique à celle de ConditionExpression. En outre, FilterExpression utilise les mêmes comparateurs, fonctions et opérateurs logiques que ConditionExpression. Pour les opérations Query, vous ne pouvez pas définir de FilterExpression basée sur une clé de partition ou une clé de tri. Cela ne s'applique pas aux opérations Sort. Pour plus d'informations sur la syntaxe ConditionExpression, consultez Référence des expressions de condition (p. 219). Une seule opération Query ou Scan peut extraire un maximum de 1 MB de données. Cette limite s'applique avant qu'une expression de filtre ne soit appliquée aux résultats. Unités de capacité consommées par les opérations Query et Scan Lorsque vous créez une table, vous spécifiez vos exigences en matière d'unités de capacité de lecture et d'écriture. Si vous ajoutez un index secondaire global à la table, vous devez également fournir les exigences de débit pour cet index. Vous pouvez utiliser les opérations Query et Scan sur les index secondaires de la même manière que vous utilisez ces opérations sur une table. Si vous utilisez Query ou Scan sur un index secondaire local, les unités de capacité sont consommées à partir du débit alloué de la table. Cependant, si vous effectuez ces opérations sur un index secondaire global, les unités de capacité sont consommées à partir du débit alloué de l'index. Cela est dû au fait qu'un index secondaire global a ses propres paramètres de débit alloué, distincts de ceux de la table. Pour plus d'informations sur la façon dont DynamoDB calcule les unités de capacité utilisées par votre opération, consultez Calcul des unités de capacité (p. 182). Note Pour les opérations Query et Scan, DynamoDB calcule la quantité de débit alloué consommée en fonction de la taille d'élément, pas de la quantité de données retournées à une application. Pour cette raison, le nombre d'unités de capacité consommées sera le même que vous demandiez tous les attributs (comportement par défaut) ou seulement certains d'entre eux à l'aide du paramètre ProjectionExpression. Le nombre d'unités de capacité consommées sera également le même que vous spécifiez ou pas une opération FilterExpression. Pagination des résultats DynamoDB pagine les résultats des opérations Query et Scan. Avec la pagination, les résultats Query et Scan sont répartis en morceaux distincts ; une application peut traiter la première page des résultats, puis la deuxième page, et ainsi de suite. Les données renvoyées par une opération Query ou Scan sont limitées à 1 MB, cela signifie que si le jeu de résultats dépasse 1 MB de données, vous devrez exécuter une autre opération Query ou Scan pour récupérer la taille 1 MB suivante de données. Si vous interrogez ou analysez des attributs spécifiques correspondant à des valeurs dont le total est supérieur à 1 MB de données, vous devez exécuter une autre demande Query ou Scan demander la taille 1 MB suivante de données. Pour ce faire, prenez la valeur LastEvaluatedKey de la demande précédente et utilisez cette valeur comme ExclusiveStartKey dans la demande suivante. Cette API Version 2012-08-10 293 Amazon DynamoDB Manuel du développeur Limite approche vous permettra progressivement d'interroger ou d'analyser de nouvelles données par incréments de 1 MB. Lorsque la totalité du résultat défini à partir d'une opération Query ou Scan a été traitée, LastEvaluatedKey a la valeur null. Cela indique que le jeu de résultats est complet (autrement dit, que l'opération a traité la « dernière page » de données). Si LastEvaluatedKey a une valeur autre que null, cela ne signifie pas nécessairement qu'il y a plus de données dans le jeu de résultats. Le seul moyen de savoir que vous avez atteint la fin du jeu de résultats est lorsque LastEvaluatedKey a la valeur null. Limite Les API DynamoDB Query et Scan permettent qu'une valeur Limit restreigne la taille des résultats. Dans une demande, définissez le paramètre Limit sur le nombre d'éléments que vous voulez que DynamoDB traite avant de retourner les résultats. Dans une réponse, DynamoDB retourne tous les résultats correspondants au sein de la portée de la valeur Limit. Par exemple, si vous émettez une demande Query ou Scan avec une valeur Limit de 6 et sans une expression de filtre, DynamoDB retourne les six premiers éléments de la table qui correspondent aux conditions de clé spécifiées dans la demande (ou juste les six premiers éléments dans le cas d'une opération Scan sans filtre). Si vous spécifiez également une valeur FilterExpression, DynamoDB retourne les éléments des six premiers qui correspondent aussi aux exigences du filtre (le nombre de résultats retournés sera inférieur ou égal à 6). Pour une opération Query ou Scan, DynamoDB peut retourner une valeur LastEvaluatedKey si l'opération n'a pas retourné tous les éléments correspondants de la table. Pour obtenir le nombre total d'éléments qui correspondent, prenez la valeur LastEvaluatedKey de la demande précédente et utilisez-la comme valeur ExclusiveStartKey dans la demande suivante. Répétez cette opération jusqu'à ce que DynamoDB ne retourne plus de valeur LastEvaluatedKey. Comptabilisation des éléments d'une réponse Outre les éléments qui correspondent à vos critères, la réponse d'une opération Query ou Scan contient les éléments suivants : • ScannedCount : le nombre d'éléments interrogés ou analysés, avant qu'une expression de filtre ne soit appliquée aux résultats. • Count : le nombre d'éléments retournés dans la réponse. Si vous n'utilisez pas une FilterExpression, ScannedCount et Count ont la même valeur. Supposons que vous ayez une table nommée TestTable avec 1 000 éléments et que la taille de chaque élément soit exactement de 250 octets. Si vous devez exécuter une opération Scan sur cette table (sans filtre), ScannedCount et Count ont la même valeur (1 000). Supposons maintenant que vous ayez ajouté une FilterExpression afin que seuls 300 éléments soient retournés. DynamoDB continue à lire tous les 1 000 éléments de TestTable, mais ignore l'ensemble de ces résultats, à l'exception des 300 éléments correspondant à vos critères. Dans ce cas, ScannedCount sera 1 000, mais Count sera 300. Si la taille du jeu de résultats dépasse 1 MB, les opérations ScannedCount et Count représentent seulement un compte partiel du total des éléments. Supposons que TestTable ait maintenant 1 million d'éléments et que la taille de chacun soit de 250 Ko. Dans ce cas, vous devez exécuter plusieurs demandes Scan pour pouvoir analyser la totalité de la table. (Pour de plus amples informations, veuillez consulter Pagination des résultats (p. 293).) Chaque réponse contient les ScannedCount et Countdes éléments traités par cette demande Scan particulière. Pour obtenir les totaux de toutes les demandes Scan, vous pouvez garder un compte actif de ScannedCount et de Count. API Version 2012-08-10 294 Amazon DynamoDB Manuel du développeur Cohérence en lecture Cohérence en lecture Cohérence en lecture de l'opération Query Un résultat Query est une lecture cohérente à terme, mais vous pouvez demander à la place une lecture à cohérence forte. Une lecture cohérente à terme peut ne pas refléter les résultats d'une opération PutItem ou UpdateItem récemment exécutée. Pour de plus amples informations, veuillez consulter Cohérence en lecture (p. 16). Cohérence en lecture de l'opération Scan Lorsque vous émettez une demande Scan, DynamoDB utilise les lectures cohérentes à terme. Cela signifie que les modifications apportées aux données de la table juste avant que l'opération Scan n'ait lieu peuvent ne pas figurer dans les résultats de l'analyse. Si vous avez besoin d'une copie cohérente des données, au moment où l'opération Scan commence, vous pouvez définir le paramètre ConsistentRead avec la valeur true. Cela garantit que toutes les opérations d'écriture qui ont pris fin avant que l'opération Scan ne commence seront inclus dans la réponse Scan. Cela est utile dans les scénarios de réplication ou de sauvegarde de table, en liaison avec Flux DynamoDB : tout d'abord, vous utilisez Scan avec ConsistentRead définie sur true, afin d'obtenir une copie cohérente des données de la table. Pendant l'opération Scan, Flux DynamoDB enregistre toute activité d'écriture supplémentaires qui se produit sur la table. Une fois l'opération Scan terminée, vous pouvez appliquer l'activité d'écriture du flux vers la table. Notez qu'une opération Scan avec ConsistentRead définie sur la valeur true consomme deux fois plus d'unités de capacité en lecture, par comparaison avec le fait de laisser ConsistentRead à sa valeur par défaut (false). Performances des opérations Query et Scan En règle générale, une opération Query est plus efficace qu'une opération Scan. Une opération Scan analyse toujours la totalité de la table ou de l'index secondaire, puis filtre les valeurs pour fournir le résultat recherché, essentiellement en ajoutant une étape consistant à supprimer les données de l'ensemble des résultats. Si possible, évitez l'utilisation d'une opération Scan sur une grande table ou sur un index avec un filtre qui supprime un grand nombre de résultats. En outre, au fur et à mesure qu'une table ou un index croît, l'opération Scan ralentit. L'opération Scan examine chaque élément pour les valeurs demandées et peut utiliser la totalité du débit alloué pour une grande table ou un index volumineux en une seule opération. Pour obtenir des temps de réponse plus rapides, concevez vos tables et vos index de telle sorte que vos applications puissent utiliser Query au lieu de Scan. (Pour les tables, vous pouvez également envisager d'utiliser les API GetItem et BatchGetItem.). Vous pouvez aussi concevoir votre application de façon à utiliser les opérations Scan d'une façon qui réduit l'impact sur votre taux de demande. Pour de plus amples informations, veuillez consulter Consignes pour interrogation et analyse (p. 588). Une opération Query recherche une plage spécifique de clés qui satisfont un ensemble donné de conditions de clé. Si vous spécifiez une expression de filtre, DynamoDB doivent exécuter l'étape supplémentaire de suppression de données du jeu de résultats. Une opération Query recherche la clé primaire composite spécifiée, ou la plage de clés, jusqu'à ce que l'un des événements suivants se produise : • Le jeu de résultats est épuisé. • Le nombre d'éléments récupérés atteint la valeur du paramètre Limit, s'il est spécifié. • La quantité de données récupérées atteint la limite de taille maximale 1 MB du jeu de résultats. API Version 2012-08-10 295 Amazon DynamoDB Manuel du développeur Analyse en parallèle Les performances de Query dépendent de la quantité de données récupérées, plutôt que du nombre total de clés primaires d'une table ou d'un index secondaire. Les paramètres d'une opération Query (et, par conséquent, le nombre de clés correspondantes) déterminent les performances de la requête. Par exemple, une requête sur une table qui contient un vaste ensemble de valeurs de clés de tri pour une valeur de clé de partition unique peut être plus efficace qu'une requête sur une autre table qui a moins de valeurs de clés de tri par valeur de clé de partition, si le nombre de clés correspondantes de la première table est inférieur à celui de la seconde table. Le nombre total de clés primaires, dans l'une ou l'autre table, ne détermine pas l'efficacité d'une opération Query. Une expression de filtre peut aussi avoir un impact sur l'efficacité d'une opération Query, car les éléments qui ne correspondent pas au filtre doivent être supprimés du jeu de résultats. Si possible, évitez l'utilisation d'une opération Query sur une grande table ou sur un index secondaire avec un filtre qui supprime un grand nombre de résultats. Si une valeur de clé de partition spécifique possède un vaste ensemble de valeurs de clé de tri et que les résultats ne peuvent pas être récupérés en une seule demande Query, le paramètre de continuation ExclusiveStartKey vous permet de soumettre une nouvelle demande de requête depuis le dernier élément extrait sans retraiter les données déjà récupérées. Analyse en parallèle Par défaut, l'opération Scan traite les données de manière séquentielle. DynamoDB retourne les données à l'application par incréments 1 MB et une application exécute des opérations Scan supplémentaires pour extraire la 1 MB de données suivante. Plus la table ou l'index en cours d'analyse est grand, plus l'opération Scan prendra de temps. En outre, une opération Scan séquentielle peut ne pas toujours être en mesure d'utiliser pleinement la capacité de débit en lecture alloué : même si DynamoDB répartit les données d'une grande table entre plusieurs partitions physiques, une opération Scan ne peut lire qu'une partition à la fois. Pour cette raison, le débit d'une opération Scan est limité par le débit maximal d'une partition unique. Pour résoudre ces problèmes, l'opération Scan peut diviser logiquement une table ou un index secondaire local en plusieurs segments, avec plusieurs travaux d'application analysant les segments en parallèle. Chaque travail peut être un thread (dans les langages de programmation qui prennent en charge le multithreading) ou un processus de système d'exploitation. Pour effectuer une analyse parallèle, chaque travail émet sa propre demande d'opération Scan avec les paramètres suivants : • Segment — Un segment à analyser par un travail particulier. Chaque travail doit utiliser une valeur différente pour Segment. • TotalSegments — Le nombre total de segments pour l'analyse parallèle. Cette valeur doit être la même que le nombre de travaux que votre application utilise. Le schéma suivant montre comment une application multithread effectue une opération Scan parallèle avec trois niveaux de parallélisme : API Version 2012-08-10 296 Amazon DynamoDB Manuel du développeur Analyse en parallèle Dans ce graphique, l'application génère trois threads et attribue un numéro à chacun d'eux. (Les segments étant de base zéro, le premier numéro est toujours 0.) Chaque thread émet une demande Scan, en définissant Segment avec son numéro défini et TotalSegments avec la valeur 3. Chaque thread analyse le segment qui lui est associé, en définissant la valeur 1 MB une par une, et retourne les données au thread principal de l'application. Les valeurs de Segment et TotalSegments s'appliquent aux demandes individuelles d'opération Scan et vous pouvez utiliser des valeurs différentes à tout moment. Vous devrez peut-être tester ces valeurs, ainsi que le nombre de travaux que vous utilisez, jusqu'à ce que votre application atteigne ses meilleures performances. Note Une analyse parallèle avec un grand nombre de travaux peut facilement consommer la totalité du débit alloué pour la table ou l'index en cours d'analyse. Il est préférable d'éviter de telles analyses si la table ou l'index sont également soumis à une importante activité en lecture ou en écriture des autres applications. Pour contrôler la quantité de données retournées par la requête, utilisez le paramètre Limit. Il est ainsi possible d'éviter les situations où un travail consomme tout le débit alloué, aux dépens de tous les autres travaux. Pour plus d'informations, consultez « Réduire la taille de la page » dans Evitez les rafales soudaines de l'activité en lecture (p. 588). API Version 2012-08-10 297 Amazon DynamoDB Manuel du développeur Interrogation Interrogation dans DynamoDB Rubriques • Interrogation de tables et d'index : Java (p. 298) • Interrogation des tables et des index : .NET (p. 304) • Interrogation des tables et des index : PHP (p. 311) Cette section présente les requêtes de base et leurs résultats. Interrogation de tables et d'index : Java L'opération Query vous permet d'interroger une table ou un index secondaire. Vous devez fournir une valeur de clé de partition et une condition d'égalité. Si la table ou l'index dispose d'une clé de tri, vous pouvez affiner les résultats en fournissant une valeur de clé de tri et une condition. Note Le SDK pour Java fournit également un modèle de persistance d'objet, ce qui vous permet de mapper vos classes côté client sur des tables DynamoDB. Cette approche peut réduire la quantité de code que vous avez à écrire. Pour de plus amples informations, veuillez consulter Java : DynamoDBMapper (p. 79). Voici les étapes pour récupérer un élément à l'aide du Document API AWS SDK for Java. 1. Créez une instance de la classe DynamoDB. 2. Créez une instance de la classe Table pour représenter la table que vous souhaitez utiliser. 3. Appelez la méthode query de l'instance Table. Vous devez spécifier la valeur de clé de partition du ou des éléments que vous souhaitez récupérer, ainsi que de n'importe quel paramètre facultatif d'interrogation. La réponse inclut un objet ItemCollection qui fournit tous les éléments renvoyés par la requête. L'extrait de code Java suivant illustre les tâches précédentes. L'extrait de code suppose que vous ayez une table Reply qui stocke les réponses des threads de forum. Pour de plus amples informations, veuillez consulter Création de tables et chargement d'exemples de données (p. 167). Reply ( Id, ReplyDateTime, ... ) Chaque thread de forum a un ID unique et peut avoir zéro ou plusieurs réponses. Par conséquent, l'attribut Id de la table Reply est composé du nom de forum et du sujet de forum. Id (clé de partition) et ReplyDateTime (clé de tri) constituent la clé primaire composite pour la table. La requête suivante récupère toutes les réponses pour un objet thread spécifique. La requête requiert à la fois le nom de la table et la valeur Subject. DynamoDB dynamoDB = new DynamoDB( new AmazonDynamoDBClient(new ProfileCredentialsProvider())); Table table = dynamoDB.getTable("Reply"); QuerySpec spec = new QuerySpec() .withKeyConditionExpression("Id = :v_id") .withValueMap(new ValueMap() .withString(":v_id", "Amazon DynamoDB#DynamoDB Thread 1")); API Version 2012-08-10 298 Amazon DynamoDB Manuel du développeur Interrogation ItemCollection<QueryOutcome> items = table.query(spec); Iterator<Item> iterator = items.iterator(); Item item = null; while (iterator.hasNext()) { item = iterator.next(); System.out.println(item.toJSONPretty()); } Spécification de paramètres facultatifs La méthode query prend en charge plusieurs paramètres facultatifs. Par exemple, vous pouvez le cas échéant affiner les résultats de la requête précédente pour renvoyer des réponses des deux semaines écoulées en spécifiant une condition. La condition est appelée condition de clé de tri, car DynamoDB analyse la condition de la requête que vous spécifiez par rapport à la clé de tri de la clé primaire. Vous pouvez spécifier d'autres paramètres facultatifs pour récupérer uniquement une liste spécifique d'attributs des éléments du résultat de la requête. L'extrait de code Java suivant récupère les réponses des threads de forum publiées au cours des 15 derniers jours. L'extrait de code spécifie des paramètres facultatifs à l'aide de : • Une KeyConditionExpression pour récupérer les réponses à partir d'un forum de discussion spécifique (clé de partition) et, au sein de cet ensemble d'éléments, des réponses qui ont été publiées au cours des 15 derniers jours (clé de tri). • Une FilterExpression pour renvoyer uniquement les réponses à partir d'un utilisateur spécifique. Le filtre est appliqué une fois la requête traitée, mais avant que les résultats soient renvoyés à l'utilisateur. • Une ValueMap pour définir les valeurs réelles pour les espaces réservés KeyConditionExpression. • Un paramètre ConsistentRead true pour demander une lecture fortement cohérente. Cet extrait de code utilise un objet QuerySpec qui permet d'accéder à tous les paramètres d'entrée de la requête de bas niveau. Table table = dynamoDB.getTable("Reply"); long twoWeeksAgoMilli = (new Date()).getTime() - (15L*24L*60L*60L*1000L); Date twoWeeksAgo = new Date(); twoWeeksAgo.setTime(twoWeeksAgoMilli); SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"); String twoWeeksAgoStr = df.format(twoWeeksAgo); QuerySpec spec = new QuerySpec() .withKeyConditionExpression("Id = :v_id and ReplyDateTime > :v_reply_dt_tm") .withFilterExpression("PostedBy = :v_posted_by") .withValueMap(new ValueMap() .withString(":v_id", "Amazon DynamoDB#DynamoDB Thread 1") .withString(":v_reply_dt_tm", twoWeeksAgoStr) .withString(":v_posted_by", "User B")) .withConsistentRead(true); ItemCollection<QueryOutcome> items = table.query(spec); API Version 2012-08-10 299 Amazon DynamoDB Manuel du développeur Interrogation Iterator<Item> iterator = items.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next().toJSONPretty()); } Vous pouvez également le cas échéant limiter le nombre d'éléments par page en utilisant la méthode withMaxPageSize. En temps voulu, vous appelez la méthode query, vous obtenez une ItemCollection qui contient les éléments qui en résultent. Vous pouvez ensuite parcourir les résultats, en traitant une page à la fois, jusqu'à ce qu'il n'y ait pas plus de pages. L'extrait de code Java suivant modifie la spécification de requête présentée ci-dessus. Cette fois-ci, la spécification de requête utilise la méthode withMaxPageSize. La classe Page fournit un itérateur qui permet au code de traiter les éléments de chaque page. spec.withMaxPageSize(10); ItemCollection<QueryOutcome> items = table.query(spec); // Process each page of results int pageNum = 0; for (Page<Item, QueryOutcome> page : items.pages()) { System.out.println("\nPage: " + ++pageNum); // Process each item on the current page Iterator<Item> item = page.iterator(); while (item.hasNext()) { System.out.println(item.next().toJSONPretty()); } } Exemple - Interrogation avec Java Les tables suivantes stockent des informations sur un ensemble de forums. Pour de plus amples informations, veuillez consulter Création de tables et chargement d'exemples de données (p. 167). Note Le SDK pour Java fournit également un modèle de persistance d'objet, ce qui vous permet de mapper vos classes côté client sur des tables DynamoDB. Cette approche peut réduire la quantité de code que vous avez à écrire. Pour de plus amples informations, veuillez consulter Java : DynamoDBMapper (p. 79). Forum ( Name, ... ) Thread ( ForumName, Subject, Message, LastPostedBy, LastPostDateTime, ...) Reply ( Id, ReplyDateTime, Message, PostedBy, ...) Dans cet exemple de code Java, vous exécutez des variantes de recherche des réponses pour un thread « DynamoDB Thread 1 » dans le forum « DynamoDB ». • Recherchez des réponses pour un thread. • Recherchez des réponses pour un thread, en spécifiant une limite sur le nombre d'éléments par page de résultats. Si le nombre d'éléments dans l'ensemble de résultats dépasse la taille de la page, vous obtenez uniquement la première page de résultats. Ce modèle de codage garantit que votre code traite toutes les pages dans le résultat de la requête. API Version 2012-08-10 300 Amazon DynamoDB Manuel du développeur Interrogation • Recherchez des réponses au cours des 15 derniers jours. • Recherchez des réponses dans une plage de dates spécifique. Les deux requêtes précédentes vous montrent comment vous pouvez spécifier des conditions de clé de tri pour affiner les résultats de la requête et utiliser d'autres paramètres de requête facultatifs. Note Cet exemple de code suppose que vous ayez déjà chargé des données dans DynamoDB pour votre compte en suivant les instructions de la section Création de tables et chargement d'exemples de données (p. 167). Pour obtenir les instructions pas à pas afin d'exécuter l'exemple suivant, consultez Exemples de Code Java (p. 173). // Copyright 2012-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. // Licensed under the Apache License, Version 2.0. package com.amazonaws.codesamples.document; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Iterator; import import import import import import import import import import com.amazonaws.auth.profile.ProfileCredentialsProvider; com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient; com.amazonaws.services.dynamodbv2.document.DynamoDB; com.amazonaws.services.dynamodbv2.document.Item; com.amazonaws.services.dynamodbv2.document.ItemCollection; com.amazonaws.services.dynamodbv2.document.Page; com.amazonaws.services.dynamodbv2.document.QueryOutcome; com.amazonaws.services.dynamodbv2.document.Table; com.amazonaws.services.dynamodbv2.document.spec.QuerySpec; com.amazonaws.services.dynamodbv2.document.utils.ValueMap; public class DocumentAPIQuery { static DynamoDB dynamoDB = new DynamoDB(new AmazonDynamoDBClient(new ProfileCredentialsProvider())); static String tableName = "Reply"; public static void main(String[] args) throws Exception { String forumName = "Amazon DynamoDB"; String threadSubject = "DynamoDB Thread 1"; findRepliesForAThread(forumName, threadSubject); findRepliesForAThreadSpecifyOptionalLimit(forumName, threadSubject); findRepliesInLast15DaysWithConfig(forumName, threadSubject); findRepliesPostedWithinTimePeriod(forumName, threadSubject); findRepliesUsingAFilterExpression(forumName, threadSubject); } private static void findRepliesForAThread(String forumName, String threadSubject) { API Version 2012-08-10 301 Amazon DynamoDB Manuel du développeur Interrogation Table table = dynamoDB.getTable(tableName); String replyId = forumName + "#" + threadSubject; QuerySpec spec = new QuerySpec() .withKeyConditionExpression("Id = :v_id") .withValueMap(new ValueMap() .withString(":v_id", replyId)); ItemCollection<QueryOutcome> items = table.query(spec); System.out.println("\nfindRepliesForAThread results:"); Iterator<Item> iterator = items.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next().toJSONPretty()); } } private static void findRepliesForAThreadSpecifyOptionalLimit(String forumName, String threadSubject) { Table table = dynamoDB.getTable(tableName); String replyId = forumName + "#" + threadSubject; QuerySpec spec = new QuerySpec() .withKeyConditionExpression("Id = :v_id") .withValueMap(new ValueMap() .withString(":v_id", replyId)) .withMaxPageSize(1); ItemCollection<QueryOutcome> items = table.query(spec); System.out.println("\nfindRepliesForAThreadSpecifyOptionalLimit results:"); // Process each page of results int pageNum = 0; for (Page<Item, QueryOutcome> page : items.pages()) { System.out.println("\nPage: " + ++pageNum); // Process each item on the current page Iterator<Item> item = page.iterator(); while (item.hasNext()) { System.out.println(item.next().toJSONPretty()); } } } private static void findRepliesInLast15DaysWithConfig(String forumName, String threadSubject) { Table table = dynamoDB.getTable(tableName); long twoWeeksAgoMilli = (new Date()).getTime() (15L*24L*60L*60L*1000L); API Version 2012-08-10 302 Amazon DynamoDB Manuel du développeur Interrogation Date twoWeeksAgo = new Date(); twoWeeksAgo.setTime(twoWeeksAgoMilli); SimpleDateFormat df = new SimpleDateFormat("yyyy-MMdd'T'HH:mm:ss.SSS'Z'"); String twoWeeksAgoStr = df.format(twoWeeksAgo); String replyId = forumName + "#" + threadSubject; QuerySpec spec = new QuerySpec() .withProjectionExpression("Message, ReplyDateTime, PostedBy") .withKeyConditionExpression("Id = :v_id and ReplyDateTime <= :v_reply_dt_tm") .withValueMap(new ValueMap() .withString(":v_id", replyId) .withString(":v_reply_dt_tm", twoWeeksAgoStr)); ItemCollection<QueryOutcome> items = table.query(spec); System.out.println("\nfindRepliesInLast15DaysWithConfig results:"); Iterator<Item> iterator = items.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next().toJSONPretty()); } } private static void findRepliesPostedWithinTimePeriod(String forumName, String threadSubject) { Table table = dynamoDB.getTable(tableName); long startDateMilli = (new Date()).getTime() (15L*24L*60L*60L*1000L); long endDateMilli = (new Date()).getTime() - (5L*24L*60L*60L*1000L); java.text.SimpleDateFormat df = new java.text.SimpleDateFormat("yyyyMM-dd'T'HH:mm:ss.SSS'Z'"); String startDate = df.format(startDateMilli); String endDate = df.format(endDateMilli); String replyId = forumName + "#" + threadSubject; QuerySpec spec = new QuerySpec() .withProjectionExpression("Message, ReplyDateTime, PostedBy") .withKeyConditionExpression("Id = :v_id and ReplyDateTime between :v_start_dt and :v_end_dt") .withValueMap(new ValueMap() .withString(":v_id", replyId) .withString(":v_start_dt", startDate) .withString(":v_end_dt", endDate)); ItemCollection<QueryOutcome> items = table.query(spec); System.out.println("\nfindRepliesPostedWithinTimePeriod results:"); Iterator<Item> iterator = items.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next().toJSONPretty()); } } API Version 2012-08-10 303 Amazon DynamoDB Manuel du développeur Interrogation private static void findRepliesUsingAFilterExpression(String forumName, String threadSubject) { Table table = dynamoDB.getTable(tableName); String replyId = forumName + "#" + threadSubject; QuerySpec spec = new QuerySpec() .withProjectionExpression("Message, ReplyDateTime, PostedBy") .withKeyConditionExpression("Id = :v_id") .withFilterExpression("PostedBy = :v_postedby") .withValueMap(new ValueMap() .withString(":v_id", replyId) .withString(":v_postedby", "User B")); ItemCollection<QueryOutcome> items = table.query(spec); System.out.println("\nfindRepliesUsingAFilterExpression results:"); Iterator<Item> iterator = items.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next().toJSONPretty()); } } } Interrogation des tables et des index : .NET L'opération Query vous permet d'interroger une table ou un index secondaire. Vous devez fournir une valeur de clé de partition et une condition d'égalité. Si la table ou l'index dispose d'une clé de tri, vous pouvez affiner les résultats en fournissant une valeur de clé de tri et une condition. Voici les étapes pour interroger une table à l'aide de l'API de bas niveau du kit SDK .NET. 1. Créez une instance de la classe AmazonDynamoDBClient. 2. Créez une instance de la classe QueryRequest et fournissez les paramètres d'opération de la requête. 3. Exécutez la méthode Query et fournissez l'objet QueryRequest que vous avez créé à l'étape précédente. La réponse inclut l'objet QueryResult qui fournit tous les éléments renvoyés par la requête. L'exemple de code C# suivant illustre les tâches précédentes. L'extrait de code suppose que vous ayez une table Reply qui stocke les réponses des threads de forum. Pour de plus amples informations, veuillez consulter Création de tables et chargement d'exemples de données (p. 167). Reply ( <emphasis role="underline">Id</emphasis>, <emphasis role="underline">ReplyDateTime</emphasis>, ... ) Chaque thread de forum a un ID unique et peut avoir zéro ou plusieurs réponses. Par conséquent, la clé primaire est composée de l'Id (clé de partition) et de ReplyDateTime (clé de tri). API Version 2012-08-10 304 Amazon DynamoDB Manuel du développeur Interrogation La requête suivante récupère toutes les réponses pour un objet thread spécifique. La requête requiert à la fois le nom de la table et la valeur Subject. AmazonDynamoDBClient client = new AmazonDynamoDBClient(); var request = new QueryRequest { TableName = "Reply", KeyConditionExpression = "Id = :v_Id", ExpressionAttributeValues = new Dictionary<string, AttributeValue> { {":v_Id", new AttributeValue { S = "Amazon DynamoDB#DynamoDB Thread 1" }}} }; var response = client.Query(request); foreach (Dictionary<string, AttributeValue> item in response.Items) { // Process the result. PrintItem(item); } Spécification de paramètres facultatifs La méthode Query prend en charge plusieurs paramètres facultatifs. Par exemple, vous pouvez le cas échéant affiner le résultat de la requête précédente pour renvoyer les réponses des deux semaines écoulées en spécifiant une condition. La condition est appelée condition de clé de tri, car Amazon DynamoDB analyse la condition de la requête que vous spécifiez par rapport à la clé de tri de la clé primaire. Vous pouvez spécifier d'autres paramètres facultatifs pour récupérer uniquement une liste spécifique d'attributs des éléments du résultat de la requête. Pour plus d'informations, consultez Query. L'extrait de code C# suivant récupère les réponses des threads de forum publiées au cours des 15 derniers jours. L'extrait spécifie les paramètres facultatifs suivants : • Un paramètre KeyConditionExpression pour récupérer uniquement les réponses des 15 derniers jours. • Un paramètre ProjectionExpression pour spécifier une liste d'attributs à récupérer pour les éléments du résultat de la requête. • Un paramètre ConsistentRead pour exécuter une lecture à cohérence forte. DateTime twoWeeksAgoDate = DateTime.UtcNow - TimeSpan.FromDays(15); string twoWeeksAgoString = twoWeeksAgoDate.ToString(AWSSDKUtils.ISO8601DateFormat); var request = new QueryRequest { TableName = "Reply", KeyConditionExpression = "Id = :v_Id and ReplyDateTime > :v_twoWeeksAgo", ExpressionAttributeValues = new Dictionary<string, AttributeValue> { {":v_Id", new AttributeValue { S = "Amazon DynamoDB#DynamoDB Thread 2" }}, {":v_twoWeeksAgo", new AttributeValue { S = twoWeeksAgoString }} }, ProjectionExpression = "Subject, ReplyDateTime, PostedBy", ConsistentRead = true }; API Version 2012-08-10 305 Amazon DynamoDB Manuel du développeur Interrogation var response = client.Query(request); foreach (Dictionary<string, AttributeValue> item in response.Items) { // Process the result. PrintItem(item); } Vous pouvez aussi limiter le cas échéant la taille de la page ou le nombre d'éléments par page, en ajoutant le paramètre facultatif Limit. Chaque fois que vous exécutez la méthode Query, vous obtenez une page de résultats ayant le nombre d'éléments spécifié. Pour récupérer la page suivante, vous exécutez à nouveau la méthode Query en fournissant la valeur de la clé primaire du dernier élément de la page précédente afin que la méthode puisse retourner l'ensemble d'éléments suivant. Vous fournissez ces informations dans la demande en définissant la propriété ExclusiveStartKey. Au départ, cette propriété peut être null. Pour récupérer les pages suivantes, vous devez mettre à jour cette valeur de propriété avec la clé primaire du dernier élément de la page précédente. L'extrait de code C# suivant interroge la table Reply. Dans la demande, il spécifie les paramètres facultatifs Limit et ExclusiveStartKey. La boucle do/while continue d'analyser une page à la fois jusqu'à ce que LastEvaluatedKey renvoie une valeur null. Dictionary<string,AttributeValue> lastKeyEvaluated = null; do { var request = new QueryRequest { TableName = "Reply", KeyConditionExpression = "Id = :v_Id", ExpressionAttributeValues = new Dictionary<string, AttributeValue> { {":v_Id", new AttributeValue { S = "Amazon DynamoDB#DynamoDB Thread 2" }} }, // Optional parameters. Limit = 1, ExclusiveStartKey = lastKeyEvaluated }; var response = client.Query(request); // Process the query result. foreach (Dictionary<string, AttributeValue> item in response.Items) { PrintItem(item); } lastKeyEvaluated = response.LastEvaluatedKey; } while (lastKeyEvaluated != null && lastKeyEvaluated.Count != 0); Exemple - Interrogation à l'aide du kit SDK AWS pour .NET Les tables suivantes stockent des informations sur un ensemble de forums. Pour de plus amples informations, veuillez consulter Création de tables et chargement d'exemples de données (p. 167). API Version 2012-08-10 306 Amazon DynamoDB Manuel du développeur Interrogation Forum ( <emphasis role="underline">Name</emphasis>, ... ) Thread ( <emphasis role="underline">ForumName</emphasis>, <emphasis role="underline">Subject</emphasis>, Message, LastPostedBy, LastPostDateTime, ...) Reply ( <emphasis role="underline">Id</emphasis>, <emphasis role="underline">ReplyDateTime</emphasis>, Message, PostedBy, ...) Dans cet exemple de code C#, vous exécutez des variantes de recherche des réponses d'un thread « Thread 1 DynamoDB » dans le forum « DynamoDB ». • Recherchez des réponses pour un thread. • Recherchez des réponses pour un thread. Spécifiez le paramètre de requête Limit pour définir la taille de la page. Cette fonction illustre l'utilisation de pagination pour traiter les résultats de plusieurs pages. Amazon DynamoDB possède une limite de taille de page et si votre résultat dépasse la taille de la page, vous obtenez uniquement la première page de résultats. Ce modèle de codage garantit que votre code traite toutes les pages dans le résultat de la requête. • Recherchez des réponses au cours des 15 derniers jours. • Recherchez des réponses dans une plage de dates spécifique. Les deux requêtes précédentes vous montrent comment vous pouvez spécifier les conditions de clé de tri pour affiner les résultats de la requête et utiliser d'autres paramètres de requête facultatifs. Pour obtenir les instructions pas à pas afin de tester l'exemple suivant, consultez Exemples de code .NET (p. 175). using using using using using using System; System.Collections.Generic; Amazon.DynamoDBv2; Amazon.DynamoDBv2.Model; Amazon.Runtime; Amazon.Util; namespace com.amazonaws.codesamples { class LowLevelQuery { private static AmazonDynamoDBClient client = new AmazonDynamoDBClient(); static void Main(string[] args) { try { // Query a specific forum and thread. string forumName = "Amazon DynamoDB"; string threadSubject = "DynamoDB Thread 1"; FindRepliesForAThread(forumName, threadSubject); FindRepliesForAThreadSpecifyOptionalLimit(forumName, threadSubject); FindRepliesInLast15DaysWithConfig(forumName, threadSubject); API Version 2012-08-10 307 Amazon DynamoDB Manuel du développeur Interrogation FindRepliesPostedWithinTimePeriod(forumName, threadSubject); Console.WriteLine("Example complete. To continue, press Enter"); Console.ReadLine(); } catch (AmazonDynamoDBException e) { Console.WriteLine(e.Message); Console.ReadLine(); } catch (AmazonServiceException e) { Console.WriteLine(e.Message); Console.ReadLine(); } catch (Exception e) { Console.WriteLine(e.Message); Console.ReadLine(); } } private static void FindRepliesPostedWithinTimePeriod(string forumName, string threadSubject) { Console.WriteLine("*** Executing FindRepliesPostedWithinTimePeriod() ***"); string replyId = forumName + "#" + threadSubject; // You must provide date value based on your test data. DateTime startDate = DateTime.UtcNow - TimeSpan.FromDays(21); string start = startDate.ToString(AWSSDKUtils.ISO8601DateFormat); // You provide date value based on your test data. DateTime endDate = DateTime.UtcNow - TimeSpan.FromDays(5); string end = endDate.ToString(AWSSDKUtils.ISO8601DateFormat); var request = new QueryRequest { TableName = "Reply", ReturnConsumedCapacity = "TOTAL", KeyConditionExpression = "Id = :v_replyId and ReplyDateTime between :v_start and :v_end", ExpressionAttributeValues = new Dictionary<string, AttributeValue> { {":v_replyId", new AttributeValue { S = replyId }}, {":v_start", new AttributeValue { S = start }}, {":v_end", new AttributeValue { S = end }} } }; var response = client.Query(request); Console.WriteLine("\nNo. of reads used (by query in FindRepliesPostedWithinTimePeriod) {0}", response.ConsumedCapacity.CapacityUnits); foreach (Dictionary<string, AttributeValue> item in response.Items) { PrintItem(item); } Console.WriteLine("To continue, press Enter"); Console.ReadLine(); } private static void FindRepliesInLast15DaysWithConfig(string forumName, string threadSubject) API Version 2012-08-10 308 Amazon DynamoDB Manuel du développeur Interrogation { Console.WriteLine("*** Executing FindRepliesInLast15DaysWithConfig() ***"); string replyId = forumName + "#" + threadSubject; DateTime twoWeeksAgoDate = DateTime.UtcNow TimeSpan.FromDays(15); string twoWeeksAgoString = twoWeeksAgoDate.ToString(AWSSDKUtils.ISO8601DateFormat); var request = new QueryRequest { TableName = "Reply", ReturnConsumedCapacity = "TOTAL", KeyConditionExpression = "Id = :v_replyId and ReplyDateTime > :v_interval", ExpressionAttributeValues = new Dictionary<string, AttributeValue> { {":v_replyId", new AttributeValue { S = replyId }}, {":v_interval", new AttributeValue { S = twoWeeksAgoString }} }, // Optional parameter. ProjectionExpression = "Id, ReplyDateTime, PostedBy", // Optional parameter. ConsistentRead = true }; var response = client.Query(request); Console.WriteLine("No. of reads used (by query in FindRepliesInLast15DaysWithConfig) {0}", response.ConsumedCapacity.CapacityUnits); foreach (Dictionary<string, AttributeValue> item in response.Items) { PrintItem(item); } Console.WriteLine("To continue, press Enter"); Console.ReadLine(); } private static void FindRepliesForAThreadSpecifyOptionalLimit(string forumName, string threadSubject) { Console.WriteLine("*** Executing FindRepliesForAThreadSpecifyOptionalLimit() ***"); string replyId = forumName + "#" + threadSubject; Dictionary<string, AttributeValue> lastKeyEvaluated = null; do { var request = new QueryRequest { TableName = "Reply", ReturnConsumedCapacity = "TOTAL", KeyConditionExpression = "Id = :v_replyId", API Version 2012-08-10 309 Amazon DynamoDB Manuel du développeur Interrogation ExpressionAttributeValues = new Dictionary<string, AttributeValue> { {":v_replyId", new AttributeValue { S = replyId }} }, Limit = 2, // The Reply table has only a few sample items. So the page size is smaller. ExclusiveStartKey = lastKeyEvaluated }; var response = client.Query(request); Console.WriteLine("No. of reads used (by query in FindRepliesForAThreadSpecifyLimit) {0}\n", response.ConsumedCapacity.CapacityUnits); foreach (Dictionary<string, AttributeValue> item in response.Items) { PrintItem(item); } lastKeyEvaluated = response.LastEvaluatedKey; } while (lastKeyEvaluated != null && lastKeyEvaluated.Count ! = 0); Console.WriteLine("To continue, press Enter"); Console.ReadLine(); } private static void FindRepliesForAThread(string forumName, string threadSubject) { Console.WriteLine("*** Executing FindRepliesForAThread() ***"); string replyId = forumName + "#" + threadSubject; var request = new QueryRequest { TableName = "Reply", ReturnConsumedCapacity = "TOTAL", KeyConditionExpression = "Id = :v_replyId", ExpressionAttributeValues = new Dictionary<string, AttributeValue> { {":v_replyId", new AttributeValue { S = replyId }} } }; var response = client.Query(request); Console.WriteLine("No. of reads used (by query in FindRepliesForAThread) {0}\n", response.ConsumedCapacity.CapacityUnits); foreach (Dictionary<string, AttributeValue> item in response.Items) { PrintItem(item); } Console.WriteLine("To continue, press Enter"); Console.ReadLine(); } API Version 2012-08-10 310 Amazon DynamoDB Manuel du développeur Interrogation private static void PrintItem( Dictionary<string, AttributeValue> attributeList) { foreach (KeyValuePair<string, AttributeValue> kvp in attributeList) { string attributeName = kvp.Key; AttributeValue value = kvp.Value; Console.WriteLine( attributeName + " " + (value.S == null ? "" : "S=[" + (value.N == null ? "" : "N=[" + (value.SS == null ? "" : "SS=[" value.SS.ToArray()) + "]") + (value.NS == null ? "" : "NS=[" value.NS.ToArray()) + "]") ); } value.S + "]") + value.N + "]") + + string.Join(",", + string.Join(",", Console.WriteLine("************************************************"); } } } Interrogation des tables et des index : PHP La fonction query vous permet d'interroger une table ou un index secondaire. Vous devez fournir une valeur de clé de partition et une condition d'égalité. Si la table ou l'index dispose d'une clé de tri, vous pouvez affiner les résultats en fournissant une valeur de clé de tri et une condition. Voici les étapes courantes pour l'utilisation du kit SDK AWS pour PHP. 1. Créer une instance du client DynamoDB. 2. Fournir les paramètres d'une opération DynamoDB, y compris les paramètres facultatifs. 3. Charger la réponse à partir de DynamoDB dans une variable locale pour votre application. Pensez à utiliser la table Reply suivante qui stocke les réponses pour les threads des forums. Reply ( Id, ReplyDateTime, ... ) Chaque thread de forum a un ID unique et peut avoir zéro ou plusieurs réponses. Par conséquent, la clé primaire est composée de l'Id (clé de partition) et de ReplyDateTime (clé de tri). La requête suivante récupère toutes les réponses pour un objet thread spécifique. La requête requiert le nom de la table et la valeur Subject. Note Cet exemple de code suppose que vous ayez déjà chargé des données dans DynamoDB pour votre compte en suivant les instructions de la section Création de tables et chargement d'exemples de données (p. 167). Sinon, vous pouvez charger les données en utilisant les instructions de la rubrique Création d'exemples de table et de chargement de données à l'aide du kit de développement (SDK) AWS pour PHP (p. 624). API Version 2012-08-10 311 Amazon DynamoDB Manuel du développeur Interrogation Pour obtenir les instructions pas à pas afin d'exécuter l'exemple suivant, consultez Exemples de Code PHP (p. 177). require 'vendor/autoload.php'; $sdk = new Aws\Sdk([ 'region' => 'us-west-2', 'version' => 'latest' ]); $dynamodb = $sdk->createDynamoDb(); $response = $dynamodb->query([ 'TableName' => 'Reply', 'KeyConditionExpression' => 'Id = :v_id', 'ExpressionAttributeValues' => [ ':v_id' => ['S' => 'Amazon DynamoDB#DynamoDB Thread 1'] ] ]); print_r($response['Items']); Spécification de paramètres facultatifs La fonction query prend en charge plusieurs paramètres facultatifs. Par exemple, vous pouvez le cas échéant affiner le résultat de la requête précédente pour renvoyer les réponses des deux dernières semaines en spécifiant une condition de clé de tri. La condition est appelée condition clé de sorte, parce que DynamoDB évalue la condition de requête que vous spécifiez par rapport à la clé de tri. Vous pouvez spécifier d'autres paramètres facultatifs pour récupérer une liste précise d'attributs d'éléments du résultat de la requête. Pour plus d'informations sur les paramètres, consultez Query. L'exemple PHP suivant récupère les réponses des threads de forum postés au cours des 7 derniers jours. L'échantillon spécifie les paramètres facultatifs suivants : • La clé de tri du paramètre KeyConditionExpression pour récupérer uniquement les réponses au cours des 7 derniers jours. La condition spécifie la valeur ReplyDateTime et un opérateur de comparaison à utiliser pour comparer les dates. • ProjectionExpression pour spécifier les attributs afin de récupérer les éléments des résultats de la requête • ConsistentRead : paramètre pour exécuter une lecture à cohérence forte. Ce paramètre remplace le comportement par défaut d'exécution de lectures cohérentes à terme. Pour en savoir plus sur la cohérence en lecture, consultez Cohérence en lecture (p. 16). $sevenDaysAgo = date('Y-m-d H:i:s', strtotime('-7 days')); $response = $dynamodb->query([ 'TableName' => 'Reply', 'KeyConditionExpression' => 'Id = :v_id and ReplyDateTime >= :v_reply_dt', 'ExpressionAttributeValues' => [ ':v_id' => ['S' => 'Amazon DynamoDB#DynamoDB Thread 2'], ':v_reply_dt' => ['S' => $sevenDaysAgo] ], API Version 2012-08-10 312 Amazon DynamoDB Manuel du développeur Interrogation // optional parameters 'ProjectionExpression' => 'Subject, ReplyDateTime, PostedBy', 'ConsistentRead' => true ]); print_r($response['Items']); Vous pouvez aussi limiter à titre facultatif la taille de la page, le nombre d'éléments par page, en ajoutant le paramètre Limit. Chaque fois que vous exécutez la fonction query, vous obtenez une page de résultats avec le nombre d'éléments spécifié. Pour récupérer la page suivante, vous exécutez à nouveau la fonction query en fournissant la valeur de clé primaire du dernier élément de la page précédente afin que la méthode puisse retourner le prochain ensemble d'éléments. Vous fournissez ces informations dans la demande en définissant la propriété ExclusiveStartKey. Au départ, cette propriété peut être null. Pour récupérer les pages suivantes, vous devez mettre à jour cette valeur de propriété avec la clé primaire du dernier élément de la page précédente. L'exemple PHP suivant interroge la table Reply pour les entrées qui datent de plus de 14 jours. Dans la demande, il spécifie les paramètres facultatifs Limit et ExclusiveStartKey. <?php require 'vendor/autoload.php'; date_default_timezone_set('UTC'); use Aws\DynamoDb\Exception\DynamoDbException; $sdk = new Aws\Sdk([ 'region' => 'us-west-2', 'version' => 'latest' ]); $dynamodb = $sdk->createDynamoDb(); $fourteenDaysAgo = date('Y-m-d H:i:s', strtotime('-14 days')); $tableName = 'Reply'; # The Query API is paginated. Issue the Query request multiple times. do { echo "Querying table $tableName\n"; $request = [ 'TableName' => $tableName, 'KeyConditionExpression' => 'Id = :v_id and ReplyDateTime >= :v_reply_dt', 'ExpressionAttributeValues' => [ ':v_id' => ['S' => 'Amazon DynamoDB#DynamoDB Thread 2'], ':v_reply_dt' => ['S' => $fourteenDaysAgo] ], 'ProjectionExpression' => 'Id, ReplyDateTime, Message, PostedBy', 'ConsistentRead' => true, 'Limit' => 1 ]; # Add the ExclusiveStartKey if we got one back in the previous response if(isset($response) && isset($response['LastEvaluatedKey'])) { $request['ExclusiveStartKey'] = $response['LastEvaluatedKey']; } API Version 2012-08-10 313 Amazon DynamoDB Manuel du développeur Analyse $response = $dynamodb->query($request); foreach ($response['Items'] as $key => $value) { echo 'Id: ' . $value['Id']['S'] . "\n"; echo 'ReplyDateTime: ' . $value['ReplyDateTime']['S'] . "\n"; echo 'Message: ' . $value['Message']['S'] . "\n"; echo 'PostedBy: ' . $value['PostedBy']['S'] . "\n"; echo "\n"; } # If there is no LastEvaluatedKey in the response, then # there are no more items matching this Query } while(isset($response['LastEvaluatedKey'])); ?> Analyse dans DynamoDB Rubriques • Analyse des tables et des index : Java (p. 314) • Analyse des tables et des index : .NET (p. 322) • Analyse des tables et des index : PHP (p. 330) Cette section présente les analyses de base et leurs résultats. Analyse des tables et des index : Java L'opération Scan lit tous les éléments dans une table ou un index. Pour en savoir plus sur la performance associée aux opérations d'analyse et de requêtes, consultez Utilisation des requêtes et des analyses (p. 290). Voici les étapes pour analyser une table à l'aide de l'API Document de AWS SDK for Java. 1. Créez une instance de la classe AmazonDynamoDBClient. 2. Créez une instance de la classe ScanRequest et fournissez un paramètre d'analyse. Le seul paramètre requis est le nom de la table. 3. Exécutez la méthode scan et fournissez l'objet ScanRequest que vous avez créé à l'étape précédente. La table Reply suivante stocke les réponses pour les threads de forum. Reply ( Id, ReplyDateTime, Message, PostedBy ) La table gère toutes les réponses pour divers threads de forum. Par conséquent, la clé primaire est composée de l'Id (clé de partition) et de ReplyDateTime (clé de tri). L'extrait de code Java suivant analyse la totalité de la table. L'instance ScanRequest spécifie le nom de la table à analyser. AmazonDynamoDBClient client = new AmazonDynamoDBClient( new ProfileCredentialsProvider()); ScanRequest scanRequest = new ScanRequest() API Version 2012-08-10 314 Amazon DynamoDB Manuel du développeur Analyse .withTableName("Reply"); ScanResult result = client.scan(scanRequest); for (Map<String, AttributeValue> item : result.getItems()){ printItem(item); } Spécification de paramètres facultatifs La méthode scan prend en charge plusieurs paramètres facultatifs. Par exemple, vous pouvez le cas échéant utiliser une expression de filtre pour filtrer le résultat d'analyse. Dans une expression de filtre, vous pouvez spécifier une condition ainsi que des noms et des valeurs d'attribut sur lesquels vous voulez que la condition soit évaluée. Pour plus d'informations, consultez Scan. L'extrait Java suivant analyse la table ProductCatalog pour rechercher des éléments dont le prix est inférieur à 0. L'extrait spécifie les paramètres facultatifs suivants : • Une expression de filtre pour récupérer uniquement les éléments dont le prix est inférieur à 0 (condition d'erreur). • Une liste d'attributs pour récupérer des éléments dans les résultats de la requête. Map<String, AttributeValue> expressionAttributeValues = new HashMap<String, AttributeValue>(); expressionAttributeValues.put(":val", new AttributeValue().withN("0")); ScanRequest scanRequest = new ScanRequest() .withTableName("ProductCatalog") .withFilterExpression("Price < :val") .withProjectionExpression("Id") .withExpressionAttributeValues(expressionAttributeValues); ScanResult result = client.scan(scanRequest); for (Map<String, AttributeValue> item : result.getItems()) { printItem(item); } Vous pouvez également le cas échéant limiter la taille de la page, ou le nombre d'éléments par page, en utilisant la méthode withLimit de la demande d'analyse. Chaque fois que vous exécutez la méthode scan, vous obtenez une page de résultats ayant le nombre d'éléments spécifié. Pour récupérer la page suivante, vous exécutez à nouveau la méthode scan en fournissant la valeur de la clé primaire du dernier élément de la page précédente afin que la méthode scan puisse renvoyer l'ensemble d'éléments suivant. Vous fournissez ces informations dans la demande en utilisant la méthode withExclusiveStartKey. À l'origine, le paramètre de cette méthode peut être null. Pour récupérer les pages suivantes, vous devez mettre à jour cette valeur de propriété avec la clé primaire du dernier élément de la page précédente. L'extrait de code Java suivant analyse la table ProductCatalog. Dans la demande, les méthodes withLimit et withExclusiveStartKey sont utilisées. La boucle do/while continue d'analyser une page à la fois jusqu'à ce que la méthode getLastEvaluatedKey du résultat renvoie une valeur null. Map<String, AttributeValue> lastKeyEvaluated = null; do { API Version 2012-08-10 315 Amazon DynamoDB Manuel du développeur Analyse ScanRequest scanRequest = new ScanRequest() .withTableName("ProductCatalog") .withLimit(10) .withExclusiveStartKey(lastKeyEvaluated); ScanResult result = client.scan(scanRequest); for (Map<String, AttributeValue> item : result.getItems()){ printItem(item); } lastKeyEvaluated = result.getLastEvaluatedKey(); } while (lastKeyEvaluated != null); Exemple - Analyse avec Java L'exemple de code Java suivant fournit un exemple de travail qui analyse la table ProductCatalog pour rechercher des éléments dont le prix est inférieur à 100. Note Le SDK pour Java fournit également un modèle de persistance d'objet, ce qui vous permet de mapper vos classes côté client sur des tables DynamoDB. Cette approche peut réduire la quantité de code que vous avez à écrire. Pour de plus amples informations, veuillez consulter Java : DynamoDBMapper (p. 79). Note Cet exemple de code suppose que vous ayez déjà chargé des données dans DynamoDB pour votre compte en suivant les instructions de la section Création de tables et chargement d'exemples de données (p. 167). Pour obtenir les instructions pas à pas afin d'exécuter l'exemple suivant, consultez Exemples de Code Java (p. 173). // Copyright 2012-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. // Licensed under the Apache License, Version 2.0. package com.amazonaws.codesamples.document; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import import import import import import import com.amazonaws.auth.profile.ProfileCredentialsProvider; com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient; com.amazonaws.services.dynamodbv2.document.DynamoDB; com.amazonaws.services.dynamodbv2.document.Item; com.amazonaws.services.dynamodbv2.document.ItemCollection; com.amazonaws.services.dynamodbv2.document.ScanOutcome; com.amazonaws.services.dynamodbv2.document.Table; public class DocumentAPIScan { static DynamoDB dynamoDB = new DynamoDB(new AmazonDynamoDBClient(new ProfileCredentialsProvider())); static String tableName = "ProductCatalog"; public static void main(String[] args) throws Exception { API Version 2012-08-10 316 Amazon DynamoDB Manuel du développeur Analyse findProductsForPriceLessThanZero(); } private static void findProductsForPriceLessThanZero() { Table table = dynamoDB.getTable(tableName); Map<String, Object> expressionAttributeValues = new HashMap<String, Object>(); expressionAttributeValues.put(":pr", 100); ItemCollection<ScanOutcome> items = table.scan( "Price < :pr", //FilterExpression "Id, Title, ProductCategory, Price", //ProjectionExpression null, //ExpressionAttributeNames - not used in this example expressionAttributeValues); System.out.println("Scan of " + tableName + " for items with a price less than 100."); Iterator<Item> iterator = items.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next().toJSONPretty()); } } } Exemple - Analyse parallèle à l'aide de Java L'exemple de code Java suivant montre une analyse parallèle. Le programme supprime et recrée une table nommée ParallelScanTest, puis charge la table avec des données. Lorsque la charge de données est terminée, le programme gère dynamiquement plusieurs threads et émet des demandes d'analyse parallèles. Le programme imprime des statistiques de temps d'exécution pour chaque demande parallèle. Note Le SDK pour Java fournit également un modèle de persistance d'objet, ce qui vous permet de mapper vos classes côté client sur des tables DynamoDB. Cette approche peut réduire la quantité de code que vous avez à écrire. Pour de plus amples informations, veuillez consulter Java : DynamoDBMapper (p. 79). Note Cet exemple de code suppose que vous ayez déjà chargé des données dans DynamoDB pour votre compte en suivant les instructions de la section Création de tables et chargement d'exemples de données (p. 167). Pour obtenir les instructions pas à pas afin d'exécuter l'exemple suivant, consultez Exemples de Code Java (p. 173). // Copyright 2012-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. API Version 2012-08-10 317 Amazon DynamoDB Manuel du développeur Analyse // Licensed under the Apache License, Version 2.0. package com.amazonaws.codesamples.document; import import import import import import import import java.util.ArrayList; java.util.Arrays; java.util.HashSet; java.util.Iterator; java.util.List; java.util.concurrent.ExecutorService; java.util.concurrent.Executors; java.util.concurrent.TimeUnit; import import import import import import import import import import import import import com.amazonaws.AmazonServiceException; com.amazonaws.auth.profile.ProfileCredentialsProvider; com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient; com.amazonaws.services.dynamodbv2.document.DynamoDB; com.amazonaws.services.dynamodbv2.document.Item; com.amazonaws.services.dynamodbv2.document.ItemCollection; com.amazonaws.services.dynamodbv2.document.ScanOutcome; com.amazonaws.services.dynamodbv2.document.Table; com.amazonaws.services.dynamodbv2.document.spec.ScanSpec; com.amazonaws.services.dynamodbv2.model.AttributeDefinition; com.amazonaws.services.dynamodbv2.model.KeySchemaElement; com.amazonaws.services.dynamodbv2.model.KeyType; com.amazonaws.services.dynamodbv2.model.ProvisionedThroughput; public class DocumentAPIParallelScan { // total number of sample items static int scanItemCount = 300; // number of items each scan request should return static int scanItemLimit = 10; // number of logical segments for parallel scan static int parallelScanThreads = 16; // table that will be used for scanning static String parallelScanTestTableName = "ParallelScanTest"; static DynamoDB dynamoDB = new DynamoDB( new AmazonDynamoDBClient(new ProfileCredentialsProvider())); public static void main(String[] args) throws Exception { try { // Clean up the table deleteTable(parallelScanTestTableName); createTable(parallelScanTestTableName, 10L, 5L, "Id", "N"); // Upload sample data for scan uploadSampleProducts(parallelScanTestTableName, scanItemCount); // Scan the table using multiple threads parallelScan(parallelScanTestTableName, scanItemLimit, parallelScanThreads); } catch (AmazonServiceException ase) { System.err.println(ase.getMessage()); API Version 2012-08-10 318 Amazon DynamoDB Manuel du développeur Analyse } } private static void parallelScan(String tableName, int itemLimit, int numberOfThreads) { System.out.println("Scanning " + tableName + " using " + numberOfThreads + " threads " + itemLimit + " items at a time"); ExecutorService executor = Executors.newFixedThreadPool(numberOfThreads); // Divide DynamoDB table into logical segments // Create one task for scanning each segment // Each thread will be scanning one segment int totalSegments = numberOfThreads; for (int segment = 0; segment < totalSegments; segment++) { // Runnable task that will only scan one segment ScanSegmentTask task = new ScanSegmentTask(tableName, itemLimit, totalSegments, segment); // Execute the task executor.execute(task); } shutDownExecutorService(executor); } // Runnable task for scanning a single segment of a DynamoDB table private static class ScanSegmentTask implements Runnable { // DynamoDB table to scan private String tableName; // number of items each scan request should return private int itemLimit; // Total number of segments // Equals to total number of threads scanning the table in parallel private int totalSegments; // Segment that will be scanned with by this task private int segment; public ScanSegmentTask(String tableName, int itemLimit, int totalSegments, int segment) { this.tableName = tableName; this.itemLimit = itemLimit; this.totalSegments = totalSegments; this.segment = segment; } @Override public void run() { System.out.println("Scanning " + tableName + " segment " + segment + " out of " + totalSegments + " segments " + itemLimit + " items at a time..."); int totalScannedItemCount = 0; API Version 2012-08-10 319 Amazon DynamoDB Manuel du développeur Analyse Table table = dynamoDB.getTable(tableName); try { ScanSpec spec = new ScanSpec() .withMaxResultSize(itemLimit) .withTotalSegments(totalSegments) .withSegment(segment); ItemCollection<ScanOutcome> items = table.scan(spec); Iterator<Item> iterator = items.iterator(); Item currentItem = null; while (iterator.hasNext()) { totalScannedItemCount++; currentItem = iterator.next(); System.out.println(currentItem.toString()); } } catch (Exception e) { System.err.println(e.getMessage()); } finally { System.out.println("Scanned " + totalScannedItemCount + " items from segment " + segment + " out of " + totalSegments + " of " + tableName); } } } private static void uploadSampleProducts(String tableName, int itemCount) { System.out.println("Adding " + itemCount + " sample items to " + tableName); for (int productIndex = 0; productIndex < itemCount; productIndex++) { uploadProduct(tableName, productIndex); } } private static void uploadProduct(String tableName, int productIndex) { Table table = dynamoDB.getTable(tableName); try { System.out.println("Processing record #" + productIndex); Item item = new Item() .withPrimaryKey("Id", productIndex) .withString("Title", "Book " + productIndex + " Title") .withString("ISBN", "111-1111111111") .withStringSet( "Authors", new HashSet<String>(Arrays.asList("Author1"))) .withNumber("Price", 2) .withString("Dimensions", "8.5 x 11.0 x 0.5") .withNumber("PageCount", 500) .withBoolean("InPublication", true) .withString("ProductCategory", "Book"); API Version 2012-08-10 320 Amazon DynamoDB Manuel du développeur Analyse table.putItem(item); } catch (Exception e) { System.err.println("Failed to create item " + productIndex + " in " + tableName); System.err.println(e.getMessage()); } } private static void deleteTable(String tableName){ try { Table table = dynamoDB.getTable(tableName); table.delete(); System.out.println("Waiting for " + tableName + " to be deleted...this may take a while..."); table.waitForDelete(); } catch (Exception e) { System.err.println("Failed to delete table " + tableName); e.printStackTrace(System.err); } } private static void createTable( String tableName, long readCapacityUnits, long writeCapacityUnits, String partitionKeyName, String partitionKeyType) { createTable(tableName, readCapacityUnits, writeCapacityUnits, partitionKeyName, partitionKeyType, null, null); } private static void createTable( String tableName, long readCapacityUnits, long writeCapacityUnits, String partitionKeyName, String partitionKeyType, String sortKeyName, String sortKeyType) { try { System.out.println("Creating table " + tableName); List<KeySchemaElement> keySchema = new ArrayList<KeySchemaElement>(); keySchema.add(new KeySchemaElement() .withAttributeName(partitionKeyName) .withKeyType(KeyType.HASH)); //Partition key List<AttributeDefinition> attributeDefinitions = new ArrayList<AttributeDefinition>(); attributeDefinitions.add(new AttributeDefinition() .withAttributeName(partitionKeyName) .withAttributeType(partitionKeyType)); if (sortKeyName != null){ keySchema.add(new KeySchemaElement() .withAttributeName(sortKeyName) .withKeyType(KeyType.RANGE)); //Sort key attributeDefinitions.add(new AttributeDefinition() .withAttributeName(sortKeyName) .withAttributeType(sortKeyType)); API Version 2012-08-10 321 Amazon DynamoDB Manuel du développeur Analyse } Table table = dynamoDB.createTable(tableName, keySchema, attributeDefinitions, new ProvisionedThroughput() .withReadCapacityUnits(readCapacityUnits) .withWriteCapacityUnits(writeCapacityUnits)); System.out.println("Waiting for " + tableName + " to be created...this may take a while..."); table.waitForActive(); } catch (Exception e) { System.err.println("Failed to create table " + tableName); e.printStackTrace(System.err); } } private static void shutDownExecutorService(ExecutorService executor) { executor.shutdown(); try { if (!executor.awaitTermination(10, TimeUnit.SECONDS)) { executor.shutdownNow(); } } catch (InterruptedException e) { executor.shutdownNow(); // Preserve interrupt status Thread.currentThread().interrupt(); } } } Analyse des tables et des index : .NET L'opération Scan lit tous les éléments dans une table ou un index. Pour en savoir plus sur la performance associée aux opérations d'analyse et de requêtes, consultez Utilisation des requêtes et des analyses (p. 290). Les étapes d'analyse d'une table à l'aide de l'API de bas niveau AWS SDK pour NET sont les suivantes : 1. Créez une instance de la classe AmazonDynamoDBClient. 2. Créez une instance de la classe ScanRequest et fournissez les paramètres d'opération de l'analyse. Le seul paramètre requis est le nom de la table. 3. Exécutez la méthode Scan et fournissez l'objet QueryRequest que vous avez créé à l'étape précédente. La table Reply suivante stocke les réponses pour les threads de forum. API Version 2012-08-10 322 Amazon DynamoDB Manuel du développeur Analyse >Reply ( <emphasis role="underline">Id</emphasis>, <emphasis role="underline">ReplyDateTime</emphasis>, Message, PostedBy ) La table gère toutes les réponses pour divers threads de forum. Par conséquent, la clé primaire est composée de l'Id (clé de partition) et de ReplyDateTime (clé de tri). L'extrait de code C# suivant analyse la totalité de la table. L'instance ScanRequest spécifie le nom de la table à analyser. AmazonDynamoDBClient client = new AmazonDynamoDBClient(); var request = new ScanRequest { TableName = "Reply", }; var response = client.Scan(request); var result = response.ScanResult; foreach (Dictionary<string, AttributeValue> item in response.ScanResult.Items) { // Process the result. PrintItem(item); } Spécification de paramètres facultatifs La méthode Scan prend en charge plusieurs paramètres facultatifs. Par exemple, vous pouvez le cas échéant utiliser un filtre d'analyse pour filtrer le résultat d'analyse. Dans un filtre d'analyse, vous pouvez spécifier une condition et un nom d'attribut sur lesquels vous voulez que la condition soit évaluée. Pour plus d'informations, consultez Scan. Le code C# suivant analyse la table ProductCatalog pour rechercher des éléments dont le prix est inférieur à 0. L'échantillon spécifie les paramètres facultatifs suivants : • Un paramètre FilterExpression pour récupérer uniquement les éléments dont le prix est inférieur à 0 (condition d'erreur). • Un paramètre ProjectionExpression pour spécifier les attributs à récupérer pour les éléments des résultats de la requête. L'extrait de code C# suivant analyse la table ProductCatalog pour rechercher tous les éléments dont le prix est inférieur à 0. var forumScanRequest = new ScanRequest { TableName = "ProductCatalog", // Optional parameters. ExpressionAttributeValues = new Dictionary<string,AttributeValue> { {":val", new AttributeValue { N = "0" }} }, FilterExpression = "Price < :val", ProjectionExpression = "Id" }; Vous pouvez aussi limiter le cas échéant la taille de la page ou le nombre d'éléments par page, en ajoutant le paramètre facultatif Limit. Chaque fois que vous exécutez la méthode Scan, vous obtenez API Version 2012-08-10 323 Amazon DynamoDB Manuel du développeur Analyse une page de résultats ayant le nombre d'éléments spécifié. Pour récupérer la page suivante, vous exécutez à nouveau la méthode Scan en fournissant la valeur de la clé primaire du dernier élément de la page précédente afin que la méthode Scan puisse renvoyer l'ensemble d'éléments suivant. Vous fournissez ces informations dans la demande en définissant la propriété ExclusiveStartKey. Au départ, cette propriété peut être null. Pour récupérer les pages suivantes, vous devez mettre à jour cette valeur de propriété avec la clé primaire du dernier élément de la page précédente. L'extrait de code C# suivant analyse la table ProductCatalog. Dans la demande, il spécifie les paramètres facultatifs Limit et ExclusiveStartKey. La boucle do/while continue d'analyser une page à la fois jusqu'à ce que LastEvaluatedKey renvoie une valeur null. Dictionary<string, AttributeValue> lastKeyEvaluated = null; do { var request = new ScanRequest { TableName = "ProductCatalog", Limit = 10, ExclusiveStartKey = lastKeyEvaluated }; var response = client.Scan(request); foreach (Dictionary<string, AttributeValue> item in response.Items) { PrintItem(item); } lastKeyEvaluated = response.LastEvaluatedKey; } while (lastKeyEvaluated != null && lastKeyEvaluated.Count != 0); Exemple - Analyse à l'aide de .NET L'exemple de code C# suivant fournit un exemple de travail qui analyse la table ProductCatalog pour rechercher des éléments dont le prix est inférieur à 0. Pour obtenir les instructions pas à pas afin de tester l'exemple suivant, consultez Exemples de code .NET (p. 175). using using using using using System; System.Collections.Generic; Amazon.DynamoDBv2; Amazon.DynamoDBv2.Model; Amazon.Runtime; namespace com.amazonaws.codesamples { class LowLevelScan { private static AmazonDynamoDBClient client = new AmazonDynamoDBClient(); static void Main(string[] args) { try { FindProductsForPriceLessThanZero(); API Version 2012-08-10 324 Amazon DynamoDB Manuel du développeur Analyse Console.WriteLine("Example complete. To continue, press Enter"); Console.ReadLine(); } catch (Exception e) { Console.WriteLine(e.Message); Console.WriteLine("To continue, press Enter"); Console.ReadLine(); } } private static void FindProductsForPriceLessThanZero() { Dictionary<string, AttributeValue> lastKeyEvaluated = null; do { var request = new ScanRequest { TableName = "ProductCatalog", Limit = 2, ExclusiveStartKey = lastKeyEvaluated, ExpressionAttributeValues = new Dictionary<string,AttributeValue> { {":val", new AttributeValue { N = "0" }} }, FilterExpression = "Price < :val", ProjectionExpression = "Id, Title, Price" }; var response = client.Scan(request); foreach (Dictionary<string, AttributeValue> item in response.Items) { Console.WriteLine("\nScanThreadTableUsePaging printing....."); PrintItem(item); } lastKeyEvaluated = response.LastEvaluatedKey; } while (lastKeyEvaluated != null && lastKeyEvaluated.Count != 0); Console.WriteLine("To continue, press Enter"); Console.ReadLine(); } private static void PrintItem( Dictionary<string, AttributeValue> attributeList) { foreach (KeyValuePair<string, AttributeValue> kvp in attributeList) { string attributeName = kvp.Key; AttributeValue value = kvp.Value; Console.WriteLine( API Version 2012-08-10 325 Amazon DynamoDB Manuel du développeur Analyse attributeName + " " + (value.S == null ? "" : "S=[" + (value.N == null ? "" : "N=[" + (value.SS == null ? "" : "SS=[" value.SS.ToArray()) + "]") + (value.NS == null ? "" : "NS=[" value.NS.ToArray()) + "]") ); } value.S + "]") + value.N + "]") + + string.Join(",", + string.Join(",", Console.WriteLine("************************************************"); } } } Exemple - Analyse parallèle à l'aide de .NET L'exemple de code C# suivant montre une analyse parallèle. Le programme supprime et recrée la table ProductCatalog, puis charge la table avec les données. Lorsque la charge de données est terminée, le programme gère dynamiquement plusieurs threads et émet des demandes Scan parallèles. Enfin, le programme imprime un résumé des statistiques d'exécution. Pour obtenir les instructions pas à pas afin de tester l'exemple suivant, consultez Exemples de code .NET (p. 175). using using using using using using using System; System.Collections.Generic; System.Threading; System.Threading.Tasks; Amazon.DynamoDBv2; Amazon.DynamoDBv2.Model; Amazon.Runtime; namespace com.amazonaws.codesamples { class LowLevelParallelScan { private static AmazonDynamoDBClient client = new AmazonDynamoDBClient(); private static string tableName = "ProductCatalog"; private static int exampleItemCount = 100; private static int scanItemLimit = 10; private static int totalSegments = 5; static void Main(string[] args) { try { DeleteExampleTable(); CreateExampleTable(); UploadExampleData(); ParallelScanExampleTable(); } catch (AmazonDynamoDBException e) { Console.WriteLine(e.Message); } catch (AmazonServiceException e) { Console.WriteLine(e.Message); } API Version 2012-08-10 326 Amazon DynamoDB Manuel du développeur Analyse catch (Exception e) { Console.WriteLine(e.Message); } Console.WriteLine("To continue, press Enter"); Console.ReadLine(); } private static void ParallelScanExampleTable() { Console.WriteLine("\n*** Creating {0} Parallel Scan Tasks to scan {1}", totalSegments, tableName); Task[] tasks = new Task[totalSegments]; for (int segment = 0; segment < totalSegments; segment++) { int tmpSegment = segment; Task task = Task.Factory.StartNew(() => { ScanSegment(totalSegments, tmpSegment); }); tasks[segment] = task; } Console.WriteLine("All scan tasks are created, waiting for them to complete."); Task.WaitAll(tasks); Console.WriteLine("All scan tasks are completed."); } private static void ScanSegment(int totalSegments, int segment) { Console.WriteLine("*** Starting to Scan Segment {0} of {1} out of {2} total segments ***", segment, tableName, totalSegments); Dictionary<string, AttributeValue> lastEvaluatedKey = null; int totalScannedItemCount = 0; int totalScanRequestCount = 0; do { var request = new ScanRequest { TableName = tableName, Limit = scanItemLimit, ExclusiveStartKey = lastEvaluatedKey, Segment = segment, TotalSegments = totalSegments }; var response = client.Scan(request); lastEvaluatedKey = response.LastEvaluatedKey; totalScanRequestCount++; totalScannedItemCount += response.ScannedCount; foreach (var item in response.Items) { Console.WriteLine("Segment: {0}, Scanned Item with Title: {1}", segment, item["Title"].S); } } while (lastEvaluatedKey.Count != 0); API Version 2012-08-10 327 Amazon DynamoDB Manuel du développeur Analyse Console.WriteLine("*** Completed Scan Segment {0} of {1}. TotalScanRequestCount: {2}, TotalScannedItemCount: {3} ***", segment, tableName, totalScanRequestCount, totalScannedItemCount); } private static void UploadExampleData() { Console.WriteLine("\n*** Uploading {0} Example Items to {1} Table***", exampleItemCount, tableName); Console.Write("Uploading Items: "); for (int itemIndex = 0; itemIndex < exampleItemCount; itemIndex+ +) { Console.Write("{0}, ", itemIndex); CreateItem(itemIndex.ToString()); } Console.WriteLine(); } private static void CreateItem(string itemIndex) { var request = new PutItemRequest { TableName = tableName, Item = new Dictionary<string, AttributeValue>() { { "Id", new AttributeValue { N = itemIndex }}, { "Title", new AttributeValue { S = "Book " + itemIndex + " Title" }}, { "ISBN", new AttributeValue { S = "11-11-11-11" }}, { "Authors", new AttributeValue { SS = new List<string>{"Author1", "Author2" }}}, { "Price", new AttributeValue { N = "20.00" }}, { "Dimensions", new AttributeValue { S = "8.5x11.0x.75" }}, { "InPublication", new AttributeValue { BOOL = false } } } }; client.PutItem(request); } private static void CreateExampleTable() { Console.WriteLine("\n*** Creating {0} Table ***", tableName); var request = new CreateTableRequest { AttributeDefinitions = new List<AttributeDefinition>() { new AttributeDefinition { AttributeName = "Id", AttributeType = "N" } }, KeySchema = new List<KeySchemaElement> { new KeySchemaElement { AttributeName = "Id", KeyType = "HASH" //Partition key API Version 2012-08-10 328 Amazon DynamoDB Manuel du développeur Analyse } }, ProvisionedThroughput = new ProvisionedThroughput { ReadCapacityUnits = 5, WriteCapacityUnits = 6 }, TableName = tableName }; var response = client.CreateTable(request); var result = response; var tableDescription = result.TableDescription; Console.WriteLine("{1}: {0} \t ReadsPerSec: {2} \t WritesPerSec: {3}", tableDescription.TableStatus, tableDescription.TableName, tableDescription.ProvisionedThroughput.ReadCapacityUnits, tableDescription.ProvisionedThroughput.WriteCapacityUnits); string status = tableDescription.TableStatus; Console.WriteLine(tableName + " - " + status); WaitUntilTableReady(tableName); } private static void DeleteExampleTable() { try { Console.WriteLine("\n*** Deleting {0} Table ***", tableName); var request = new DeleteTableRequest { TableName = tableName }; var response = client.DeleteTable(request); var result = response; Console.WriteLine("{0} is being deleted...", tableName); WaitUntilTableDeleted(tableName); } catch (ResourceNotFoundException) { Console.WriteLine("{0} Table delete failed: Table does not exist", tableName); } } private static void WaitUntilTableReady(string tableName) { string status = null; // Let us wait until table is created. Call DescribeTable. do { System.Threading.Thread.Sleep(5000); // Wait 5 seconds. API Version 2012-08-10 329 Amazon DynamoDB Manuel du développeur Analyse try { var res = client.DescribeTable(new DescribeTableRequest { TableName = tableName }); Console.WriteLine("Table name: {0}, status: {1}", res.Table.TableName, res.Table.TableStatus); status = res.Table.TableStatus; } catch (ResourceNotFoundException) { // DescribeTable is eventually consistent. So you might // get resource not found. So we handle the potential exception. } } while (status != "ACTIVE"); } private static void WaitUntilTableDeleted(string tableName) { string status = null; // Let us wait until table is deleted. Call DescribeTable. do { System.Threading.Thread.Sleep(5000); // Wait 5 seconds. try { var res = client.DescribeTable(new DescribeTableRequest { TableName = tableName }); Console.WriteLine("Table name: {0}, status: {1}", res.Table.TableName, res.Table.TableStatus); status = res.Table.TableStatus; } catch (ResourceNotFoundException) { Console.WriteLine("Table name: {0} is not found. It is deleted", tableName); return; } } while (status == "DELETING"); } } } Analyse des tables et des index : PHP L'opération Scan lit tous les éléments dans une table ou un index. Pour en savoir plus sur la performance associée aux opérations d'analyse et de requêtes, consultez Utilisation des requêtes et des analyses (p. 290). Voici les étapes courantes pour l'utilisation du kit SDK AWS pour PHP. API Version 2012-08-10 330 Amazon DynamoDB Manuel du développeur Analyse 1. Créer une instance du client DynamoDB. 2. Fournir les paramètres d'une opération DynamoDB, y compris les paramètres facultatifs. 3. Charger la réponse à partir de DynamoDB dans une variable locale pour votre application. Pensez à utiliser la table Reply suivante qui stocke les réponses de différents threads de forum. Reply ( Id, ReplyDateTime, Message, PostedBy ) La table gère toutes les réponses pour divers threads de forum. Par conséquent, la clé primaire est composée de l'Id (clé de partition) et de ReplyDateTime (clé de tri). L'extrait de code PHP suivant analyse la table. Note Cet exemple de code suppose que vous ayez déjà chargé des données dans DynamoDB pour votre compte en suivant les instructions de la section Création de tables et chargement d'exemples de données (p. 167). Sinon, vous pouvez charger les données en utilisant les instructions de la rubrique Création d'exemples de table et de chargement de données à l'aide du kit de développement (SDK) AWS pour PHP (p. 624). Pour obtenir les instructions pas à pas afin d'exécuter l'exemple suivant, consultez Exemples de Code PHP (p. 177). require 'vendor/autoload.php'; $sdk = new Aws\Sdk([ 'region' => 'us-west-2', 'version' => 'latest' ]); $dynamodb = $sdk->createDynamoDb(); $response = $dynamodb->scan([ 'TableName' => 'Reply' ]); foreach ($response['Items'] as $key => $value) { echo 'Id: ' . $value['Id']['S'] . "\n"; echo 'ReplyDateTime: ' . $value['ReplyDateTime']['S'] . "\n"; echo 'Message: ' . $value['Message']['S'] . "\n"; echo 'PostedBy: ' . $value['PostedBy']['S'] . "\n"; echo "\n"; } Spécification de paramètres facultatifs La fonction scan prend en charge plusieurs paramètres facultatifs. Par exemple, vous pouvez le cas échéant utiliser une expression de filtre pour filtrer le résultat d'analyse. Dans une expression de filtre, vous spécifiez une condition et un nom d'attribut sur lequel vous voulez que la condition soit évaluée. Pour plus d'informations, consultez Scan. Le code PHP suivant analyse la table ProductCatalog pour rechercher les éléments dont le prix (de façon incorrecte) est inférieur ou égal à zéro. L'échantillon spécifie les paramètres facultatifs suivants : API Version 2012-08-10 331 Amazon DynamoDB Manuel du développeur Analyse • FilterExpression pour récupérer uniquement les éléments dont le prix est inférieur ou égal à zéro. • ProjectionExpression pour spécifier les attributs afin de récupérer les éléments des résultats de la requête $response = $dynamodb->scan([ 'TableName' => 'ProductCatalog', 'ProjectionExpression' => 'Id, Price', 'ExpressionAttributeValues' => [ ':val1' => ['N' => '0']] , 'FilterExpression' => 'Price <= :val1', ]); foreach ($response['Items'] as $key => $value) { echo 'Id: ' . $value['Id']['N'] . ' Price: ' . $value['Price']['N'] . "\n"; echo "\n"; } Vous pouvez aussi limiter à titre facultatif la taille de la page, le nombre d'éléments par page, en ajoutant le paramètre facultatif Limit. Chaque fois que vous exécutez la fonction scan, vous obtenez une page de résultats avec un nombre spécifié d'éléments. Pour récupérer la page suivante, vous exécutez à nouveau la fonction scan en fournissant la valeur de clé primaire du dernier élément de la page précédente afin que la fonction scan puisse retourner le prochain ensemble d'éléments. Vous fournissez ces informations dans la demande en définissant la propriété ExclusiveStartKey. Au départ, cette propriété peut être null. Pour récupérer les pages suivantes, vous devez mettre à jour cette valeur de propriété avec la clé primaire du dernier élément de la page précédente. L'extrait de code PHP suivant analyse la table ProductCatalog. Dans la demande, il spécifie les paramètres facultatifs Limit et ExclusiveStartKey. $tableName = 'ProductCatalog'; # The Scan operation is paginated. Issue the Scan request multiple times. do { echo "Scanning table $tableName\n"; $request = [ 'TableName' => $tableName, 'ExpressionAttributeValues' => [ ':val1' => ['N' => '201'] ], 'FilterExpression' => 'Price < :val1', 'Limit' => 2 ]; # Add the ExclusiveStartKey if we got one back in the previous response if(isset($response) && isset($response['LastEvaluatedKey'])) { $request['ExclusiveStartKey'] = $response['LastEvaluatedKey']; } $response = $dynamodb->scan($request); foreach ($response['Items'] as $key => $value) { echo 'Id: ' . $value['Id']['N'] . "\n"; echo 'Title: ' . $value['Title']['S'] . "\n"; API Version 2012-08-10 332 Amazon DynamoDB Manuel du développeur Analyse echo 'Price: ' . $value['Price']['N'] . "\n"; echo "\n"; } } # If there is no LastEvaluatedKey in the response, there are no more items matching this Scan while(isset($response['LastEvaluatedKey'])); Exemple : Chargement des données avec PHP L'exemple de code PHP suivant prépare des exemples de données qui seront utilisés par les exemples ultérieurs. Le programme supprime et recrée la table ProductCatalog, puis charge la table avec les données. Note Pour obtenir les instructions pas à pas afin d'exécuter ces exemples de code, consultez Exemples de Code PHP (p. 177). <?php require 'vendor/autoload.php'; date_default_timezone_set('UTC'); use Aws\DynamoDb\Exception\DynamoDbException; $sdk = new Aws\Sdk([ 'region' => 'us-west-2', 'version' => 'latest' ]); $dynamodb = $sdk->createDynamoDb(); $tableName = 'ProductCatalog'; // Delete an old DynamoDB table echo "Deleting the table...\n"; try { $response = $dynamodb->deleteTable([ 'TableName' => $tableName ]); $dynamodb->waitUntil('TableNotExists', [ 'TableName' => $tableName, '@waiter' => [ 'delay' => 5, 'maxAttempts' => 20 ] ]); echo "The table has been deleted.\n"; echo "The table {$tableName} has been deleted.\n"; } catch (DynamoDbException $e) { echo $e->getMessage() . "\n"; exit ("Unable to delete table $tableName\n"); API Version 2012-08-10 333 Amazon DynamoDB Manuel du développeur Analyse } // Create a new DynamoDB table echo "# Creating table $tableName...\n"; try { $response = $dynamodb->createTable([ 'TableName' => $tableName, 'AttributeDefinitions' => [ [ 'AttributeName' => 'Id', 'AttributeType' => 'N' ] ], 'KeySchema' => [ [ 'AttributeName' => 'Id', 'KeyType' => 'HASH' ] ], 'ProvisionedThroughput' => [ 'ReadCapacityUnits' => 5, 'WriteCapacityUnits' => 6 ] ]); //Partition key $dynamodb->waitUntil('TableExists', [ 'TableName' => $tableName, '@waiter' => [ 'delay' => 5, 'maxAttempts' => 20 ] ]); echo "Table {$tableName} has been created.\n"; } catch (DynamoDbException $e) { echo $e->getMessage() . "\n"; exit ("Unable to create table $tableName\n"); } // Populate DynamoDB table echo "# Populating Items to $tableName...\n"; for ($i = 1; $i <= 100; $i++) { $response = $dynamodb->putItem([ 'TableName' => $tableName, 'Item' => [ 'Id' => [ 'N' => "$i" ], // Primary Key 'Title' => [ 'S' => "Book {$i} Title" ], 'ISBN' => [ 'S' => '111-1111111111' ], 'Price' => [ 'N' => "25" ], 'Authors' => [ 'SS' => ['Author1', 'Author2']] ] ]); $response = $dynamodb->getItem([ API Version 2012-08-10 334 Amazon DynamoDB Manuel du développeur Analyse 'TableName' => 'ProductCatalog', 'Key' => [ 'Id' => [ 'N' => "$i" ] ] ]); echo "Item populated: {$response['Item']['Title']['S']}\n"; sleep(1); } echo "{$tableName} is populated with items.\n"; ?> Exemple - Analyse avec PHP L'exemple de code PHP suivant effectue une opération Scan en série sur la table ProductCatalog. Note Avant d'exécuter ce programme, vous devrez remplir la table ProductTable avec des données. Pour en savoir plus, consultez Exemple : Chargement des données avec PHP (p. 333). Pour obtenir les instructions pas à pas afin d'exécuter ces exemples de code, consultez Exemples de Code PHP (p. 177). <?php require 'vendor/autoload.php'; date_default_timezone_set('UTC'); use Aws\DynamoDb\Exception\DynamoDbException; $sdk = new Aws\Sdk([ 'region' => 'us-west-2', 'version' => 'latest' ]); $dynamodb = $sdk->createDynamoDb(); $tableName = 'ProductCatalog'; $params = [ 'TableName' => $tableName, 'ExpressionAttributeValues' => [ ':val1' => ['S' => 'Book'] ], 'FilterExpression' => 'contains (Title, :val1)', 'Limit' => 10 ]; // Execute scan operations until the entire table is scanned $count = 0; do { $response = $dynamodb->scan ( $params ); $items = $response->get ( 'Items' ); $count = $count + count ( $items ); API Version 2012-08-10 335 Amazon DynamoDB Manuel du développeur Analyse // Do something with the $items foreach ( $items as $item ) { echo "Scanned item with Title \"{$item['Title']['S']}\".\n"; } // Set parameters for next scan $params ['ExclusiveStartKey'] = $response ['LastEvaluatedKey']; } while ( $params ['ExclusiveStartKey'] ); echo "{$tableName} table scanned completely. {$count} items found.\n"; ?> Exemple - Analyse parallèle avec PHP L'exemple de code PHP suivant illustre une analyse parallèle, exécutant plusieurs demandes Scan simultanées. Enfin, le programme imprime un résumé des statistiques d'exécution. Note Avant d'exécuter ce programme, vous devrez remplir la table ProductTable avec des données. Pour en savoir plus, consultez Exemple : Chargement des données avec PHP (p. 333). Pour obtenir les instructions pas à pas afin d'exécuter ces exemples de code, consultez Exemples de Code PHP (p. 177). <?php require 'vendor/autoload.php'; date_default_timezone_set('UTC'); use Aws\DynamoDb\Exception\DynamoDbException; use Aws\CommandPool; $sdk = new Aws\Sdk([ 'region' => 'us-west-2', 'version' => 'latest' ]); $dynamodb = $sdk->createDynamoDb(); $tableName = 'ProductCatalog'; $totalSegments = 5; $params = array( 'TableName' => $tableName, 'ExpressionAttributeValues' => array ( ':val1' => array('S' => 'Book') ) , 'FilterExpression' => 'contains (Title, :val1)', 'Limit' => 10, 'TotalSegments' => $totalSegments ); // Build an array of Scan commands - one for each segment $commands = []; API Version 2012-08-10 336 Amazon DynamoDB Manuel du développeur Utilisation des index for ($segment = 0; $segment < $totalSegments; $segment++) { $params['Segment'] = $segment; $commands[] = $dynamodb->getCommand('Scan',$params); } // Setup a command pool to run the Scan commands concurrently // The 'fulfilled' callback will process the results from each command // The 'rejected' callback will tell why the command failed $pool = new CommandPool($dynamodb,$commands,[ 'fulfilled' => function($result, $iterKey, $aggregatePromise) { echo "\nResults from segment $iterKey\n"; // Do something with the items foreach ($result['Items'] as $item) { echo "Scanned item with Title \"" . $item['Title']['S'] . "\"\n"; } }, 'rejected' => function ($reason, $iterKey, $aggregatePromise) { echo "Failed {$iterKey}: {$reason}\n"; } ]); $promise = $pool->promise(); $promise->wait(); ?> Amélioration de l'accès aux données avec les index secondaires Rubriques • Index secondaires globaux (p. 340) • Index secondaires locaux (p. 387) Amazon DynamoDB fournit un accès rapide aux éléments d'une table en spécifiant les valeurs de clé principale. Cependant, il serait utile pour de nombreuses applications de disposer d'une ou de plusieurs clés secondaires (ou alternatives) permettant un accès efficace aux données présentant d'autres attributs que la clé primaire. Pour ce faire, vous pouvez créer un ou plusieurs index secondaires pour une table, et effectuer des requêtes Query ou Scan portant sur ces index. Un index secondaire est une structure de données qui contient un sous-ensemble d'attributs d'une table, ainsi que d'une autre clé pour prendre en charge des opérations Query. Vous pouvez récupérer les données de l'index à l'aide d'un Query, globalement de la même manière que vous utilisez Query avec une table. Une table peut avoir plusieurs index secondaires, ce qui permet à vos applications d'accéder à de nombreux modèles de requête différents. Note Vous pouvez également Scan un index, globalement de la même manière que vous le feriez pour Scan une table. Chaque index secondaire est associé à une seule table dans laquelle il obtient ses données. Il s'agit de la table de base de l'index. Lorsque vous créez un index, vous définissez une autre clé pour cet API Version 2012-08-10 337 Amazon DynamoDB Manuel du développeur Utilisation des index index (clé de partition et clé de tri). Vous définissez également les attributs à projeter, ou à copier, de la table de base vers l'index. DynamoDB copie ces attributs dans l'index, ainsi que les attributs de la clé primaire de la table de base. Vous pouvez ensuite interroger ou analyser l'index de la même manière que vous procéderiez avec une table. Chaque index secondaire est automatiquement géré par DynamoDB. Lorsque vous ajoutez, modifiez ou supprimez des éléments dans la table de base, tous les index de cette table sont également mis à jour pour refléter ces modifications. DynamoDB prend en charge deux types d'index secondaires : • Index secondaire global – un index avec une clé de partition et une clé de tri qui peuvent être différentes de celles sur la table de base. Un index secondaire global est considéré comme « global », car les requêtes sur l'index peuvent s'étendre à toutes les données dans une table de base, sur toutes les partitions. • Index secondaire local – un index possédant la même clé de partition que la table de base, mais une clé de tri différente. Un local secondary index est « local » dans le sens où chaque partition d'un local secondary index s'étend à une partition de table de base qui a la même valeur de clé de partition. Vous devez tenir compte des exigences de votre application lorsque vous déterminez le type d'index à utiliser. La table suivante présente les principales différences entre un index secondaire global et un local secondary index : Caractéristiques Index global secondaire Index local secondaire Schéma de clé La clé primaire d'un index secondaire global peut être simple (clé de partition) ou composite (clé de partition et clé de tri). La clé primaire d'un local secondary index doit être composite (clé de partition et clé de tri). Attributs de clé La clé de partition d'index et la clé de tri (le cas échéant) peuvent être n'importe quels attributs de table de base de type chaîne, nombre ou binaire. La clé de partition de l'index est le même attribut que la clé de partition de la table de base. La clé de tri peut être n'importe quel attribut de la table de base, de type chaîne, nombre ou binaire. Restrictions de taille par valeur de clé de partition Il n'y a aucune restriction de taille pour les index secondaire global. Pour chaque valeur de clé de partition, la taille totale de tous les éléments indexés doit être inférieure ou égale à 10 Go. Opérations d'index en ligne Les Global secondary index peuvent être créés en même temps que vous créez une table. Vous pouvez également ajouter un nouveau index secondaire global à une table existante, ou supprimer un index secondaire global existant. Pour de plus amples informations, veuillez consulter Gestion des index secondaires globaux (p. 348). Les Index secondaire local sont créés en même temps que vous créez une table. Vous ne pouvez pas ajouter un local secondary index à une table existante. Vous ne pouvez pas non plus supprimer des local secondary index qui existent actuellement. Requêtes et partitions Un index secondaire global vous permet d'exécuter Un local secondary index vous permet d'exécuter une requête API Version 2012-08-10 338 Amazon DynamoDB Manuel du développeur Utilisation des index Caractéristiques Index global secondaire Index local secondaire une requête sur la totalité de la table, entre toutes les partitions. sur une seule partition, comme indiqué par la valeur de clé de partition dans la requête. Cohérence en lecture Les requêtes sur les index secondaire global prennent en charge la cohérence à terme uniquement. Lorsque vous interrogez un local secondary index, vous pouvez choisir une cohérence à terme ou une cohérence forte. Consommation de débit alloué Chaque index secondaire global a ses propres paramètres de débit alloué pour les activités de lecture et d'écriture. Les requêtes ou les analyses sur un index secondaire global consomment des unités de capacité de l'index, pas à partir de la table de base. Il en va de même pour les mises à jour de index secondaire global en raison d'écritures de table. Des requêtes ou des analyses sur un local secondary index consomment des unités de capacité de lecture de la table de base. Lorsque vous écrivez sur une table, ses local secondary index sont également mis à jour ; ces mises à jour consomment des unités de capacité d'écriture de la table de base. Attributs projetés Avec des requêtes ou des analyses d'index secondaire global, vous pouvez demander uniquement les attributs qui sont projetés dans l'index. DynamoDB ne va pas chercher tous les attributs de la table. Si vous interrogez ou analysez un local secondary index, vous pouvez interroger des attributs qui ne sont pas projetés dans l'index. DynamoDB cherchera automatiquement ces attributs dans la table. Si vous souhaitez créer plus d'une table avec des index secondaires, vous devez le faire de manière séquentielle. Par exemple, vous créez la première table et attendez qu'elle devienne ACTIVE, vous créez la table suivante et attendez qu'elle devienne ACTIVE, et ainsi de suite. Si vous essayez de créer simultanément plus d'une table avec un index secondaire, DynamoDB renverra une LimitExceededException. Pour chaque index secondaire, vous devez spécifier les informations suivantes : • Le type d'index à créer – soit un index secondaire global, soit un local secondary index. • Un nom pour l'index. Les règles de dénomination pour les index sont identiques à celles pour les tables, comme indiqué dans Limites dans DynamoDB (p. 564). Le nom doit être unique pour la table de base à laquelle il est associé, mais vous pouvez utiliser le même nom pour des index qui sont associés à d'autres tables de base. • Le schéma de clés pour l'index. Chaque attribut dans le schéma de clé d'index doit être un attribut de niveau supérieur de type String, Number ou Binary. D'autres types de données, y compris les documents et les jeux, ne sont pas autorisés. Les autres exigences pour le schéma de clé dépendent du type d'index : • Pour un index secondaire global, la clé de partition peut être n'importe quel attribut scalaire de la table de base. Une clé de tri est facultative et peut également être n'importe quel attribut scalaire de la table de base. • Pour un local secondary index, la clé de partition doit être la même que la clé de partition de la table de base et la clé de tri doit être un attribut non-clé de la table de base. • Attributs supplémentaires, le cas échéant, à projeter de la table de base vers l'index. Ces attributs sont en plus des attributs clés de la table, qui sont automatiquement projetés dans chaque index. API Version 2012-08-10 339 Amazon DynamoDB Manuel du développeur Index secondaires globaux Vous pouvez projeter des attributs de n'importe quel type de données, y compris scalaires, documents et jeux. • Les paramètres de débit alloué pour l'index, si nécessaire : • Pour un index secondaire global, vous devez spécifier les paramètres d'unité de capacité de lecture et d'écriture. Ces paramètres de débit alloué sont indépendants des paramètres de la table de base. • Pour un local secondary index, vous n'avez pas besoin de spécifier des paramètres d'unité de capacité de lecture et d'écriture. Toute opération de lecture et d'écriture sur un local secondary index tire les paramètres de débit alloué de sa table de base. Pour une flexibilité de requête maximale, vous pouvez créer jusqu'à 5 index secondaire global et jusqu'à 5 local secondary index par table. Pour obtenir une liste détaillée des index secondairees sur une table, utilisez l'opération DescribeTable. DescribeTable renvoie le nom, la taille de stockage et le nombre d'éléments pour chaque index secondaire sur la table. Ces valeurs ne sont pas mises à jour en temps réel, mais elles sont actualisées environ toutes les six heures. Vous pouvez accéder aux données dans un index secondaire à l'aide de l'opération Query ou Scan. Vous devez spécifier le nom de la table de base et le nom de l'index que vous souhaitez utiliser, les attributs à retourner dans les résultats et tous les filtres ou conditions d'expressions que vous souhaitez appliquer. DynamoDB peut retourner les résultats dans l'ordre croissant ou décroissant. Lorsque vous supprimez une table, tous les index associés à cette table sont également supprimés. Pour connaître les bonnes pratiques, consultez Consignes pour les index secondaires locaux (p. 590) et Consignes pour les Index global secondaire (p. 593), respectivement. Index secondaires globaux Rubriques • Projections d'attribut (p. 343) • Interrogation d'un index secondaire global (p. 345) • Analyse d'un index secondaire global (p. 345) • Synchronisation des données entre les tables et les index secondaires globaux (p. 345) • Considérations sur le débit provisionné pour les index secondaires globaux (p. 346) • Considérations sur le stockage des index secondaires globaux (p. 347) • Gestion des index secondaires globaux (p. 348) • Utilisation des Index global secondaire : Java (p. 360) • Utilisation de Index global secondaire : .NET (p. 368) • Utilisation des index secondaires globaux PHP (p. 379) Certaines applications peuvent avoir besoin d'exécuter de nombreux types de requêtes, à l'aide de divers attributs comme critères de requête. Pour prendre en charge ces exigences, vous pouvez créer un ou plusieurs index secondaires globaux et émettre des requêtes Query sur ces index. A des fins d'illustration, considérons une table nommée GameScores qui assure le suivi des utilisateurs et enregistre les scores d'une application de jeux pour appareils mobiles. Chaque élément de GameScores est identifié par une clé de partition (UserId) et une clé de tri (GameTitle). Le schéma suivant illustre la façon dont les éléments de la table seront organisés. (Tous les attributs ne sont pas affichés.) API Version 2012-08-10 340 Amazon DynamoDB Manuel du développeur Index secondaires globaux Supposons maintenant que vous vouliez écrire une application de classement pour afficher les meilleurs scores de chaque partie. Une requête qui a spécifié les attributs clés (UserId et GameTitle) serait très économique ; toutefois, si l'application devait récupérer des données depuis GameScores en fonction de GameTitle seulement, elle devrait utiliser une opération Scan. Lorsque plusieurs éléments sont ajoutés à la table, les analyses de toutes les données deviennent lentes et inefficaces, ce qui rend difficile la réponse aux questions suivantes : • Quel est le meilleur score jamais enregistré pour le jeu Meteor Blasters ? • Quel utilisateur a le score le plus élevé pour Galaxy Invaders ? • Quel est le taux plus élevé du nombre de victoires par rapport au nombre de pertes ? Afin d'accélérer les requêtes sur les attributs non-clés, vous pouvez créer un index secondaire global. Un index secondaire global contient une sélection d'attributs de la table de base, mais ils sont organisées selon une clé primaire différente de celle de la table. La clé d'index n'a pas besoin d'avoir l'un des attributs clés de la table ; Il n'a pas même besoin d'avoir le même schéma clé qu'une table. Par exemple, vous pouvez créer un index secondaire global nommé GameTitleIndex, avec une clé de partition GameTitle et une clé de tri TopScore. Comme les attributs de la clé primaire de la table de base sont toujours projetés sur un index, l'attribut UserId est également présent. Le schéma suivant illustre ce à quoi l'index GameTitleIndex ressemble : API Version 2012-08-10 341 Amazon DynamoDB Manuel du développeur Index secondaires globaux Maintenant, vous pouvez interroger GameTitleIndex et obtenir facilement les scores de Meteor Blasters. Les résultats sont triés sur les valeurs de la clé de tri, TopScore. Si vous définissez le paramètre ScanIndexForward sur la valeur false, les résultats sont retournés par ordre décroissant, de telle sorte que le meilleur score est retourné en premier. Chaque index secondaire global doit avoir une clé de partition et peut avoir une clé de tri facultative. Le schéma de clé d'index peut être différent du schéma de table de base ; vous pouvez avoir une table avec une clé primaire simple (clé de partition) et créer un index secondaire global avec une clé primaire composite (clé de partition et clé de tri), et inversement. Les attributs de la clé d'index peuvent être composés de n'importe quel attribut String, Number ou Binary de la table de base ; les autres types, tels que Scalar, Document et Set, ne sont pas autorisés. Vous pouvez projeter d'autres attributs de table de base sur l'index si vous le souhaitez. Lorsque vous interrogez l'index, DynamoDB peut extraire efficacement ces attributs projetés ; cependant, les requêtes d'index secondaires globaux ne peuvent pas extraire d'attributs de la table de base. Par exemple, si vous interrogiez GameTitleIndex, comme illustré dans le schéma ci-dessus, la requête ne serait pas en mesure d'accéder à des attributs non-clés autres que TopScore (même si les attributs clés GameTitle et UserId seraient automatiquement projetés). Dans une table DynamoDB, chaque valeur de clé doit être unique. Cependant, les valeurs de clé d'un index secondaire global n'ont pas besoin d'être uniques. A des fins d'illustration, supposons qu'un jeu nommé Comet Quest soit particulièrement difficile, avec de nombreux utilisateurs qui tentent en vain d'obtenir un score supérieur à zéro. Voici quelques données que nous pourrions utiliser pour représenter ceci : UserId GameTitle TopScore 123 Comet Quest 0 USD 201 Comet Quest 0 USD 301 Comet Quest 0 USD Lorsque ces données sont ajoutées à la table GameScores, DynamoDB les répercute sur GameTitleIndex. Si nous interrogeons alors l'index à l'aide de Comet Quest pour GameTitle et de 0 pour TopScore, les données suivantes sont renvoyées : API Version 2012-08-10 342 Amazon DynamoDB Manuel du développeur Index secondaires globaux Seuls les éléments avec les valeurs de clés spécifiées apparaissent dans la réponse ; dans ce jeu de données, les éléments ne sont pas dans un ordre particulier. Un index secondaire global ne suit que les éléments de données où ses attributs clés existent réellement. Par exemple, supposons que vous ayez ajouté un nouvel élément à la table GameScores, mais que vous n'ayez fourni que les attributs de clé primaires requis : UserId GameTitle 400 Comet Quest Etant donné que vous n'avez pas spécifié l'attribut TopScore, DynamoDB ne propage pas cet élément sur GameTitleIndex. Par conséquent, si vous interrogiez GameScores pour tous les éléments Comet Quest, vous obtiendriez les quatre éléments suivants : Une requête similaire sur GameTitleIndex renvoie toujours trois éléments, plutôt que quatre. Cela est dû au fait que l'élément avec TopScore non existant n'est pas propagé sur l'index : Projections d'attribut Une projection est l'ensemble d'attributs qui est copié à partir d'une table et appliqué à un index secondaire. La clé de partition et la clé de tri de la table sont toujours projetées dans l'index ; vous pouvez projeter d'autres attributs pour répondre aux besoins d'interrogation de votre application. Lorsque vous interrogez un index, Amazon DynamoDB peut accéder à n'importe quel attribut de la projection comme si ces attributs figuraient dans sa propre table. Lorsque vous créez un index secondaire, vous devez indiquer quels attributs feront l'objet d'une projection dans l'index. DynamoDB propose trois options différentes pour cela : • KEYS_ONLY – chaque élément de l'index se compose uniquement des valeurs de clé de partition et de clé de tri de la table, ainsi que des valeurs de clé d'index. L'option KEYS_ONLY correspond à l'index secondaire le plus petit. API Version 2012-08-10 343 Amazon DynamoDB Manuel du développeur Index secondaires globaux • INCLUDE – en plus des attributs décrits dans KEYS_ONLY, l'index secondaire inclut d'autres attributs non-clés que vous spécifiez. • ALL – l'index secondaire inclut tous les attributs de la table source. Comme toutes les données de la table sont dupliquées dans l'index, une projection ALL correspond à l'index secondaire le plus grand. Dans le schéma ci-dessus, GameTitleIndex n'a aucun attribut supplémentaire projeté. Une application peut utiliser GameTitle et TopScore dans les requêtes ; cependant, il n'est pas possible de déterminer efficacement quel utilisateur a le score le plus élevé pour une partie donnée, ou le taux le plus élevé de victoires par rapport au nombre de défaites. La façon la plus efficace de prendre en charge les requêtes sur ces données serait de projeter ces attributs depuis la table de base vers l'index secondaire global, comme illustré dans ce diagramme : Comme les attributs non clés Wins et Losses sont projetés dans l'index, une application peut déterminer le rapport entre le nombre de victoires et le nombre de défaites de n'importe quel jeu, ou pour toute combinaison d'ID d'utilisateur et de jeu. Lorsque vous choisissez les attributs à projeter sur un index secondaire global, vous devez prendre en compte le compromis entre les coûts de débit alloué et les coûts de stockage : • Si vous avez juste besoin d'accéder à quelques attributs avec la plus faible latence possible, envisagez de ne projeter que ces attributs sur un index secondaire global. Plus l'index est petit, moins les coûts d'écriture et de stockage sont élevés. • Si votre application accède fréquemment à certains attributs non-clés, vous devez envisager de projeter ces attributs sur un index secondaire global. Les coûts de stockage supplémentaires de l'index secondaire global compenseront le coût d'exécution d'analyses de table fréquentes. • Si vous avez besoin d'accéder à la plupart des attributs non-clés sur une base fréquente, vous pouvez projeter ces attributs, voire la totalité de la table de base, sur un index secondaire global. Cela vous donne une flexibilité maximale ; cependant, le coût de votre stockage augmentera, ou même sera multiplié par deux. • Si votre application doit interroger peu fréquemment une table, mais doit exécuter un grand nombre d'écritures ou de mises à jour des données de la table, pensez à projeter KEYS_ONLY. L'index secondaire global sera d'une taille minimale, mais continuera d'être disponible chaque fois que nécessaire pour une activité de requête. API Version 2012-08-10 344 Amazon DynamoDB Manuel du développeur Index secondaires globaux Interrogation d'un index secondaire global Vous pouvez utiliser l'opération Query pour accéder à un ou plusieurs éléments d'un index secondaire global. La requête doit spécifier le nom de la table de base et le nom de l'index que vous souhaitez utiliser, les attributs à retourner dans les résultats de la requête et toutes les conditions de requête que vous souhaitez appliquer. DynamoDB peut retourner les résultats dans l'ordre croissant ou décroissant. Prenez en compte les données suivantes retournées à partir d'une opération Query qui demande les données de jeu pour une application de classement : { "TableName": "GameScores", "IndexName": "GameTitleIndex", "KeyConditionExpression": "GameTitle = :v_title", "ExpressionAttributeValues": { ":v_title": {"S": "Meteor Blasters"} }, "ProjectionExpression": "UserId, TopScore", "ScanIndexForward": false } Dans cette requête : • DynamoDB accède à GameTitleIndex, en utilisant la clé de partition GameTitle pour rechercher les éléments d'index de Meteor Blasters. Tous les éléments d'index avec cette clé sont stockés les uns à côté des autres pour une récupération rapide. • Dans ce jeu, DynamoDB utilise l'index pour accéder à tous les ID d'utilisateur et meilleurs scores du jeu. • Les résultats sont retournés, triés par ordre décroissant, car le paramètre ScanIndexForward a la valeur false. Analyse d'un index secondaire global Vous pouvez utiliser l'opération Scan pour récupérer toutes les données d'un index secondaire global. Vous devez fournir le nom de la table de base et le nom de l'index dans la demande. Avec une opération Scan, DynamoDB lit toutes les données de l'index et les renvoie à l'application. Vous pouvez également demander que seules quelques données soient retournées, et que les données restantes soient ignorées. Pour ce faire, utilisez le paramètre FilterExpression de l'opération Scan. Pour de plus amples informations, veuillez consulter Filtrage des résultats d'une opération Query ou Scan (p. 292). Synchronisation des données entre les tables et les index secondaires globaux DynamoDB synchronise automatiquement chaque index secondaire global avec sa table de base. Quand une application écrit ou supprime les éléments d'une table, les index secondaires globaux de cette table sont mis à jour de manière asynchrone, à l'aide d'un modèle de cohérence à terme. Les applications n'écrivent jamais directement sur un index. Cependant, il est important que vous compreniez les implications de la façon dont DynamoDB gère ces index. Lorsque vous créez un index secondaire global, vous spécifiez un ou plusieurs attributs de clé d'index et leurs types de données. Cela signifie que chaque fois que vous écrivez un élément sur la table de base, les types de données de ces attributs doivent correspondre aux types de données du schéma de la clé d'index. Dans le cas de GameTitleIndex, la clé de partition GameTitle de l'index est définie API Version 2012-08-10 345 Amazon DynamoDB Manuel du développeur Index secondaires globaux comme type de données String et la clé de tri TopScore de l'index est de type Number. Si vous essayez d'ajouter un élément à la table GameScores et spécifiez un autre type de données pour GameTitle ou pour TopScore, DynamoDB retourne une exception ValidationException en raison de l'incompatibilité des types de données. Lorsque vous insérez ou supprimez des éléments dans une table, les index secondaires globaux sont mis à jour selon une façon cohérente à terme. Les modifications apportées aux données de la table sont propagées sur les index secondaires globaux en une fraction de seconde, dans des conditions normales. Cependant, dans certains scénarios de défaillance peu probables, les retards de propagation peuvent être plus longs. Pour cette raison, vos applications ont besoin d'anticiper et de gérer les situations où une requête sur un index secondaire global retourne des résultats qui ne sont pas à jour. Si vous écrivez un élément sur une table, vous n'avez pas à spécifier les attributs de clé de tri des index secondaires globaux. Si vous utilisez GameTitleIndex comme exemple, vous n'avez pas besoin de spécifier une valeur pour l'attribut TopScore pour pouvoir écrire un nouvel élément sur la table GameScores. Dans ce cas, Amazon DynamoDB n'écrit aucune donnée sur l'index pour cet élément particulier. Une table avec de nombreux index secondaires globaux s'expose à des coûts plus élevés pour l'activité d'écriture qu'une table ayant moins d'index. Pour de plus amples informations, veuillez consulter Considérations sur le débit provisionné pour les index secondaires globaux (p. 346). Considérations sur le débit provisionné pour les index secondaires globaux Lorsque vous créez un index secondaire global, vous devez spécifier les unités de capacité en lecture et en écriture pour la charge de travail prévue sur cet index. Les paramètres de débit alloué d'un index secondaire global sont distincts de ceux de la table de base. Une opération Query sur un index secondaire global consomme les unités de capacité en lecture de l'index, pas de la table de base. Lorsque vous insérez, mettez à jour ou supprimez des éléments dans une table, les index secondaires globaux de cette table sont également mis à jour ; ces mises à jour de l'index consomment les unités de capacité en écriture de l'index, pas de la table de base. Par exemple, si vous exécutez une opération Query sur un index secondaire global et que vous dépassez sa capacité de lecture provisionnée, votre demande sera limitée. Si vous exécutez une activité en écriture massive sur la table, mais qu'un index secondaire global de cette table a une capacité d'écriture insuffisante, l'activité d'écriture sur la table est limitée. Pour afficher les paramètres de débit alloué d'un index secondaire global, utilisez l'opération DescribeTable ; des informations détaillées sur tous les index secondaires globaux de la table seront renvoyées. Unités de capacité en lecture Les index secondaires globaux prennent en charge les lectures cohérentes à terme ; chacune d'elles utilise la moitié d'une unité de capacité en lecture. Cela signifie qu'une seule requête d'index secondaire global peut extraire jusqu'à 2 × 4 KB = 8 Ko par unité de capacité en lecture. Pour les requêtes d'index secondaire global, DynamoDB calcule l'activité en lecture allouée de la même façon qu'elle le fait pour les requêtes sur les tables. La seule différence est que le calcul est basé sur les tailles des entrées d'index, plutôt que sur la taille de l'élément de la table de base. Le nombre d'unités de capacité en lecture est la somme des tailles de tous les attributs projetés de tous les éléments renvoyés ; le résultat est alors arrondi à la limite 4 KB suivante. Pour plus d'informations sur la façon dont DynamoDB calcule l'utilisation du débit alloué, consultez Spécification d'exigences de lecture et d'écriture pour des tables (p. 180). La taille maximale des résultats retournés par une opération Query est 1 MB ; cela inclut les tailles de tous les noms et valeurs d'attribut à travers l'ensemble des éléments retournés. API Version 2012-08-10 346 Amazon DynamoDB Manuel du développeur Index secondaires globaux Par exemple, imaginons un index secondaire global où chaque élément contient 2000 octets de données. Supposons, maintenant, que vous exécutiez une opération Query sur cet index et que la requête renvoie 8 éléments. La taille totale des éléments correspondants est 2000 octets × 8 éléments = 16 000 octets. Ce résultat est ensuite arrondie à la limite 4 KB la plus proche. Comme les requêtes d'index secondaire global sont cohérentes à terme, le coût total est 0,5 × (16 Ko / 4 KB), ou 2 unités de capacité en lecture. Unités de capacité en écriture Lorsqu'un élément d'une table est ajouté, mis à jour ou supprimé et qu'un index secondaire global en est affecté, l'index secondaire global consomme les unités de capacité en écriture allouées pour l'opération. Le coût total du débit alloué pour une écriture se compose de la somme des unités de capacité en écriture utilisées par l'écriture sur la table de base et de celles utilisées par la mise à jour des index secondaires globaux. Notez que si une écriture sur une table ne requiert pas la mise à jour d'un index secondaire global, aucune capacité en écriture n'est consommée à partir de l'index. Pour qu'une écriture de table réussisse, les paramètres de débit provisionnés de la table et de tous ses index secondaires globaux doivent avoir une capacité d'écriture suffisante pour accueillir l'écriture ; sinon, l'écriture sur la table est limitée. Le coût d'écriture d'un élément sur un index secondaire global dépend de plusieurs facteurs : • Si vous écrivez un nouvel élément sur la table qui définit un attribut indexé, ou que vous mettez à jour un élément existant pour définir un attribut indexé précédemment non défini, une opération d'écriture est nécessaire pour insérer l'élément dans l'index. • Si une mise à jour de la table change la valeur d'un attribut de clé indexée (de A en B), deux écritures sont requises, une pour supprimer l'élément précédent de l'index et une autre pour insérer le nouveau élément dans l'index. • Si un élément était présent dans l'index, mais qu'une écriture sur la table a entraîné la suppression de l'attribut indexé, une écriture est nécessaire pour supprimer de l'index la projection de l'ancien élément. • Si un élément n'est pas présent dans l'index avant ou après la mise à jour de l'élément, il n'y a aucun coût d'écriture supplémentaire pour l'index. • Si la mise à jour de la table ne modifie que la valeur des attributs projetés du schéma de clé d'index, mais ne change pas la valeur d'un quelconque attribut de clé indexé, une écriture est nécessaire pour mettre à jour les valeurs des attributs projetés sur l'index. Tous ces facteurs présument que la taille de chaque élément de l'index soit inférieure ou égale à la taille d'élément 1 KB pour le calcul des unités de capacité en écriture. Les plus grandes entrées d'index nécessitent des unités de capacité en écriture supplémentaires. Vous pouvez réduire vos coûts d'écriture en considérant les attributs que vos requêtes ont besoin de retourner et en projetant uniquement ces attributs dans l'index. Considérations sur le stockage des index secondaires globaux Quand une application écrit un élément sur une table, DynamoDB copie automatiquement le sousensemble approprié d'attributs sur les index secondaires globaux où ces attributs doivent apparaître. Votre compte AWS est facturé pour le stockage de l'élément dans la table de base, ainsi que pour le stockage des attributs dans les index secondaires globaux de cette table. La quantité d'espace utilisée par un élément de l'index est la somme des éléments suivants : • La taille en octets de la clé primaire de la table de base (clé de partition et clé de tri) • La taille en octets de l'attribut de clé d'index • La taille en octets des attributs projetés (le cas échéant) • 100 bytes de traitement par élément d'index API Version 2012-08-10 347 Amazon DynamoDB Manuel du développeur Index secondaires globaux Afin d'estimer les besoins en stockage d'un index secondaire global, vous pouvez estimer la taille moyenne d'un élément de l'index, puis la multiplier par le nombre d'éléments de la table de base ayant les attributs clés de l'index secondaire global. Si une table contient un élément dans lequel un attribut particulier n'est pas défini, mais que cet attribut est défini comme clé de tri ou clé de partition d'index, DynamoDB n'écrit aucune donnée pour cet élément sur l'index. Gestion des index secondaires globaux Cette section décrit comment créer, modifier et supprimer des index secondaires globaux. Rubriques • Création d'une table avec index secondaires globaux (p. 348) • Description des index secondaires globaux sur une table (p. 348) • Ajout d'un index secondaire global à une table existante (p. 349) • Modification d'une création d'index (p. 351) • Suppression d'un index secondaire global d'une table (p. 352) • Détection et correction des violations de clé d'index (p. 352) Création d'une table avec index secondaires globaux Pour créer une table avec un ou plusieurs index secondaires globaux, utilisez l'opération CreateTable avec le paramètre GlobalSecondaryIndexes. Pour une flexibilité de requête maximale, vous pouvez créer jusqu'à 5 index secondaires globaux par table. Vous devez spécifier un attribut comme clé de partition d'index ; vous pouvez, le cas échéant, spécifier un autre attribut pour la clé de tri d'index. Il n'est pas nécessaire que l'un ou l'autre de ces attributs soit le même qu'un attribut de clé de la table. Par exemple, dans la table GameScores (voir Index secondaires globaux (p. 340)), ni TopScore, ni TopScoreDateTime ne sont des attributs clés ; vous pouvez créer un index secondaire global avec une clé de partition TopScore et une clé de tri TopScoreDateTime. Vous pouvez utiliser un tel index pour déterminer s'il existe un lien entre les meilleurs scores et l'heure à laquelle la partie a lieu. Chaque attribut de clé d'index doit être un scalaire de type String, Number, or Binary (chaîne, nombre ou binaire). (Il ne peut pas s'agir d'un document ou d'un ensemble.) Vous pouvez projeter les attributs de n'importe quel type de données dans un index secondaire global ; cela inclut les scalaires, les documents et les ensembles. Pour obtenir la liste complète des types de données, consultez Type de données (p. 12). Vous devez fournir les paramètres ProvisionedThroughput pour l'index, composés de ReadCapacityUnits et WriteCapacityUnits. Ces paramètres de débit alloué sont séparés de ceux de la table, mais se comportent de manière similaire. Pour de plus amples informations, veuillez consulter Considérations sur le débit provisionné pour les index secondaires globaux (p. 346). Description des index secondaires globaux sur une table Pour afficher le statut de index secondaire global tous les index secondaires globaux sur une table, utilisez l'opération DescribeTable. La partie GlobalSecondaryIndexes de la réponse affiche tous les index de la table, ainsi que l'état actuel de chaque (IndexStatus). L'état IndexStatus d'un index secondaire global a l'une des valeurs suivantes : • CREATING : l'index est actuellement créé et n'est pas encore disponible pour être utilisé. • ACTIVE : l'index est prêt à être utilisé et les applications peuvent effectuer des opérations Query sur l'index • UPDATING : les paramètres de débit alloué de l'index sont en cours de modification. API Version 2012-08-10 348 Amazon DynamoDB Manuel du développeur Index secondaires globaux • DELETING : l'index est actuellement en cours de suppression et ne peut plus être utilisé. Quand DynamoDB a terminé la construction d'un index secondaire global, l'état de l'index passe de CREATING à ACTIVE. Ajout d'un index secondaire global à une table existante Pour ajouter un index secondaire global à une table existante, utilisez l'opération UpdateTable avec le paramètre GlobalSecondaryIndexUpdates. Vous devez fournir les informations suivantes : • Un nom d'index. Le nom doit être unique parmi tous les index de la table. • Le schéma de clé de l'index. Vous devez spécifier un attribut pour la clé de partition d'index ; vous pouvez, le cas échéant, spécifier un autre attribut pour la clé de tri d'index. Il n'est pas nécessaire que l'un ou l'autre de ces attributs soit le même qu'un attribut de clé de la table. Les types de données de chaque attribut de schéma doivent être scalaires : String, Number ou Binary. • Les attributs à projeter depuis la table vers l'index : • KEYS_ONLY : chaque élément de l'index se compose uniquement des valeurs de clé de partition de table et de clé de tri, ainsi que des valeurs de clé d'index. • INCLUDE : en plus des attributs décrits dans KEYS_ONLY, l'index secondaire inclut d'autres attributs non- clés que vous spécifiez. • ALL : l'index inclut tous les attributs de la table source. • Les paramètres de débit alloué pour l'index, composés de ReadCapacityUnits et WriteCapacityUnits. Ces paramètres de débit alloué sont distincts de ceux de la table. Vous pouvez uniquement créer ou supprimer un index secondaire global par opération UpdateTable. Cependant, si vous exécutez plusieurs opérations UpdateTable simultanément, vous pouvez créer plusieurs index à la fois. Vous pouvez exécuter jusqu'à cinq de ces opérations UpdateTable à la fois sur une table et chaque opération peut créer exactement un index. Note Vous ne pouvez pas annuler une création d'index secondaire global à la volée. Phases de la création d'index Lorsque vous ajoutez un nouvel index secondaire global à une table existante, la table continue à être disponible pendant la construction de l'index. Cependant, le nouvel index n'est pas disponible pour les opérations Query, jusqu'à ce que son statut passe de CREATING à ACTIVE. En arrière-plan, DynamoDB crée l'index en deux étapes : Allocation des ressources DynamoDB alloue les ressources de calcul et de stockage qui seront nécessaires pour la construction de l'index. Lors de la phase d'allocation des ressources, l'attribut IndexStatus a la valeur CREATING et l'attribut Backfilling la valeur false. Utilisez l'opération DescribeTable pour extraire l'état d'une table et de tous ses index secondaires. Tandis que l'index est dans la phase d'allocation des ressources, vous ne pouvez pas supprimer sa table parent ni modifier le débit alloué de l'index ou de la table. Vous ne pouvez pas ajouter ou supprimer d'index sur la table ; cependant, vous pouvez modifier le débit alloué de ces autres index. Renvoi Pour chaque élément de la table, DynamoDB détermine l'ensemble d'attributs à écrire sur l'index en fonction de sa projection (KEYS_ONLY, INCLUDE ou ALL). Il écrit ensuite ces attributs sur API Version 2012-08-10 349 Amazon DynamoDB Manuel du développeur Index secondaires globaux l'index. Lors de la phase de renvoi, DynamoDB assure le suivi des éléments qui sont ajoutés, supprimés ou mis à jour dans la table. Les attributs de ces éléments sont également ajoutés, supprimés ou mis à jour dans l'index, le cas échéant. Lors de la phase de renvoi, l'attribut IndexStatus a la valeur CREATING et l'attribut Backfilling la valeur true. Utilisez l'opération DescribeTable pour extraire l'état d'une table et de tous ses index secondaires. Tandis que l'index est en cours de renvoi, vous ne pouvez pas supprimer sa table parent. Cependant, vous pouvez toujours modifier le débit alloué de la table et de l'un de ses index secondaires globaux. Note Pendant la phase de renvoi, certaines écritures d'éléments en violation peuvent réussir, tandis que d'autres sont rejetées. Après le renvoi, toutes les écritures qui enfreignent le schéma de clé du nouvel index sont rejetées. Nous vous recommandons d'exécuter l'outil Violation Detector une fois la phase de renvoi terminée, afin de détecter et de résoudre toutes les violations de clé qui ont pu se produire. Pour de plus amples informations, veuillez consulter Détection et correction des violations de clé d'index (p. 352). Bien que les phases d'allocation des ressources et de renvoi soient en cours, l'index se trouve dans l'état CREATING. Pendant ce temps, DynamoDB effectue les opérations de lecture sur la table ; vous ne serez pas facturé pour cette activité de lecture. Lorsque la génération de l'index est terminée, son état devient ACTIVE. Vous ne serez pas en mesure d'exécuter une opération Query ou Scan sur l'index jusqu'à ce que l'état soit ACTIVE. Note Dans certains cas, DynamoDB n'est pas en mesure d'écrire les données de la table sur l'index en raison de violations de clé index. Cela peut se produire si le type de données d'une valeur d'attribut ne correspond pas au type de données d'un type de données de schéma de clé d'index ou si la taille d'un attribut dépasse la longueur maximale d'un attribut de clé d'index. Les violations de clé d'index n'interfèrent pas avec la création des index secondaires globaux ; toutefois, lorsque l'index devient ACTIVE, les clés en violation ne sont pas présentes dans l'index. DynamoDB fournit un outil autonome pour rechercher et résoudre ces problèmes. Pour de plus amples informations, veuillez consulter Détection et correction des violations de clé d'index (p. 352). Ajout d'un index secondaire global à une grande table Le temps nécessaire pour construire un index secondaire global dépend de plusieurs facteurs, tels que : • La taille de la table • Le nombre d'éléments de la table qualifiés pour l'inclusion dans l'index • Le nombre d'attributs projetés dans l'index • La capacité en écriture allouée pour l'index • L'activité d'écriture sur la table principale pendant les générations d'index. Si vous ajoutez un index secondaire global à une très grande table, cela peut prendre beaucoup de temps pour que le processus de création se termine. Pour suivre la progression et déterminer si l'index dispose d'une capacité suffisante en écriture, consultez les métriques Amazon CloudWatch suivantes : API Version 2012-08-10 350 Amazon DynamoDB Manuel du développeur Index secondaires globaux • OnlineIndexPercentageProgress • OnlineIndexConsumedWriteCapacity • OnlineIndexThrottleEvents Note Pour plus d'informations sur les métriques CloudWatch associées à DynamoDB, consultez DynamoDB Metrics (p. 503). Si le paramètre de débit alloué en écriture de l'index est trop bas, la génération de l'index peut prendre plus de temps. Pour réduire le temps nécessaire à la création d'un nouvel index secondaire global, vous pouvez augmenter provisoirement sa capacité en écriture provisionnée. Note Comme règle générale, nous recommandons de définir une capacité en écriture allouée égale à 1,5 fois la capacité en écriture de la table. Il s'agit d'un bon réglage pour de nombreux cas d'utilisation ; cependant, vos besoins réels peuvent être supérieurs ou inférieurs. Tandis qu'un index est en cours de renvoi, DynamoDB utilise la capacité système interne pour lire à partir de la table. L'objectif est de réduire l'impact de la création d'index et de vous assurer que votre table ne se trouve pas à court de capacité en lecture. Cependant, il est possible que le volume de l'activité en écriture entrante dépasse la capacité en écriture allouée de l'index. Il s'agit d'un scénario de goulot d'étranglement, dans lequel la création de l'index peut prendre plus de temps, parce que l'activité en écriture de l'index est limitée. Lors de la construction de l'index, nous vous recommandons de surveiller les métriques Amazon CloudWatch de l'index afin de déterminer si la capacité en écriture consommée est supérieure à sa capacité provisionnée. Dans un scénario de goulot d'étranglement, vous devez augmenter la capacité en écriture allouée de l'index pour éviter toute limitation en écriture pendant la phase de renvoi. Une fois que l'index a été créé, vous devez définir sa capacité en écriture provisionnée afin de refléter l'utilisation normale de votre application. Modification d'une création d'index Pendant la construction d'un index, vous pouvez utiliser l'opération DescribeTable afin de déterminer dans quelle phase elle se trouve. La description de l'index inclut un attribut booléen, Backfilling, pour indiquer que DynamoDB charge actuellement l'index avec des éléments de la table. Si Backfilling a la valeur true, la phase d'allocation des ressources est terminée et l'index est désormais en cours de renvoi. Tandis que le renvoi se poursuit, vous pouvez mettre à jour les paramètres de débit alloué de l'index. Vous pouvez décider de le faire afin d'accélérer la construction de l'index : vous pouvez augmenter la capacité en écriture de l'index pendant sa construction, puis la diminuer par la suite. Pour modifier les paramètres de débit alloué de l'index, utilisez l'opération UpdateTable. L'état de l'index devient UPDATING et Backfilling a la valeur true jusqu'à ce que l'index soit prêt à être utilisé. Lors de la phase de renvoi, vous ne pouvez pas ajouter ou supprimer d'autres index sur la table. Note Pour les index qui ont été créés dans le cadre d'une opération CreateTable, l'attribut Backfilling n'apparaît pas dans la sortie de DescribeTable. Pour de plus amples informations, veuillez consulter Phases de la création d'index (p. 349). API Version 2012-08-10 351 Amazon DynamoDB Manuel du développeur Index secondaires globaux Suppression d'un index secondaire global d'une table Si vous n'avez plus besoin d'un index secondaire global, vous pouvez le supprimer à l'aide de l'opération UpdateTable. Vous pouvez supprimer un seul index secondaire global par opération UpdateTable. Cependant, vous pouvez supprimer plusieurs index à la fois en exécutant plusieurs opérations UpdateTable simultanément. Vous pouvez exécuter jusqu'à cinq de ces opérations UpdateTable à la fois sur une table et chaque opération peut supprimer exactement un index. Pendant que l'index secondaire global est en cours de suppression, il y a aucun impact sur les activités en lecture ou en écriture de la table parent. Bien que la suppression soit en cours, vous pouvez toujours modifier le débit alloué sur d'autres index. Note Lorsque vous supprimez une table à l'aide de l'action DeleteTable, tous les index secondaires globaux de cette table sont également supprimés. Détection et correction des violations de clé d'index Lors de la phase de renvoi de la création d'index secondaires globaux, DynamoDB examine chaque élément de la table pour déterminer s'il est éligible à l'inclusion dans l'index. Certains éléments peuvent ne pas l'être, car cela entraînerait des violations de clé index. Dans ce cas, les éléments demeurent dans la table, mais l'index n'a pas d'entrée correspondante pour cet élément. Une violation de clé d'index se produit dans les circonstances suivantes : • Il existe une incompatibilité de type de données entre une valeur d'attribut et le type de données du schéma de clé d'index. Par exemple, imaginez que l'un des éléments de la table GameScores ait une valeur TopScore de type String (chaîne). Si vous avez ajouté un index secondaire global avec la clé de partition TopScore, de type Number (numérique), l'élément de la table enfreint la clé d'index. • Une valeur d'attribut de la table dépasse la longueur maximale d'un attribut de clé d'index. La longueur maximale d'une clé de partition est 2048 bytes et la longueur maximale d'une clé de tri est 1024 bytes. Si l'une des valeurs d'attributs correspondantes de la table dépasse ces limites, l'élément de la table enfreint la clé d'index. Lors d'une violation de clé index, la phase de renvoi se poursuit sans interruption ; cependant, les éléments de la violation ne sont pas inclus dans l'index. Une fois la phase de renvoi terminée, toutes les écritures sur des éléments qui enfreignent le schéma de clé du nouvel index sont rejetées. Afin d'identifier et de corriger les valeurs d'attribut d'une table qui enfreignent une clé d'index, utilisez l'outil Violation Detector. Pour exécuter Violation Detector, vous créez un fichier de configuration qui spécifie le nom d'une table à analyser, les noms et les types de données de la clé de partition et de la clé de tri de l'index secondaire global et les actions à prendre, le cas échéant, s'il se produit une violation de clé d'index. Violation Detector peut s'exécuter dans l'un des deux modes suivants : • Mode détection : détecter les violations de clé index. Utilisez le mode détection pour signaler les éléments d'une table qui entraîneraient des violations de clé d'un index secondaire global. (Vous pouvez demander, le cas échéant, la suppression immédiate de ces éléments de table à l'origine des violations dès qu'ils sont trouvés). La sortie du mode détection est écrite dans un fichier, que vous pouvez utiliser pour une analyse complémentaire. • Mode correction : corriger les violations de clé index. En mode correction, Violation Detector lit un fichier d'entrée avec le même format que le fichier de sortie du mode détection. Le mode correction lit les enregistrements du fichier d'entrée et, pour chaque enregistrement, supprime ou met à jour les éléments correspondants de la table. (Notez que si vous choisissez de mettre à jour les éléments, vous devez modifier le fichier d'entrée et définir les valeurs appropriées de ces mises à jour.) API Version 2012-08-10 352 Amazon DynamoDB Manuel du développeur Index secondaires globaux Téléchargement et exécution de l'outil Violation Detector Violation Detector est disponible dans une archive Java exécutable (fichier .jar) et s'exécute sur les ordinateurs Windows, Mac ou Linux. Violation Detector nécessite Java 1.7 (ou version supérieure) et Maven. • https://github.com/awslabs/dynamodb-online-index-violation-detector Suivez les instructions du fichier README.md pour télécharger et installer Violation Detector à l'aide de Maven Pour démarrer Violation Detector, allez dans le répertoire où vous avez installé ViolationDetector.java et entrez la commande suivante : java -jar ViolationDetector.jar [options] La ligne de commande de Violation Detector accepte les options suivantes : • -h | --help : affiche un résumé de l'utilisation et les options de Violation Detector. • -p | --configFilePathvalue : nom complet d'un fichier de configuration Violation Detector. Pour de plus amples informations, veuillez consulter Fichier de configuration de Violation Detector (p. 353) . • -t | --detectvalue : détecter les violations de clé index de la table et les écrire sur le fichier de sortie Violation Detector. Si la valeur du paramètre est keep, les éléments avec violations de clé ne sont pas modifiés. Si la valeur est delete, les éléments avec violations de clé sont supprimés de la table. • -c | --correctvalue : lire les violations de clé index d'un fichier d'entrée et prendre les mesures correctives sur les éléments de la table. Si la valeur de ce paramètre est définie sur update, les éléments avec violations de clé sont mis à jour avec les nouvelles valeurs, exemptes de violation. Si la valeur est delete, les éléments avec violations de clé sont supprimés de la table. Fichier de configuration de Violation Detector Lors de l'exécution, l'outil Violation Detector nécessite un fichier de configuration. Les paramètres de ce fichier déterminent les ressources DynamoDB auxquelles Violation Detector peut accéder, ainsi que la quantité de débit provisionné qu'il peut consommer. Le tableau suivant décrit ces paramètres. Nom du paramètre Description Obligatoire? awsCredentialsFile Nom complet d'un fichier contenant vos informations d'identification AWS. Le fichier des informations d'identification doit être au format suivant : Oui accessKey = access_key_id_goes_here secretKey = secret_key_goes_here dynamoDBRegion Région AWS dans laquelle la table réside. Par exemple: uswest-2. Oui tableName Nom de la table DynamoDB à analyser. Oui API Version 2012-08-10 353 Amazon DynamoDB Manuel du développeur Index secondaires globaux Nom du paramètre Description Obligatoire? gsiHashKeyName Nom de la clé de partition d'index. Oui gsiHashKeyType Type de données de la clé de partition d'index : String, Number ou Binary : Oui S | N | B gsiRangeKeyName Nom de la clé de partition de tri. Non Ne spécifiez pas ce paramètre si l'index n'a qu'une simple clé primaire (clé de partition). gsiRangeKeyType Type de données de la clé d'index : String, Number ou Binary : Non S | N | B Ne spécifiez pas ce paramètre si l'index n'a qu'une simple clé primaire (clé de partition). recordDetails Définit si tous les détails des violations de clé index doivent être écrits dans le fichier de sortie. Si la valeur est true (valeur par défaut), les informations complètes sur les éléments de violation sont présentées. Si la valeur est false, seul le nombre de violations est présenté. recordGsiValueInViolationRecord Définit si les valeurs des violations de clé d'index doivent être écrites dans le fichier de sortie. Si la valeur est true (par défaut), les valeurs des clés sont présentées. Si la valeur est false, les valeurs des clés ne sont pas présentées. API Version 2012-08-10 354 Non Non Amazon DynamoDB Manuel du développeur Index secondaires globaux Nom du paramètre Description Obligatoire? detectionOutputPath Chemin d'accès complet du fichier de sortie Violation Detector. Ce paramètre prend en charge l'écriture sur un répertoire local ou sur Amazon Simple Storage Service (Amazon S3). Voici quelques exemples : Non detectionOutputPath = //local/path/ filename.csv detectionOutputPath = s3://bucket/filename.csv Les informations du fichier de sortie s'affichent au format CSV (valeurs séparées par des virgules). Si vous ne définissez pas detectionOutputPath, le fichier de sortie est nommé violation_detection.csv et il est écrit sur votre répertoire de travail actif. numOfSegments Nombre de segments d'analyse parallèle à utiliser quand Violation Detector analyse la table. La valeur par défaut est 1, ce qui signifie que la table est analysée de manière séquentielle. Si la valeur est 2 ou plus, Violation Detector scinde la table en plusieurs segments logiques et un nombre égal de threads d'analyse. La valeur maximale pour numOfSegments est 4096. Pour les plus grandes tables, une analyse parallèle est généralement plus rapide qu'une analyse séquentielle. En outre, si la table est suffisamment grande pour couvrir plusieurs partitions, une analyse parallèle répartit son activité de lecture de façon égale entre plusieurs partitions. Pour plus d'informations sur les analyses parallèles dans DynamoDB, consultez Analyse en parallèle (p. 296). API Version 2012-08-10 355 Non Amazon DynamoDB Manuel du développeur Index secondaires globaux Nom du paramètre Description Obligatoire? numOfViolations Limite supérieure des violations de clé d'index à écrire sur le fichier de sortie. Si la valeur est -1 (valeur par défaut), la totalité de la table est analysée. Si la valeur est un nombre entier positif, Violation Detector s'arrête une fois qu'il a atteint le nombre de violations. Non numOfRecords Nombre d'éléments de la table à analyser. Si la valeur est -1 (valeur par défaut), la totalité de la table est analysée. Si la valeur est un nombre entier positif, Violation Detector s'arrête une fois qu'il a analysé le nombre correspondant d'éléments de la table. Non readWriteIOPSPercent Règle le pourcentage d'unités de capacité en lecture provisionnées qui sont consommées lors de l'analyse de la table. Les valeurs valides s'étendent de 1 à 100. La valeur par défaut (25) signifie que Violation Detector ne consomme pas plus de 25 % du débit en lecture provisionné de la table. Non correctionInputPath Chemin d'accès complet du fichier en entrée de correction Violation Detector. Si vous exécutez Violation Detector en mode de correction, le contenu du fichier est utilisé pour modifier ou supprimer les éléments de données de la table qui enfreignent l'index secondaire global. Non Le format du fichier correctionInputPath est identique à celui du fichier detectionOutputPath. Cela vous permet de traiter la sortie du mode détection comme entrée du mode correction. API Version 2012-08-10 356 Amazon DynamoDB Manuel du développeur Index secondaires globaux Nom du paramètre Description Obligatoire? correctionOutputPath Chemin d'accès complet du fichier en sortie de correction Violation Detector. Ce fichier est créé uniquement en cas d'erreurs de mise à jour. Non Ce paramètre prend en charge l'écriture sur un répertoire local ou sur Amazon Simple Storage Service (Amazon S3). Voici quelques exemples : correctionOutputPath = //local/path/ filename.csv correctionOutputPath = s3://bucket/filename.csv Les informations du fichier de sortie s'affichent au format CSV (valeurs séparées par des virgules). Si vous ne définissez pas correctionOutputPath, le fichier de sortie est nommé violation_update_errors.csv et il est écrit sur votre répertoire de travail actif. Détection Afin de détecter les violations de clé d'index, utilisez Violation Detector avec l'option de ligne de commande --detect. Pour montrer le fonctionnement de cette option, prenez en compte la table ProductCatalog affichée dans Création de tables et chargement d'exemples de données (p. 167). Ce qui suit est une liste d'éléments de la table ; seuls la clé primaire (Id) et l'attribut Price sont affichés. Id (clé primaire) Prix 101 -2 102 20 103 200 201 100 202 200 203 300 204 400 205 500 API Version 2012-08-10 357 Amazon DynamoDB Manuel du développeur Index secondaires globaux Notez que toutes les valeurs de Price sont de type Number (numérique). Cependant, comme DynamoDB est sans schéma, il est possible d'ajouter un élément avec un Price non numérique. Par exemple, supposons que nous ajoutions un autre élément à la table ProductCatalog : Id (clé primaire) Prix 999 "Hello" La table a maintenant un total de neuf éléments. Maintenant, nous allons ajouter un nouvel index secondaire global à la table : PriceIndex. La clé primaire de l'index est une clé de partition, Price, qui est de type Number (numérique). Une fois que l'index a été créé, il contient huit éléments, mais la table ProductCatalog comporte neuf éléments. La raison de cet écart est que la valeur "Hello" est de type String (chaîne), mais que PriceIndex a une clé primaire de type Number (numérique). La valeur String (chaîne) violant la clé d'index de l'index secondaire global, elle n'est pas présente dans l'index. Pour utiliser Violation Detector dans ce scénario, vous créez d'abord un fichier de configuration tel que le suivant : # Properties file for violation detection tool configuration. # Parameters that are not specified will use default values. awsCredentialsFile = /home/alice/credentials.txt dynamoDBRegion = us-west-2 tableName = ProductCatalog gsiHashKeyName = Price gsiHashKeyType = N recordDetails = true recordGsiValueInViolationRecord = true detectionOutputPath = ./gsi_violation_check.csv correctionInputPath = ./gsi_violation_check.csv numOfSegments = 1 readWriteIOPSPercent = 40 Ensuite, vous exécutez Violation Detector dans cet exemple : $ java -jar ViolationDetector.jar --configFilePath config.txt --detect keep Violation detection started: sequential scan, Table name: ProductCatalog, GSI name: PriceIndex Progress: Items scanned in total: 9, Items scanned by this thread: 9, Violations found by this thread: 1, Violations deleted by this thread: 0 Violation detection finished: Records scanned: 9, Violations found: 1, Violations deleted: 0, see results at: ./gsi_violation_check.csv Si le paramètre de configuration recordDetails a la valeur true, Violation Detector écrit les détails de chaque violation dans le fichier de sortie, comme dans l'exemple suivant : Table Hash Key,GSI Hash Key Value,GSI Hash Key Violation Type,GSI Hash Key Violation Description,GSI Hash Key Update Value(FOR USER),Delete Blank Attributes When Updating?(Y/N) 999,"{""S"":""Hello""}",Type Violation,Expected: N Found: S,, API Version 2012-08-10 358 Amazon DynamoDB Manuel du développeur Index secondaires globaux Le fichier de sortie est au format CSV (valeurs séparées par des virgules). La première ligne du fichier est un en-tête, suivi d'un enregistrement par élément qui enfreint la clé d'index. Les champs de ces enregistrements de violation sont les suivants : • Table Hash Key : valeur de clé de partition de l'élément de la table. • Table Range Key : valeur de clé de tri de l'élément de la table. • GSI Hash Key Value : valeur de clé de partition de l'index secondaire global • GSI Hash Key Violation Type : Type Violation ou Size Violation. • GSI Hash Key Violation Description : cause de la violation. • GSI Hash Key Update Value(FOR USER) : en mode correction, une nouvelle valeur fournie par l'utilisateur pour l'attribut. • GSI Range Key Value : valeur de clé de tri de l'index secondaire global • GSI Range Key Violation Type : Type Violation ou Size Violation. • GSI Range Key Violation Description : cause de la violation. • GSI Range Key Update Value(FOR USER) : en mode correction, une nouvelle valeur fournie par l'utilisateur pour l'attribut. • Delete Blank Attribute When Updating(Y/N) : en mode correction, détermine s'il faut supprimer (Y) ou conserver (N) l'élément de violation de la table, mais uniquement si l'un des champs suivants est vide : • GSI Hash Key Update Value(FOR USER) • GSI Range Key Update Value(FOR USER) Si l'un des ces champs n'est pas vide, Delete Blank Attribute When Updating(Y/N) n'a aucun effet. Note Le format de sortie peut varier selon le fichier de configuration et les options de ligne de commande. Par exemple, si la table a une clé primaire simple (sans clé de tri), aucun champ de clé de tri n'est présent dans la sortie. Les enregistrements de violation dans le fichier peuvent ne pas être triés. Correction Pour corriger les violations de clé d'index, utilisez Violation Detector avec l'option de ligne de commande --correct. En mode correction, Violation Detector lit le fichier d'entrée spécifié par le paramètre correctionInputPath. Ce fichier a le même format que le fichier detectionOutputPath, de telle sorte que vous pouvez utiliser la sortie de la détection comme entrée de la correction. Violation Detector fournit deux méthodes différentes pour corriger les violations de clé d'index : • Supprimer les violations : supprimer les éléments de la table qui ont violé les valeurs d'attribut. • Mettre à jour les violations : mettre à jour les éléments de la table, en remplaçant les attributs à l'origine de la violation par des attributs ne donnant pas lieu à violation. Dans les deux cas, vous pouvez utiliser le fichier de sortie du mode détection comme entrée du mode correction. Si nous poursuivons avec notre exemple ProductCatalog, supposons que nous voulions supprimer de la table l'élément à l'origine de la violation. Pour ce faire, nous utilisons la ligne de commande suivante : API Version 2012-08-10 359 Amazon DynamoDB Manuel du développeur Index secondaires globaux $ java -jar ViolationDetector.jar --configFilePath config.txt --correct delete A ce stade, vous devez confirmer si vous souhaitez supprimer les éléments de violation. Are you sure to delete all violations on the table?y/n y Confirmed, will delete violations on the table... Violation correction from file started: Reading records from file: ./ gsi_violation_check.csv, will delete these records from table. Violation correction from file finished: Violations delete: 1, Violations Update: 0 Désormais, ProductCatalog et PriceIndex ont le même nombre d'éléments. Utilisation des Index global secondaire : Java Vous pouvez utiliser l'API Document AWS SDK for Java pour créer une table avec un ou plusieurs index secondaire global, décrire les index sur la table et exécuter des requêtes en utilisant les index. Voici les étapes courantes pour les opérations de table. 1. Créez une instance de la classe DynamoDB. 2. Fournissez les paramètres obligatoires et facultatifs pour l'opération en créant les objets de requête correspondants. 3. Appelez la méthode appropriée fournie par le client que vous avez créée à l'étape précédente. Créer une table avec un Index global secondaire Vous pouvez créer des index secondaire global en même temps que vous créez une table. Pour ce faire, utilisez CreateTable et fournissez vos spécifications pour un ou plusieurs index secondaire global. L'extrait de code Java suivant crée une table pour conserver les informations sur les données météorologiques. La clé de partition est Location et la clé de tri est Date. Un index secondaire global nommé PrecipIndex permet un accès rapide aux données de précipitations pour divers emplacements. Voici les étapes pour créer une table avec un index secondaire global, à l'aide de l'API document DynamoDB. 1. Créez une instance de la classe DynamoDB. 2. Créez une instance de la classe CreateTableRequest pour fournir l'information de requête. Vous devez fournir le nom de la table, sa clé primaire et les valeurs du débit alloué. Pour les index secondaire global, vous devez fournir le nom d'index, ses paramètres de débit alloué, les définitions d'attribut pour la clé de tri d'index, le schéma de clés pour l'index et les projections d'attribut. 3. Appelez la méthode createTable en fournissant l'objet de requête comme paramètre. L'extrait de code Java suivant illustre les étapes précédentes. L'extrait crée une table (WeatherData) avec un index secondaire global (PrecipIndex). La clé de partition d'index est Date et sa clé de tri est Precipitation. Tous les attributs de table sont projetés sur l'index. Les utilisateurs peuvent interroger cet index pour obtenir des données météorologiques pour une date spécifique, avec une option de tri des données par volume des précipitations. Veuillez noter que dans la mesure où Precipitation n'est pas un attribut clé pour la table, il n'est pas obligatoire. Cependant, les éléments WeatherData sans Precipitation n'apparaîtront pas dans PrecipIndex. API Version 2012-08-10 360 Amazon DynamoDB Manuel du développeur Index secondaires globaux DynamoDB dynamoDB = new DynamoDB(new AmazonDynamoDBClient( new ProfileCredentialsProvider())); // Attribute definitions ArrayList<AttributeDefinition> attributeDefinitions = new ArrayList<AttributeDefinition>(); attributeDefinitions.add(new AttributeDefinition() .withAttributeName("Location") .withAttributeType("S")); attributeDefinitions.add(new AttributeDefinition() .withAttributeName("Date") .withAttributeType("S")); attributeDefinitions.add(new AttributeDefinition() .withAttributeName("Precipitation") .withAttributeType("N")); // Table key schema ArrayList<KeySchemaElement> tableKeySchema = new ArrayList<KeySchemaElement>(); tableKeySchema.add(new KeySchemaElement() .withAttributeName("Location") .withKeyType(KeyType.HASH)); //Partition key tableKeySchema.add(new KeySchemaElement() .withAttributeName("Date") .withKeyType(KeyType.RANGE)); //Sort key // PrecipIndex GlobalSecondaryIndex precipIndex = new GlobalSecondaryIndex() .withIndexName("PrecipIndex") .withProvisionedThroughput(new ProvisionedThroughput() .withReadCapacityUnits((long) 10) .withWriteCapacityUnits((long) 1)) .withProjection(new Projection().withProjectionType(ProjectionType.ALL)); ArrayList<KeySchemaElement> indexKeySchema = new ArrayList<KeySchemaElement>(); indexKeySchema.add(new KeySchemaElement() .withAttributeName("Date") .withKeyType(KeyType.HASH)); //Partition key indexKeySchema.add(new KeySchemaElement() .withAttributeName("Precipitation") .withKeyType(KeyType.RANGE)); //Sort key precipIndex.setKeySchema(indexKeySchema); CreateTableRequest createTableRequest = new CreateTableRequest() .withTableName("WeatherData") .withProvisionedThroughput(new ProvisionedThroughput() .withReadCapacityUnits((long) 5) .withWriteCapacityUnits((long) 1)) .withAttributeDefinitions(attributeDefinitions) .withKeySchema(tableKeySchema) .withGlobalSecondaryIndexes(precipIndex); Table table = dynamoDB.createTable(createTableRequest); API Version 2012-08-10 361 Amazon DynamoDB Manuel du développeur Index secondaires globaux System.out.println(table.getDescription()); Vous devez attendre que DynamoDB ait créé la table et défini l'état de la table sur ACTIVE. Après cela, vous pouvez commencer à mettre les éléments de données dans la table. Décrire une Table avec un Index global secondaire Pour obtenir des informations sur les index secondaire global d'une table, utilisez DescribeTable. Pour chaque index, vous pouvez accéder à son nom, son schéma de clé et ses attributs projetés. Voici les étapes pour accéder aux informations index secondaire global d'une table. 1. Créez une instance de la classe DynamoDB. 2. Créez une instance de la classe Table pour représenter l'index que vous souhaitez utiliser. 3. Appelez la méthode describe sur l'objet Table. L'extrait de code Java suivant illustre les étapes précédentes. DynamoDB dynamoDB = new DynamoDB(new AmazonDynamoDBClient( new ProfileCredentialsProvider())); Table table = dynamoDB.getTable("WeatherData"); TableDescription tableDesc = table.describe(); Iterator<GlobalSecondaryIndexDescription> gsiIter = tableDesc.getGlobalSecondaryIndexes().iterator(); while (gsiIter.hasNext()) { GlobalSecondaryIndexDescription gsiDesc = gsiIter.next(); System.out.println("Info for index " + gsiDesc.getIndexName() + ":"); Iterator<KeySchemaElement> kseIter = gsiDesc.getKeySchema().iterator(); while (kseIter.hasNext()) { KeySchemaElement kse = kseIter.next(); System.out.printf("\t%s: %s\n", kse.getAttributeName(), kse.getKeyType()); } Projection projection = gsiDesc.getProjection(); System.out.println("\tThe projection type is: " + projection.getProjectionType()); if (projection.getProjectionType().toString().equals("INCLUDE")) { System.out.println("\t\tThe non-key projected attributes are: " + projection.getNonKeyAttributes()); } } Interroger un Index global secondaire Vous pouvez utiliser Query sur un index secondaire global, de la même façon que vous exécutez une opération Query sur une table. Vous devez spécifier le nom d'index, les critères de la requête pour la clé de partition d'index et la clé de tri (le cas échéant), ainsi que les attributs que vous souhaitez renvoyer. Dans cet exemple, l'index est PrecipIndex, qui a une clé de partition Date et une clé de tri Precipitation. La requête d'index renvoie toutes les données météorologiques pour une date particulière, où le volume des précipitations est supérieur à zéro. Voici les étapes pour interroger un index secondaire global à l'aide de l'API Document de AWS SDK for Java. API Version 2012-08-10 362 Amazon DynamoDB Manuel du développeur Index secondaires globaux 1. Créez une instance de la classe DynamoDB. 2. Créez une instance de la classe Table pour représenter l'index que vous souhaitez utiliser. 3. Création d'une instance de la classe Index pour l'index que vous souhaitez interroger. 4. Appelez la méthode query sur l'objet Index. Le nom d'attribut Date est un mot réservé DynamoDB. Par conséquent, nous devons utiliser un nom d'attribut d'expression comme espace réservé dans KeyConditionExpression. L'extrait de code Java suivant illustre les étapes précédentes. DynamoDB dynamoDB = new DynamoDB(new AmazonDynamoDBClient( new ProfileCredentialsProvider())); Table table = dynamoDB.getTable("WeatherData"); Index index = table.getIndex("PrecipIndex"); QuerySpec spec = new QuerySpec() .withKeyConditionExpression("#d = :v_date and Precipitation = :v_precip") .withNameMap(new NameMap() .with("#d", "Date")) .withValueMap(new ValueMap() .withString(":v_date","2013-08-10") .withNumber(":v_precip",0)); ItemCollection<QueryOutcome> items = index.query(spec); Iterator<Item> iter = items.iterator(); while (iter.hasNext()) { System.out.println(iter.next().toJSONPretty()); } Exemple : Index global secondaire à l'aide de l'API Document AWS SDK for Java L'exemple de code Java suivant montre comment utiliser les index secondaire global. L'exemple crée une table nommée Issues qui peut être utilisée dans un système simple de suivi des bogues pour le développement de logiciels. La clé de partition est IssueId et la clé de tri est Title. Il y a trois index secondaire global sur ce tableau : • CreateDateIndex—La clé de partition est CreateDate et la clé de tri est IssueId. En plus des clés de table, les attributs Description et Status sont projetés sur l'index. • TitleIndex— la clé de partition est IssueId et la clé de tri est Title. Aucun attribut autre que les clés de table n'est projeté sur l'index. • DueDateIndex—la clé de partition est DueDate et il n'y a aucune clé de tri. Tous les attributs de table sont projetés sur l'index. Une fois la table Issues créée, le programme charge la table avec des données représentant des rapports de bogues logiciels puis interroge les données à l'aide des index secondaire global. Enfin, le programme supprime la table Issues. Pour obtenir les instructions pas à pas afin de tester l'exemple suivant, consultez Exemples de Code Java (p. 173). // Copyright 2012-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. // Licensed under the Apache License, Version 2.0. package com.amazonaws.codesamples.document; API Version 2012-08-10 363 Amazon DynamoDB Manuel du développeur Index secondaires globaux import java.util.ArrayList; import java.util.Iterator; import import import import import import import import import import import import import import import import import com.amazonaws.auth.profile.ProfileCredentialsProvider; com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient; com.amazonaws.services.dynamodbv2.document.DynamoDB; com.amazonaws.services.dynamodbv2.document.Index; com.amazonaws.services.dynamodbv2.document.Item; com.amazonaws.services.dynamodbv2.document.ItemCollection; com.amazonaws.services.dynamodbv2.document.QueryOutcome; com.amazonaws.services.dynamodbv2.document.Table; com.amazonaws.services.dynamodbv2.document.spec.QuerySpec; com.amazonaws.services.dynamodbv2.document.utils.ValueMap; com.amazonaws.services.dynamodbv2.model.AttributeDefinition; com.amazonaws.services.dynamodbv2.model.CreateTableRequest; com.amazonaws.services.dynamodbv2.model.GlobalSecondaryIndex; com.amazonaws.services.dynamodbv2.model.KeySchemaElement; com.amazonaws.services.dynamodbv2.model.KeyType; com.amazonaws.services.dynamodbv2.model.Projection; com.amazonaws.services.dynamodbv2.model.ProvisionedThroughput; public class DocumentAPIGlobalSecondaryIndexExample { static DynamoDB dynamoDB = new DynamoDB(new AmazonDynamoDBClient( new ProfileCredentialsProvider())); public static String tableName = "Issues"; public static void main(String[] args) throws Exception { createTable(); loadData(); queryIndex("CreateDateIndex"); queryIndex("TitleIndex"); queryIndex("DueDateIndex"); deleteTable(tableName); } public static void createTable() { // Attribute definitions ArrayList<AttributeDefinition> attributeDefinitions = new ArrayList<AttributeDefinition>(); attributeDefinitions.add(new AttributeDefinition() .withAttributeName("IssueId") .withAttributeType("S")); attributeDefinitions.add(new AttributeDefinition() .withAttributeName("Title") .withAttributeType("S")); attributeDefinitions.add(new AttributeDefinition() .withAttributeName("CreateDate") .withAttributeType("S")); API Version 2012-08-10 364 Amazon DynamoDB Manuel du développeur Index secondaires globaux attributeDefinitions.add(new AttributeDefinition() .withAttributeName("DueDate") .withAttributeType("S")); // Key schema for table ArrayList<KeySchemaElement> tableKeySchema = new ArrayList<KeySchemaElement>(); tableKeySchema.add(new KeySchemaElement() .withAttributeName("IssueId") .withKeyType(KeyType.HASH)); //Partition key tableKeySchema.add(new KeySchemaElement() .withAttributeName("Title") .withKeyType(KeyType.RANGE)); //Sort key // Initial provisioned throughput settings for the indexes ProvisionedThroughput ptIndex = new ProvisionedThroughput() .withReadCapacityUnits(1L) .withWriteCapacityUnits(1L); // CreateDateIndex GlobalSecondaryIndex createDateIndex = new GlobalSecondaryIndex() .withIndexName("CreateDateIndex") .withProvisionedThroughput(ptIndex) .withKeySchema( new KeySchemaElement() .withAttributeName("CreateDate") .withKeyType( KeyType.HASH), //Partition key new KeySchemaElement() .withAttributeName("IssueId") .withKeyType(KeyType.RANGE)) //Sort key .withProjection(new Projection() .withProjectionType("INCLUDE") .withNonKeyAttributes("Description", "Status")); // TitleIndex GlobalSecondaryIndex titleIndex = new GlobalSecondaryIndex() .withIndexName("TitleIndex") .withProvisionedThroughput(ptIndex) .withKeySchema(new KeySchemaElement() .withAttributeName("Title") .withKeyType(KeyType.HASH), //Partition key new KeySchemaElement() .withAttributeName("IssueId") .withKeyType(KeyType.RANGE)) //Sort key .withProjection(new Projection() .withProjectionType("KEYS_ONLY")); // DueDateIndex GlobalSecondaryIndex dueDateIndex = new GlobalSecondaryIndex() .withIndexName("DueDateIndex") .withProvisionedThroughput(ptIndex) .withKeySchema( new KeySchemaElement() .withAttributeName("DueDate") .withKeyType(KeyType.HASH)) //Partition key .withProjection(new Projection() .withProjectionType("ALL")); CreateTableRequest createTableRequest = new CreateTableRequest() .withTableName(tableName) API Version 2012-08-10 365 Amazon DynamoDB Manuel du développeur Index secondaires globaux .withProvisionedThroughput( new ProvisionedThroughput() .withReadCapacityUnits( (long) 1) .withWriteCapacityUnits( (long) 1)) .withAttributeDefinitions(attributeDefinitions) .withKeySchema(tableKeySchema) .withGlobalSecondaryIndexes(createDateIndex, titleIndex, dueDateIndex); System.out.println("Creating table " + tableName + "..."); dynamoDB.createTable(createTableRequest); // Wait for table to become active System.out.println("Waiting for " + tableName + " to become ACTIVE..."); try { Table table = dynamoDB.getTable(tableName); table.waitForActive(); } catch (InterruptedException e) { e.printStackTrace(); } } public static void queryIndex(String indexName) { Table table = dynamoDB.getTable(tableName); System.out.println ("\n***********************************************************\n"); System.out.print("Querying index " + indexName + "..."); Index index = table.getIndex(indexName); ItemCollection<QueryOutcome> items = null; QuerySpec querySpec = new QuerySpec(); if (indexName == "CreateDateIndex") { System.out.println("Issues filed on 2013-11-01"); querySpec.withKeyConditionExpression("CreateDate = :v_date and begins_with(IssueId, :v_issue)") .withValueMap(new ValueMap() .withString(":v_date","2013-11-01") .withString(":v_issue","A-")); items = index.query(querySpec); } else if (indexName == "TitleIndex") { System.out.println("Compilation errors"); querySpec.withKeyConditionExpression("Title = :v_title and begins_with(IssueId, :v_issue)") .withValueMap(new ValueMap() .withString(":v_title","Compilation error") .withString(":v_issue","A-")); items = index.query(querySpec); } else if (indexName == "DueDateIndex") { System.out.println("Items that are due on 2013-11-30"); querySpec.withKeyConditionExpression("DueDate = :v_date") .withValueMap(new ValueMap() .withString(":v_date","2013-11-30")); items = index.query(querySpec); } else { API Version 2012-08-10 366 Amazon DynamoDB Manuel du développeur Index secondaires globaux System.out.println("\nNo valid index name provided"); return; } Iterator<Item> iterator = items.iterator(); System.out.println("Query: printing results..."); while (iterator.hasNext()) { System.out.println(iterator.next().toJSONPretty()); } } public static void deleteTable(String tableName) { System.out.println("Deleting table " + tableName + "..."); Table table = dynamoDB.getTable(tableName); table.delete(); // Wait for table to be deleted System.out.println("Waiting for " + tableName + " to be deleted..."); try { table.waitForDelete(); } catch (InterruptedException e) { e.printStackTrace(); } } public static void loadData() { System.out.println("Loading data into table " + tableName + "..."); // // // // IssueId, Title, Description, CreateDate, LastUpdateDate, DueDate, Priority, Status putItem("A-101","Compilation error", "Can't compile Project X - bad version number. What does this mean?", "2013-11-01", "2013-11-02", "2013-11-10", 1, "Assigned"); putItem("A-102","Can't read data file", "The main data file is missing, or the permissions are incorrect", "2013-11-01", "2013-11-04", "2013-11-30", 2, "In progress"); putItem("A-103", "Test failure", "Functional test of Project X produces errors", "2013-11-01", "2013-11-02", "2013-11-10", 1, "In progress"); putItem("A-104", "Compilation error", "Variable 'messageCount' was not initialized.", API Version 2012-08-10 367 Amazon DynamoDB Manuel du développeur Index secondaires globaux "2013-11-15", "2013-11-16", "2013-11-30", 3, "Assigned"); putItem("A-105", "Network issue", "Can't ping IP address 127.0.0.1. Please fix this.", "2013-11-15", "2013-11-16", "2013-11-19", 5, "Assigned"); } public static void putItem( String issueId, String title, String description, String createDate, String lastUpdateDate, String dueDate, Integer priority, String status) { Table table = dynamoDB.getTable(tableName); Item item = new Item() .withPrimaryKey("IssueId", issueId) .withString("Title", title) .withString("Description", description) .withString("CreateDate", createDate) .withString("LastUpdateDate", lastUpdateDate) .withString("DueDate", dueDate) .withNumber("Priority", priority) .withString("Status", status); table.putItem(item); } } Utilisation de Index global secondaire : .NET Rubriques • Créer une table avec un Index global secondaire (p. 369) • Décrire une Table avec un Index global secondaire (p. 370) • Interroger un Index global secondaire (p. 371) • Exemple : Index global secondaire utilisant le SDK AWS pour l'API de bas niveau .NET (p. 372) Vous pouvez utiliser l'API de bas niveau du SDK AWS pour .NET afin de créer une table avec un ou plusieurs index secondaire global, décrire les index de la table et exécuter les requêtes à l'aide des index. Ces opérations sont mappées avec les opérations DynamoDB correspondantes. Pour plus d'informations, consultez Amazon DynamoDB API Reference. Voici les étapes courantes pour les opérations de table à l'aide de l'API de bas niveau .NET. 1. Créez une instance de la classe AmazonDynamoDBClient. 2. Fournissez les paramètres obligatoires et facultatifs pour l'opération en créant les objets de requête correspondants. Par exemple, créez un objet CreateTableRequest pour créer une table et un objet QueryRequest pour interroger une table ou un index. 3. Exécutez la méthode appropriée fournie par le client que vous avez créée à l'étape précédente. API Version 2012-08-10 368 Amazon DynamoDB Manuel du développeur Index secondaires globaux Créer une table avec un Index global secondaire Vous pouvez créer des index secondaire global en même temps que vous créez une table. Pour ce faire, utilisez CreateTable et fournissez vos spécifications pour un ou plusieurs index secondaire global. L'extrait de code C# suivant crée une table pour conserver les informations sur les données météorologiques. La clé de partition est Location et la clé de tri est Date. Un index secondaire global nommé PrecipIndex permet un accès rapide aux données de précipitations pour divers emplacements. Voici les étapes pour créer une table avec un index secondaire global, à l'aide de l'API de bas niveau .NET. 1. Créez une instance de la classe AmazonDynamoDBClient. 2. Créez une instance de la classe CreateTableRequest pour fournir l'information de requête. Vous devez fournir le nom de la table, sa clé primaire et les valeurs du débit alloué. Pour les index secondaire global, vous devez fournir le nom d'index, ses paramètres de débit alloué, les définitions d'attribut pour la clé de tri d'index, le schéma de clés pour l'index et les projections d'attribut. 3. Exécutez la méthode CreateTable en fournissant l'objet de requête comme paramètre. L'extrait de code C# suivant illustre les étapes précédentes. L'extrait crée une table (WeatherData) avec un index secondaire global (PrecipIndex). La clé de partition d'index est Date et sa clé de tri est Precipitation. Tous les attributs de table sont projetés sur l'index. Les utilisateurs peuvent interroger cet index pour obtenir des données météorologiques pour une date spécifique, avec une option de tri des données par volume des précipitations. Veuillez noter que dans la mesure où Precipitation n'est pas un attribut clé pour la table, il n'est pas obligatoire. Cependant, les éléments WeatherData sans Precipitation n'apparaîtront pas dans PrecipIndex. client = new AmazonDynamoDBClient(); string tableName = "WeatherData"; // Attribute definitions var attributeDefinitions = new List<AttributeDefinition>() { {new AttributeDefinition{ AttributeName = "Location", AttributeType = "S"}}, {new AttributeDefinition{ AttributeName = "Date", AttributeType = "S"}}, {new AttributeDefinition(){ AttributeName = "Precipitation", AttributeType = "N"} } }; // Table key schema var tableKeySchema = new List<KeySchemaElement>() { {new KeySchemaElement { AttributeName = "Location", KeyType = "HASH"}}, //Partition key {new KeySchemaElement { AttributeName = "Date", KeyType = "RANGE"} //Sort key } }; API Version 2012-08-10 369 Amazon DynamoDB Manuel du développeur Index secondaires globaux // PrecipIndex var precipIndex = new GlobalSecondaryIndex { IndexName = "PrecipIndex", ProvisionedThroughput = new ProvisionedThroughput { ReadCapacityUnits = (long)10, WriteCapacityUnits = (long)1 }, Projection = new Projection { ProjectionType = "ALL" } }; var indexKeySchema = new List<KeySchemaElement> { {new KeySchemaElement { AttributeName = "Date", KeyType = "HASH"}}, // Partition key {new KeySchemaElement{AttributeName = "Precipitation",KeyType = "RANGE"}} //Sort key }; precipIndex.KeySchema = indexKeySchema; CreateTableRequest createTableRequest = new CreateTableRequest { TableName = tableName, ProvisionedThroughput = new ProvisionedThroughput { ReadCapacityUnits = (long)5, WriteCapacityUnits = (long)1 }, AttributeDefinitions = attributeDefinitions, KeySchema = tableKeySchema, GlobalSecondaryIndexes = { precipIndex } }; CreateTableResponse response = client.CreateTable(createTableRequest); Console.WriteLine(response.CreateTableResult.TableDescription.TableName); Console.WriteLine(response.CreateTableResult.TableDescription.TableStatus); Vous devez attendre que DynamoDB ait créé la table et défini l'état de la table sur ACTIVE. Après cela, vous pouvez commencer à mettre les éléments de données dans la table. Décrire une Table avec un Index global secondaire Pour obtenir des informations sur les index secondaire global d'une table, utilisez DescribeTable. Pour chaque index, vous pouvez accéder à son nom, son schéma de clé et ses attributs projetés. Voici les étapes pour accéder aux informations index secondaire global sur une table à l'aide de l'API de bas niveau .NET. 1. Créez une instance de la classe AmazonDynamoDBClient. 2. Créez une instance de la classe DescribeTableRequest pour fournir l'information de requête. Vous devez fournir le nom de la table. 3. Exécutez la méthode describeTable en fournissant l'objet de requête comme un paramètre. L'extrait de code C# suivant illustre les étapes précédentes. client = new AmazonDynamoDBClient(); API Version 2012-08-10 370 Amazon DynamoDB Manuel du développeur Index secondaires globaux string tableName = "WeatherData"; DescribeTableResponse response = client.DescribeTable(new DescribeTableRequest { TableName = tableName}); List<GlobalSecondaryIndexDescription> globalSecondaryIndexes = response.DescribeTableResult.Table.GlobalSecondaryIndexes; // This code snippet will work for multiple indexes, even though // there is only one index in this example. foreach (GlobalSecondaryIndexDescription gsiDescription in globalSecondaryIndexes) { Console.WriteLine("Info for index " + gsiDescription.IndexName + ":"); foreach (KeySchemaElement kse in gsiDescription.KeySchema) { Console.WriteLine("\t" + kse.AttributeName + ": key type is " + kse.KeyType); } Projection projection = gsiDescription.Projection; Console.WriteLine("\tThe projection type is: " + projection.ProjectionType); if (projection.ProjectionType.ToString().Equals("INCLUDE")) { Console.WriteLine("\t\tThe non-key projected attributes are: " + projection.NonKeyAttributes); } } Interroger un Index global secondaire Vous pouvez utiliser Query sur un index secondaire global, de la même façon que vous exécutez une opération Query sur une table. Vous devez spécifier le nom d'index, les critères de la requête pour la clé de partition d'index et la clé de tri (le cas échéant), ainsi que les attributs que vous souhaitez renvoyer. Dans cet exemple, l'index est PrecipIndex, qui a une clé de partition Date et une clé de tri Precipitation. La requête d'index renvoie toutes les données météorologiques pour une date particulière, où le volume des précipitations est supérieur à zéro. Voici les étapes pour interroger un index secondaire global à l'aide de l'API de bas niveau .NET. 1. Créez une instance de la classe AmazonDynamoDBClient. 2. Créez une instance de la classe QueryRequest pour fournir l'information de requête. 3. Exécutez la méthode query en fournissant l'objet de requête comme un paramètre. Le nom d'attribut Date est un mot réservé DynamoDB. Par conséquent, nous devons utiliser un nom d'attribut d'expression comme espace réservé dans KeyConditionExpression. L'extrait de code C# suivant illustre les étapes précédentes. client = new AmazonDynamoDBClient(); QueryRequest queryRequest = new QueryRequest { TableName = "WeatherData", IndexName = "PrecipIndex", KeyConditionExpression = "#dt = :v_date and Precipitation > :v_precip", API Version 2012-08-10 371 Amazon DynamoDB Manuel du développeur Index secondaires globaux ExpressionAttributeNames = new Dictionary<String, String> { {"#dt", "Date"} }, ExpressionAttributeValues = new Dictionary<string, AttributeValue> { {":v_date", new AttributeValue { S = "2013-08-01" }}, {":v_precip", new AttributeValue { N = "0" }} }, ScanIndexForward = true }; var result = client.Query(queryRequest); var items = result.Items; foreach (var currentItem in items) { foreach (string attr in currentItem.Keys) { Console.Write(attr + "---> "); if (attr == "Precipitation") { Console.WriteLine(currentItem[attr].N); } else { Console.WriteLine(currentItem[attr].S); } } Console.WriteLine(); } Exemple : Index global secondaire utilisant le SDK AWS pour l'API de bas niveau .NET L'exemple de code C# suivant montre comment utiliser les index secondaire global. L'exemple crée une table nommée Issues, qui peut être utilisée dans un système simple de suivi des bogues pour le développement de logiciels. La clé de partition est IssueId et la clé de tri est Title. Il y a trois index secondaire global sur ce tableau : • CreateDateIndex : la clé de partition est CreateDate et la clé de tri est IssueId. En plus des clés de table, les attributs Description et Status sont projetés sur l'index. • TitleIndex : la clé de partition est IssueId et la clé de tri est Title. Aucun attribut autre que les clés de table n'est projeté sur l'index. • DueDateIndex : la clé de partition est DueDate et il n'y a aucune clé de tri. Tous les attributs de table sont projetés sur l'index. Une fois la table Issues créée, le programme charge la table avec des données représentant des rapports de bogues logiciels puis interroge les données à l'aide des index secondaire global. Enfin, le programme supprime la table Issues. Pour obtenir les instructions pas à pas afin de tester l'exemple suivant, consultez Exemples de code .NET (p. 175). using using using using System; System.Collections.Generic; System.Linq; Amazon.DynamoDBv2; API Version 2012-08-10 372 Amazon DynamoDB Manuel du développeur Index secondaires globaux using using using using using Amazon.DynamoDBv2.DataModel; Amazon.DynamoDBv2.DocumentModel; Amazon.DynamoDBv2.Model; Amazon.Runtime; Amazon.SecurityToken; namespace com.amazonaws.codesamples { class LowLevelGlobalSecondaryIndexExample { private static AmazonDynamoDBClient client = new AmazonDynamoDBClient(); public static String tableName = "Issues"; public static void Main(string[] args) { CreateTable(); LoadData(); QueryIndex("CreateDateIndex"); QueryIndex("TitleIndex"); QueryIndex("DueDateIndex"); DeleteTable(tableName); Console.WriteLine("To continue, press enter"); Console.Read(); } private static void CreateTable() { // Attribute definitions var attributeDefinitions = new List<AttributeDefinition>() { {new AttributeDefinition {AttributeName = "IssueId", AttributeType = "S"}}, {new AttributeDefinition {AttributeName = "Title", AttributeType = "S"}}, {new AttributeDefinition {AttributeName = "CreateDate", AttributeType = "S"}}, {new AttributeDefinition {AttributeName = "DueDate", AttributeType = "S"}} }; // Key schema for table var tableKeySchema = new List<KeySchemaElement>() { { new KeySchemaElement { AttributeName= "IssueId", KeyType = "HASH" //Partition key } }, { new KeySchemaElement { AttributeName = "Title", KeyType = "RANGE" //Sort key API Version 2012-08-10 373 Amazon DynamoDB Manuel du développeur Index secondaires globaux } } }; // Initial provisioned throughput settings for the indexes var ptIndex = new ProvisionedThroughput { ReadCapacityUnits = 1L, WriteCapacityUnits = 1L }; // CreateDateIndex var createDateIndex = new GlobalSecondaryIndex() { IndexName = "CreateDateIndex", ProvisionedThroughput = ptIndex, KeySchema = { new KeySchemaElement { AttributeName = "CreateDate", KeyType = "HASH" // Partition key }, new KeySchemaElement { AttributeName = "IssueId", KeyType = "RANGE" //Sort key } }, Projection = new Projection { ProjectionType = "INCLUDE", NonKeyAttributes = { "Description", "Status" } } }; // TitleIndex var titleIndex = new GlobalSecondaryIndex() { IndexName = "TitleIndex", ProvisionedThroughput = ptIndex, KeySchema = { new KeySchemaElement { AttributeName = "Title", KeyType = "HASH" // Partition key }, new KeySchemaElement { AttributeName = "IssueId", KeyType = "RANGE" //Sort key } }, Projection = new Projection { ProjectionType = "KEYS_ONLY" } }; // DueDateIndex var dueDateIndex = new GlobalSecondaryIndex() { IndexName = "DueDateIndex", ProvisionedThroughput = ptIndex, API Version 2012-08-10 374 Amazon DynamoDB Manuel du développeur Index secondaires globaux KeySchema = { new KeySchemaElement { AttributeName = "DueDate", KeyType = "HASH" //Partition key } }, Projection = new Projection { ProjectionType = "ALL" } }; var createTableRequest = new CreateTableRequest { TableName = tableName, ProvisionedThroughput = new ProvisionedThroughput { ReadCapacityUnits = (long)1, WriteCapacityUnits = (long)1 }, AttributeDefinitions = attributeDefinitions, KeySchema = tableKeySchema, GlobalSecondaryIndexes = { createDateIndex, titleIndex, dueDateIndex } }; Console.WriteLine("Creating table " + tableName + "..."); client.CreateTable(createTableRequest); WaitUntilTableReady(tableName); } private static void LoadData() { Console.WriteLine("Loading data into table " + tableName + "..."); // // // // IssueId, Title, Description, CreateDate, LastUpdateDate, DueDate, Priority, Status putItem("A-101", "Compilation error", "Can't compile Project X - bad version number. What does this mean?", "2013-11-01", "2013-11-02", "2013-11-10", 1, "Assigned"); putItem("A-102", "Can't read data file", "The main data file is missing, or the permissions are incorrect", "2013-11-01", "2013-11-04", "2013-11-30", 2, "In progress"); putItem("A-103", "Test failure", API Version 2012-08-10 375 Amazon DynamoDB Manuel du développeur Index secondaires globaux "Functional test of Project X produces errors", "2013-11-01", "2013-11-02", "2013-11-10", 1, "In progress"); putItem("A-104", "Compilation error", "Variable 'messageCount' was not initialized.", "2013-11-15", "2013-11-16", "2013-11-30", 3, "Assigned"); putItem("A-105", "Network issue", "Can't ping IP address 127.0.0.1. Please fix this.", "2013-11-15", "2013-11-16", "2013-11-19", 5, "Assigned"); } private static void putItem( String issueId, String title, String description, String createDate, String lastUpdateDate, String dueDate, Int32 priority, String status) { Dictionary<String, AttributeValue> item = new Dictionary<string, AttributeValue>(); item.Add("IssueId", new AttributeValue { S = issueId }); item.Add("Title", new AttributeValue { S = title }); item.Add("Description", new AttributeValue { S = description }); item.Add("CreateDate", new AttributeValue { S = createDate }); item.Add("LastUpdateDate", new AttributeValue { S = lastUpdateDate }); item.Add("DueDate", new AttributeValue { S = dueDate }); item.Add("Priority", new AttributeValue { N = priority.ToString() }); item.Add("Status", new AttributeValue { S = status }); try { client.PutItem(new PutItemRequest { TableName = tableName, Item = item }); } catch (Exception e) { Console.WriteLine(e.ToString()); } } private static void QueryIndex(string indexName) { Console.WriteLine ("\n***********************************************************\n"); Console.WriteLine("Querying index " + indexName + "..."); API Version 2012-08-10 376 Amazon DynamoDB Manuel du développeur Index secondaires globaux QueryRequest queryRequest = new QueryRequest { TableName = tableName, IndexName = indexName, ScanIndexForward = true }; String keyConditionExpression; Dictionary<string, AttributeValue> expressionAttributeValues = new Dictionary<string, AttributeValue>(); if (indexName == "CreateDateIndex") { Console.WriteLine("Issues filed on 2013-11-01\n"); keyConditionExpression = "CreateDate = :v_date and begins_with(IssueId, :v_issue)"; expressionAttributeValues.Add(":v_date", new AttributeValue { S = "2013-11-01" }); expressionAttributeValues.Add(":v_issue", new AttributeValue { S = "A-" }); } else if (indexName == "TitleIndex") { Console.WriteLine("Compilation errors\n"); keyConditionExpression = "Title = :v_title and begins_with(IssueId, :v_issue)"; expressionAttributeValues.Add(":v_title", new AttributeValue { S = "Compilation error" }); expressionAttributeValues.Add(":v_issue", new AttributeValue { S = "A-" }); // Select queryRequest.Select = "ALL_PROJECTED_ATTRIBUTES"; } else if (indexName == "DueDateIndex") { Console.WriteLine("Items that are due on 2013-11-30\n"); keyConditionExpression = "DueDate = :v_date"; expressionAttributeValues.Add(":v_date", new AttributeValue { S = "2013-11-30" }); // Select queryRequest.Select = "ALL_PROJECTED_ATTRIBUTES"; } else { Console.WriteLine("\nNo valid index name provided"); return; } queryRequest.KeyConditionExpression = keyConditionExpression; API Version 2012-08-10 377 Amazon DynamoDB Manuel du développeur Index secondaires globaux queryRequest.ExpressionAttributeValues = expressionAttributeValues; var result = client.Query(queryRequest); var items = result.Items; foreach (var currentItem in items) { foreach (string attr in currentItem.Keys) { if (attr == "Priority") { Console.WriteLine(attr + "---> " + currentItem[attr].N); } else { Console.WriteLine(attr + "---> " + currentItem[attr].S); } } Console.WriteLine(); } } private static void DeleteTable(string tableName) { Console.WriteLine("Deleting table " + tableName + "..."); client.DeleteTable(new DeleteTableRequest { TableName = tableName }); WaitForTableToBeDeleted(tableName); } private static void WaitUntilTableReady(string tableName) { string status = null; // Let us wait until table is created. Call DescribeTable. do { System.Threading.Thread.Sleep(5000); // Wait 5 seconds. try { var res = client.DescribeTable(new DescribeTableRequest { TableName = tableName }); Console.WriteLine("Table name: {0}, status: {1}", res.Table.TableName, res.Table.TableStatus); status = res.Table.TableStatus; } catch (ResourceNotFoundException) { // DescribeTable is eventually consistent. So you might // get resource not found. So we handle the potential exception. API Version 2012-08-10 378 Amazon DynamoDB Manuel du développeur Index secondaires globaux } } while (status != "ACTIVE"); } private static void WaitForTableToBeDeleted(string tableName) { bool tablePresent = true; while (tablePresent) { System.Threading.Thread.Sleep(5000); // Wait 5 seconds. try { var res = client.DescribeTable(new DescribeTableRequest { TableName = tableName }); Console.WriteLine("Table name: {0}, status: {1}", res.Table.TableName, res.Table.TableStatus); } catch (ResourceNotFoundException) { tablePresent = false; } } } } } Utilisation des index secondaires globaux PHP Rubriques • Créer une table avec un Index global secondaire (p. 380) • Décrire une Table avec un Index global secondaire (p. 381) • Interroger un Index global secondaire (p. 381) • Exemple : index secondaires globaux avec l'API de bas niveau du SDK AWS pour PHP (p. 382) Vous pouvez utiliser l'API de bas niveau du SDK AWS pour PHP afin de créer une table avec un ou plusieurs index secondaires globaux, décrire les index de la table et exécuter les requêtes à l'aide des index. Ces opérations sont mappées aux actions DynamoDB correspondantes. Pour de plus amples informations, veuillez consulter Exemples de Code PHP (p. 177). Voici les étapes courantes des opérations de table à l'aide du SDK AWS pour PHP. 1. Créer une instance du client DynamoDB. 2. Fournir les paramètres d'une opération DynamoDB, y compris les paramètres facultatifs. 3. Charger la réponse à partir de DynamoDB dans une variable locale pour votre application. API Version 2012-08-10 379 Amazon DynamoDB Manuel du développeur Index secondaires globaux Créer une table avec un Index global secondaire Vous pouvez créer des index secondaire global en même temps que vous créez une table. Pour ce faire, utilisez CreateTable et fournissez vos spécifications pour un ou plusieurs index secondaire global. L'extrait de code PHP suivant crée une table pour conserver les informations sur les données météorologiques. La clé de partition est Location et la clé de tri est Date. Un index secondaire global nommé PrecipIndex permet un accès rapide aux données de précipitations pour divers emplacements. L'extrait de code suivant crée une table (WeatherData) avec un index secondaire global (PrecipIndex). La clé de partition d'index est Date et sa clé de tri est Precipitation. Tous les attributs de table sont projetés sur l'index. Les utilisateurs peuvent interroger cet index pour obtenir des données météorologiques pour une date spécifique, avec une option de tri des données par volume des précipitations. Veuillez noter que dans la mesure où Precipitation n'est pas un attribut clé pour la table, il n'est pas obligatoire. Cependant, les éléments WeatherData sans Precipitation n'apparaîtront pas dans PrecipIndex. require 'vendor/autoload.php'; $sdk = new Aws\Sdk([ 'region' => 'us-west-2', 'version' => 'latest' ]); $dynamodb = $sdk->createDynamoDb(); $tableName = 'WeatherData'; $result = $dynamodb->createTable([ 'TableName' => $tableName, 'AttributeDefinitions' => [ [ 'AttributeName' => 'Location', 'AttributeType' => 'S' ], [ 'AttributeName' => 'Date', 'AttributeType' => 'S' ], [ 'AttributeName' => 'Precipitation', 'AttributeType' => 'N' ] ], 'KeySchema' => [ [ 'AttributeName' => 'Location', 'KeyType' => 'HASH' ], //Partition key [ 'AttributeName' => 'Date', 'KeyType' => 'RANGE' ] //Sort key ], 'GlobalSecondaryIndexes' => [ [ 'IndexName' => 'PrecipIndex', 'ProvisionedThroughput' => [ 'ReadCapacityUnits' => 5, 'WriteCapacityUnits' => 5 ], 'KeySchema' => [ [ 'AttributeName' => 'Date', 'KeyType' => 'HASH' ], // Partition key [ 'AttributeName' => 'Precipitation', 'KeyType' => 'RANGE' ] //Sort key ], 'Projection' => [ 'ProjectionType' => 'ALL' ] ] ], 'ProvisionedThroughput' => [ API Version 2012-08-10 380 Amazon DynamoDB Manuel du développeur Index secondaires globaux 'ReadCapacityUnits' => 5, 'WriteCapacityUnits' => 5 ] ]); Vous devez attendre que DynamoDB ait créé la table et défini l'état de la table sur ACTIVE. Après cela, vous pouvez commencer à mettre les éléments de données dans la table. Décrire une Table avec un Index global secondaire Pour obtenir des informations sur les index secondaire global d'une table, utilisez DescribeTable. Pour chaque index, vous pouvez accéder à son nom, son schéma de clé et ses attributs projetés. $tableName = 'WeatherData'; $result = $dynamodb->describeTable([ 'TableName' => $tableName ]); foreach ($result['Table']['GlobalSecondaryIndexes'] as $key => $value) { echo "Info for index " . $value['IndexName'] . ":\n"; foreach ($value['KeySchema'] as $attribute => $keyschema) { echo "\t" . $value['KeySchema'][$attribute]['AttributeName'] . ': ' . $value['KeySchema'][$attribute]['KeyType'] . "\n"; } echo "\tThe projection type is: " . $value['Projection'] ['ProjectionType'] . "\n"; } Interroger un Index global secondaire Vous pouvez utiliser Query sur un index secondaire global, de la même façon que vous exécutez une opération Query sur une table. Vous devez spécifier le nom d'index, les critères de la requête pour la clé de partition d'index et la clé de tri (le cas échéant), ainsi que les attributs que vous souhaitez renvoyer. Dans cet exemple, l'index est PrecipIndex, qui a une clé de partition Date et une clé de tri Precipitation. La requête d'index renvoie toutes les données météorologiques pour une date particulière, où le volume des précipitations est supérieur à zéro. Le nom d'attribut Date est un mot réservé DynamoDB. Par conséquent, nous devons utiliser un nom d'attribut d'expression comme espace réservé dans KeyConditionExpression. $tableName = 'WeatherData'; $response = $dynamodb->query([ 'TableName' => $tableName, 'IndexName' => 'PrecipIndex', 'KeyConditionExpression' => '#dt = :v_dt and Precipitation > :v_precip', 'ExpressionAttributeNames' => ['#dt' => 'Date'], 'ExpressionAttributeValues' => [ ':v_dt' => ['S' => '2014-08-01'], ':v_precip' => ['N' => '0'] ], 'Select' => 'ALL_ATTRIBUTES', 'ScanIndexForward' => true, API Version 2012-08-10 381 Amazon DynamoDB Manuel du développeur Index secondaires globaux ]); foreach ($response['Items'] as $item) { echo "Date ---> " . $item['Date']['S'] . "\n"; echo "Location ---> " . $item['Location']['S'] . "\n"; echo "Precipitation ---> " . $item['Precipitation']['N'] . "\n"; echo "\n"; } Exemple : index secondaires globaux avec l'API de bas niveau du SDK AWS pour PHP L'exemple de code PHP suivant montre comment utiliser les index secondaires globaux. L'exemple crée une table nommée Issues, qui peut être utilisée dans un système simple de suivi des bogues pour le développement de logiciels. La clé de partition est IssueId et la clé de tri est Title. Il y a trois index secondaire global sur ce tableau : • CreateDateIndex : la clé de partition est CreateDate et la clé de tri est IssueId. En plus des clés de table, les attributs Description et Status sont projetés sur l'index. • TitleIndex : la clé de partition est IssueId et la clé de tri est Title. Aucun attribut autre que les clés de table n'est projeté sur l'index. • DueDateIndex : la clé de partition est DueDate et il n'y a aucune clé de tri. Tous les attributs de table sont projetés sur l'index. Une fois la table Issues créée, le programme charge la table avec des données représentant des rapports de bogues logiciels puis interroge les données à l'aide des index secondaire global. Enfin, le programme supprime la table Issues. <?php require 'vendor/autoload.php'; date_default_timezone_set('UTC'); use Aws\DynamoDb\Exception\DynamoDbException; $sdk = new Aws\Sdk([ 'region' => 'us-west-2', 'version' => 'latest' ]); $dynamodb = $sdk->createDynamoDb(); $tableName = 'Issues'; echo "# Creating table $tableName...\n"; try { $response = $dynamodb->createTable ( [ 'TableName' => $tableName, 'AttributeDefinitions' => [ [ 'AttributeName' => 'IssueId', 'AttributeType' => 'S' ], [ 'AttributeName' => 'Title', 'AttributeType' => 'S' ], [ 'AttributeName' => 'CreateDate', 'AttributeType' => 'S' ], [ 'AttributeName' => 'DueDate', 'AttributeType' => 'S' ] ], 'KeySchema' => [ API Version 2012-08-10 382 Amazon DynamoDB Manuel du développeur Index secondaires globaux [ 'AttributeName' => 'IssueId', 'KeyType' => 'HASH' ], // Partition key [ 'AttributeName' => 'Title', 'KeyType' => 'RANGE' ] //Sort key ], 'GlobalSecondaryIndexes' => [ [ 'IndexName' => 'CreateDateIndex', 'KeySchema' => [ [ 'AttributeName' => 'CreateDate', 'KeyType' => 'HASH' ], //Partition key [ 'AttributeName' => 'IssueId', 'KeyType' => 'RANGE' ] //Sort key ], 'Projection' => [ 'ProjectionType' => 'INCLUDE', 'NonKeyAttributes' => [ 'Description', 'Status' ] ], 'ProvisionedThroughput' => [ 'ReadCapacityUnits' => 1, 'WriteCapacityUnits' => 1 ] ], [ 'IndexName' => 'TitleIndex', 'KeySchema' => [ [ 'AttributeName' => 'Title', 'KeyType' => 'HASH' ], // Partition key [ 'AttributeName' => 'IssueId', 'KeyType' => 'RANGE' ] //Sort key ], 'Projection' => [ 'ProjectionType' => 'KEYS_ONLY' ], 'ProvisionedThroughput' => [ 'ReadCapacityUnits' => 1, 'WriteCapacityUnits' => 1 ] ], [ 'IndexName' => 'DueDateIndex', 'KeySchema' => [ [ 'AttributeName' => 'DueDate', 'KeyType' => 'HASH' ] // Partition key ], 'Projection' => [ 'ProjectionType' => 'ALL' ], 'ProvisionedThroughput' => [ 'ReadCapacityUnits' => 1, 'WriteCapacityUnits' => 1 ] ] ], 'ProvisionedThroughput' => [ 'ReadCapacityUnits' => 1, 'WriteCapacityUnits' => 1 ] ]); echo " Waiting for table $tableName to be created.\n"; $dynamodb->waitUntil('TableExists', [ 'TableName' => $tableName, '@waiter' => [ 'delay' => 5, 'maxAttempts' => 20 ] ]); API Version 2012-08-10 383 Amazon DynamoDB Manuel du développeur Index secondaires globaux echo " Table $tableName has been created.\n"; } catch (DynamoDbException $e) { echo $e->getMessage() . "\n"; exit ("Unable to create table $tableName\n"); } // ######################################## // Add items to the table echo "# Loading data into $tableName...\n"; $response = $dynamodb->putItem ([ 'TableName' => $tableName, 'Item' => [ 'IssueId' => [ 'S' => 'A-101' ], 'Title' => [ 'S' => 'Compilation error' ], 'Description' => [ 'S' => 'Can\'t compile Project X - bad version number. What does this mean?' ], 'CreateDate' => [ 'S' => '2014-11-01' ], 'LastUpdateDate' => [ 'S' => '2014-11-02' ], 'DueDate' => [ 'S' => '2014-11-10' ], 'Priority' => [ 'N' => '1' ], 'Status' => [ 'S' => 'Assigned' ] ] ]); $response = $dynamodb->putItem ([ 'TableName' => $tableName, 'Item' => [ 'IssueId' => [ 'S' => 'A-102' ], 'Title' => [ 'S' => 'Can\'t read data file' ], 'Description' => [ 'S' => 'The main data file is missing, or the permissions are incorrect' ], 'CreateDate' => [ 'S' => '2014-11-01' ], 'LastUpdateDate' => [ 'S' => '2014-11-04' ], 'DueDate' => [ 'S' => '2014-11-30' ], 'Priority' => [ 'N' => '2' ], 'Status' => [ 'S' => 'In progress' ] ] ]); $response = $dynamodb->putItem ([ 'TableName' => $tableName, 'Item' => [ 'IssueId' => [ 'S' => 'A-103' ], 'Title' => [ 'S' => 'Test failure' ], 'Description' => [ 'S' => 'Functional test of Project X produces errors.' ], 'CreateDate' => [ 'S' => '2014-11-01' ], 'LastUpdateDate' => [ 'S' => '2014-11-02' ], 'DueDate' => [ 'S' => '2014-11-10' ], 'Priority' => [ 'N' => '1' ], 'Status' => [ 'S' => 'In progress' ] ] ]); API Version 2012-08-10 384 Amazon DynamoDB Manuel du développeur Index secondaires globaux $response = $dynamodb->putItem ([ 'TableName' => $tableName, 'Item' => [ 'IssueId' => [ 'S' => 'A-104' ], 'Title' => [ 'S' => 'Compilation error' ], 'Description' => [ 'S' => 'Variable "messageCount" was not initialized.' ], 'CreateDate' => [ 'S' => '2014-11-15' ], 'LastUpdateDate' => [ 'S' => '2014-11-16' ], 'DueDate' => [ 'S' => '2014-11-30' ], 'Priority' => [ 'N' => '3' ], 'Status' => [ 'S' => 'Assigned' ] ] ]); $response = $dynamodb->putItem ([ 'TableName' => $tableName, 'Item' => [ 'IssueId' => [ 'S' => 'A-105' ], 'Title' => [ 'S' => 'Network issue' ], 'Description' => [ 'S' => 'Can\'t ping IP address 127.0.0.1. Please fix this.' ], 'CreateDate' => [ 'S' => '2014-11-15' ], 'LastUpdateDate' => [ 'S' => '2014-11-16' ], 'DueDate' => [ 'S' => '2014-11-19' ], 'Priority' => [ 'N' => '5' ], 'Status' => [ 'S' => 'Assigned' ] ] ]); // ######################################## // Query for issues filed on 2014-11-01 $response = $dynamodb->query ( [ 'TableName' => $tableName, 'IndexName' => 'CreateDateIndex', 'KeyConditionExpression' => 'CreateDate = :v_dt and begins_with(IssueId, :v_issue)', 'ExpressionAttributeValues' => [ ':v_dt' => ['S' => '2014-11-01'], ':v_issue' => ['S' => 'A-'] ] ]); echo '# Query for issues filed on 2014-11-01:' . "\n"; foreach ( $response ['Items'] as $item ) { echo ' - ' . $item ['CreateDate'] ['S'] . ' ' . $item ['IssueId'] ['S'] . ' ' . $item ['Description'] ['S'] . ' ' . $item ['Status'] ['S'] . "\n"; } echo "\n"; // ######################################## // Query for issues that are 'Compilation errors' $response = $dynamodb->query ( [ API Version 2012-08-10 385 Amazon DynamoDB Manuel du développeur Index secondaires globaux 'TableName' => $tableName, 'IndexName' => 'TitleIndex', 'KeyConditionExpression' => 'Title = :v_title and IssueId >= :v_issue', 'ExpressionAttributeValues' => [ ':v_title' => ['S' => 'Compilation error'], ':v_issue' => ['S' => 'A-'] ] ]); echo '# Query for issues that are compilation errors: ' . "\n"; foreach ( $response ['Items'] as $item ) { echo ' - ' . $item ['Title'] ['S'] . ' ' . $item ['IssueId'] ['S'] . "\n"; } echo "\n"; // ######################################## // Query for items that are due on 2014-11-30 $response = $dynamodb->query ( [ 'TableName' => $tableName, 'IndexName' => 'DueDateIndex', 'KeyConditionExpression' => 'DueDate = :v_dt', 'ExpressionAttributeValues' => [ ':v_dt' => ['S' => '2014-11-30'] ] ]); echo "# Querying for items that are due on 2014-11-30:\n"; foreach ( $response ['Items'] as $item ) { echo ' - ' . $item ['DueDate'] ['S'] . ' ' . $item ['IssueId'] ['S'] . ' ' . $item ['Title'] ['S'] . ' ' . $item ['Description'] ['S'] . ' ' . $item ['CreateDate'] ['S'] . ' ' . $item ['LastUpdateDate'] ['S'] . ' ' . $item ['Priority'] ['N'] . ' ' . $item ['Status'] ['S'] . "\n"; } echo "\n"; // ######################################## // Delete the table try { echo "# Deleting table $tableName...\n"; $dynamodb->deleteTable(['TableName' => $tableName]); echo " Waiting for table $tableName to be deleted.\n"; $dynamodb->waitUntil('TableNotExists', [ 'TableName' => $tableName, '@waiter' => [ 'delay' => 5, API Version 2012-08-10 386 Amazon DynamoDB Manuel du développeur Index secondaires locaux 'maxAttempts' => 20 ] ]); echo " Table $tableName has been deleted.\n"; } catch (DynamoDbException $e) { echo $e->getMessage() . "\n"; exit ("Unable to delete table $tableName\n"); } ?> Index secondaires locaux Rubriques • Projections d'attribut (p. 389) • Création d'un index secondaire local (p. 391) • Interrogation d'un index secondaire local (p. 391) • Analyse d'un index secondaire local (p. 392) • Ecritures de l'élément et index secondaires locaux (p. 393) • Considérations sur le débit provisionné pour les index secondaires locaux (p. 393) • Considérations sur le stockage des index secondaires locaux (p. 395) • Collections d'éléments (p. 395) • Utilisation des Index local secondaire : Java (p. 398) • Utilisation de Index local secondaire : .NET (p. 409) • Utilisation des index secondaires locaux : PHP (p. 422) Certaines applications doivent uniquement interroger les données à l'aide de la clé primaire de la table de base ; cependant, il peut y avoir des situations où une clé de tri secondaire sera utile. Pour offrir à votre application un choix de clés de tri, vous pouvez créer une ou plusieurs index secondaires locaux sur une table et émettre les demandes Query ou Scan sur ces index. Par exemple, imaginons la table Thread définie dans Création de tables et chargement d'exemples de données (p. 167). Cette table est utile pour une application telle que les forums de discussion AWS. Le schéma suivant illustre la façon dont les éléments de la table seront organisés. (Tous les attributs ne sont pas affichés.) API Version 2012-08-10 387 Amazon DynamoDB Manuel du développeur Index secondaires locaux DynamoDB stocke tous les éléments avec la même valeur de clé de partition de façon contiguë. Dans cet exemple, soit un ForumName particulier, une opération Query a pu trouver immédiatement tous les threads de ce forum. Au sein d'un groupe d'éléments ayant la même valeur de clé de partition, les éléments sont triés par valeur de clé de tri. Si la clé de tri (Subject) est également fournie dans la requête, DynamoDB peut affiner les résultats retournés : par exemple, en retournant tous les threads du forum « S3 » dont Subject commence par la lettre « a ». Certaines demandes peuvent nécessiter des modèles d'accès aux données plus complexes. Exemples : • Quelles discussions du forum obtiennent le plus de vues et de réponses ? • Quelle discussion en particulier possède le plus grand nombre de messages ? • Combien de discussions ont été publiées dans un forum particulier au sein d'une période donnée ? Pour répondre à ces questions, l'action Query ne suffira pas. Au lieu de cela, vous devrez Scan (analyser) la totalité de la table. Pour une table avec des millions d'éléments, cette action consomme une grande quantité du débit alloué en lecture et nécessite un long temps d'exécution. Cependant, vous pouvez spécifier un ou plusieurs index secondaires locaux sur les attributs non-clés, tels que Replies ou LastPostDateTime. Un index secondaire local gère une clé de tri secondaire pour une valeur de clé de partition donnée. Un index secondaire local contient aussi une copie de tout ou partie des attributs de la table de base ; vous spécifiez les attributs qui sont projetés dans l'index secondaire local lorsque vous créez la table. Les données d'un index secondaire local sont organisées selon la même clé de partition que la table de base, mais avec une clé de tri différente. Vous pouvez ainsi accéder efficacement aux éléments de données au travers de cette dimension différente. Pour une plus grande souplesse de requête ou d'analyse, vous pouvez créer jusqu'à cinq index secondaires locaux par table. Supposons qu'une application ait besoin de trouver toutes les discussions publiées au cours des trois derniers mois. Sans un index secondaire local, l'application devrait Scan (analyser) la totalité de la table Thread et ignorer tous les messages qui ne figurent pas dans le délai spécifié. Avec un index secondaire local, une opération Query peut utiliser LastPostDateTime comme clé de tri et trouver les données rapidement. Le schéma suivant illustre un index secondaire local nommé LastPostIndex. Notez que la clé de partition est identique à celle de la table Thread, mais que la clé de tri est LastPostDateTime. API Version 2012-08-10 388 Amazon DynamoDB Manuel du développeur Index secondaires locaux Chaque index secondaire local doit satisfaire aux conditions suivantes : • La clé de partition est identique à celle de sa table de base. • La clé de tri se compose exactement d'un attribut scalaire. • La clé de tri de la table de base est projetée dans l'index, où il agit comme attribut non-clé. Dans cet exemple, la clé de partition est ForumName et la clé de tri de l'index secondaire local est LastPostDateTime. En outre, la valeur de la clé de tri de la table de base (dans cet exemple, Subject) est projetée dans l'index, mais ne fait pas partie de la clé d'index. Si une application a besoin d'une liste qui s'appuie sur ForumName et LastPostDateTime, elle peut émettre une demande Query sur LastPostIndex. Les résultats de la requête sont triés sur LastPostDateTime et peuvent être retournés en ordre croissant ou décroissant. La requête peut également appliquer des conditions de clé, telles que ne retourner que les éléments ayant un LastPostDateTime au sein d'un intervalle de temps donné. Chaque index secondaire local contient automatiquement les clés de partition et de tri de sa table de base ; vous pouvez, le cas échéant, projeter les attributs non-clés sur l'index. Lorsque vous interrogez l'index, DynamoDB peut extraire ces attributs projetés de façon efficace. Lorsque vous interrogez un index secondaire local, la requête peut également extraire les attributs qui ne sont pas projetés sur l'index. DynamoDB extrait automatiquement ces attributs de la table de base, mais à une latence plus grande et avec des coûts plus élevés de débit alloué. Pour tout index secondaire local, vous pouvez stocker jusqu'à 10 Go de données par valeur de clé de partition distincte. Ce chiffre inclut tous les éléments de la table de base, plus tous les éléments des index, qui ont la même valeur de clé de partition. Pour de plus amples informations, veuillez consulter Collections d'éléments (p. 395). Projections d'attribut Avec LastPostIndex, une application peut utiliser ForumName et LastPostDateTime comme critères de requête ; cependant, pour récupérer tout attribut supplémentaire, DynamoDB a besoin d'effectuer des opérations de lecture supplémentaires sur la table Thread. Ces lectures supplémentaires sont appelées récupérations et peuvent augmenter le montant total du débit alloué nécessaire pour une requête. Supposons que vous vouliez renseigner une page web avec la liste de toutes les discussions dans « S3 » et le nombre de réponses pour chaque discussions, triée sur la dernière date/heure de réponse API Version 2012-08-10 389 Amazon DynamoDB Manuel du développeur Index secondaires locaux en commençant par la réponse la plus récente. Pour remplir cette liste, vous avez besoin des attributs suivants : • Sujet • Replies • LastPostDateTime La façon la plus efficace d'interroger ces données et d'éviter les opérations de récupération consiste à projeter l'attribut Replies depuis de la table vers l'index secondaire local, comme illustré dans ce diagramme : Une projection est l'ensemble d'attributs qui est copié à partir d'une table et appliqué à un index secondaire. La clé de partition et la clé de tri de la table sont toujours projetées dans l'index ; vous pouvez projeter d'autres attributs pour répondre aux besoins d'interrogation de votre application. Lorsque vous interrogez un index, Amazon DynamoDB peut accéder à n'importe quel attribut de la projection comme si ces attributs figuraient dans sa propre table. Lorsque vous créez un index secondaire, vous devez indiquer quels attributs feront l'objet d'une projection dans l'index. DynamoDB propose trois options différentes pour cela : • KEYS_ONLY – chaque élément de l'index se compose uniquement des valeurs de clé de partition et de clé de tri de la table, ainsi que des valeurs de clé d'index. L'option KEYS_ONLY correspond à l'index secondaire le plus petit. • INCLUDE – en plus des attributs décrits dans KEYS_ONLY, l'index secondaire inclut d'autres attributs non-clés que vous spécifiez. • ALL – l'index secondaire inclut tous les attributs de la table source. Comme toutes les données de la table sont dupliquées dans l'index, une projection ALL correspond à l'index secondaire le plus grand. Dans le diagramme précédent, l'attribut non-clé Replies est projeté sur LastPostIndex. Une application peut interroger LastPostIndex au lieu de la table Thread complète pour renseigner une page web avec Subject, Replies et LastPostDateTime. Si d'autres attributs non clés sont demandés, DynamoDB doit récupérer ces attributs à partir de la table Thread. Du point de vue d'une application, la récupération d'attributs supplémentaires à partir de la table de base étant automatique et transparente, il n'est pas nécessaire de réécrire la logique de l'application. API Version 2012-08-10 390 Amazon DynamoDB Manuel du développeur Index secondaires locaux Cependant, notez qu'une telle récupération peut réduire considérablement l'avantage de l'utilisation d'un index secondaire local en termes de performances. Lorsque vous choisissez les attributs à projeter sur un index secondaire local, vous devez prendre en compte le compromis entre les coûts de débit alloué et les coûts de stockage : • Si vous avez juste besoin d'accéder à quelques attributs avec la plus faible latence possible, envisagez de ne projeter que ces attributs sur un index secondaire local. Plus l'index est petit, moins les coûts d'écriture et de stockage sont élevés. S'il y a des attributs que vous devez parfois récupérer, le coût du débit alloué peut bien dépasser leur coût de stockage à plus long terme. • Si votre application accède fréquemment à certains attributs non-clés, vous devez envisager de projeter ces attributs sur un index secondaire local. Les coûts de stockage supplémentaires de l'index secondaire local compenseront le coût d'exécution d'analyses de table fréquentes. • Si vous avez besoin d'accéder à la plupart des attributs non-clés sur une base fréquente, vous pouvez projeter ces attributs, voire la totalité de la table de base, sur un index secondaire local. Cela vous offrira une flexibilité maximale et la consommation de débit alloué la plus basse qui soit, car aucune récupération ne sera requise ; cependant, votre coût de stockage augmenterait, ou même doublerait si vous projetiez tous les attributs. • Si votre application doit interroger peu fréquemment une table, mais doit exécuter un grand nombre d'écritures ou de mises à jour des données de la table, pensez à projeter KEYS_ONLY. L'index secondaire local sera d'une taille minimale, mais continuera d'être disponible chaque fois que nécessaire pour une activité de requête. Création d'un index secondaire local Pour créer un ou plusieurs index secondaires locaux sur une table, utilisez le paramètre LocalSecondaryIndexes de l'opération CreateTable. Les index secondaires locaux d'une table sont créés lors de la création de la table. Lorsque vous supprimez une table, tous les index secondaires locaux de cette table sont également supprimés. Vous devez spécifier un attribut non-clé faisant office de clé de tri de l'index secondaire local. L'attribut que vous choisissez doit être un scalaire de type String (chaîne), Number (nombre) ou Binary (binaire) ; les autres types scalaires, les types document et les types set (ensemble) ne sont pas autorisés. Pour obtenir la liste complète des types de données, consultez Type de données (p. 12). Important Pour les tables avec index secondaires locaux, il existe une limite de taille 10 Go par valeur de clé de partition. Une table avec des index secondaires locaux peut stocker n'importe quel nombre d'éléments, aussi longtemps que la taille totale d'une valeur de clé de partition ne dépasse pas 10 Go. Pour de plus amples informations, veuillez consulter Taille limite de la collection d'éléments (p. 397). Vous pouvez projeter les attributs de n'importe quel type de données sur un index secondaire local. Sont inclus les scalaires, les documents et les ensembles. Pour obtenir la liste complète des types de données, consultez Type de données (p. 12). Interrogation d'un index secondaire local Dans une table DynamoDB, la combinaison des valeurs de clé de partition et de clé de tri de chaque élément doit être unique. Cependant, dans un index secondaire local, la valeur de clé de tri n'a pas besoin d'être unique pour une valeur de clé de partition donnée. S'il y a plusieurs éléments de l'index secondaire local qui ont la même valeur de clé de tri, une opération Query retourne tous les éléments ayant la même valeur de clé de partition. Dans la réponse, les éléments correspondants ne sont pas retournés dans un ordre particulier. API Version 2012-08-10 391 Amazon DynamoDB Manuel du développeur Index secondaires locaux Vous pouvez interroger un index secondaire local à l'aide de lectures cohérentes à terme ou de lectures à cohérence forte. Pour spécifier le type de cohérence que vous voulez, utilisez le paramètre ConsistentRead de l'opération Query. Une lecture à cohérence forte à partir d'un index secondaire local retourne toujours les dernières valeurs mises à jour. Si la requête doit récupérer des attributs supplémentaires à partir de la table de base, ces attributs sont cohérents par rapport à l'index. Example Considérez les données suivantes retournées à partir d'une opération Query qui demande les données des thèmes de discussion d'un forum particulier : { "TableName": "Thread", "IndexName": "LastPostIndex", "ConsistentRead": false, "ProjectionExpression": "Subject, LastPostDateTime, Replies, Tags", "KeyConditionExpression": "ForumName = :v_forum and LastPostDateTime between :v_start and :v_end", "ExpressionAttributeValues": { ":v_start": {"S": "2015-08-31T00:00:00.000Z"}, ":v_end": {"S": "2015-11-31T00:00:00.000Z"}, ":v_forum": {"S": "EC2"} } } Dans cette requête : • DynamoDB accède à LastPostIndex, à l'aide de la clé de partition ForumName pour rechercher les éléments de l'index pour « EC2 ». Tous les éléments d'index avec cette clé sont stockés les uns à côté des autres pour une récupération rapide. • Au sein de ce forum, DynamoDB utilise l'index pour rechercher les clés qui correspondent à la condition LastPostDateTime spécifiée. • Comme l'attribut Replies est projeté sur l'index, DynamoDB peut extraire cet attribut sans consommer de débit alloué supplémentaire. • Comme l'attribut Tags n'est pas projeté sur l'index, DynamoDB doit accéder à la table Thread et récupérer cet attribut. • Les résultats sont retournés, triés par LastPostDateTime. Les entrées d'index sont triées par valeur de clé de partition, puis par valeur de clé de tri, et Query les retourne dans l'ordre où ils sont stockés. (Vous pouvez utiliser le paramètre ScanIndexForward pour retourner les résultats dans l'ordre décroissant.) Comme l'attribut Tags n'est pas projeté sur l'index secondaire local, DynamoDB doit consommer les unités de capacité en lecture supplémentaires pour extraire cet attribut de la table de base. Si vous devez exécuter souvent cette requête, vous devez projeter Tags sur LastPostIndex pour éviter une extraction depuis la table de base ; cependant, si vous ne devez accéder à Tags qu'occasionnellement, le coût de stockage supplémentaire de la projection de Tags sur l'index peut ne pas en valoir la peine. Analyse d'un index secondaire local Vous pouvez utiliser Scan pour récupérer toutes les données d'un index secondaire local. Vous devez fournir le nom de la table de base et le nom de l'index dans la demande. Avec une opération Scan, DynamoDB lit toutes les données de l'index et les renvoie à l'application. Vous pouvez également demander que seules quelques données soient retournées, et que les données restantes soient API Version 2012-08-10 392 Amazon DynamoDB Manuel du développeur Index secondaires locaux ignorées. Pour ce faire, utilisez le paramètre FilterExpression de l'API Scan. Pour de plus amples informations, veuillez consulter Filtrage des résultats d'une opération Query ou Scan (p. 292). Ecritures de l'élément et index secondaires locaux DynamoDB conserve automatiquement tous les index secondaires locaux synchronisés avec leurs tables de base respectives. Les applications n'écrivent jamais directement sur un index. Cependant, il est important que vous compreniez les implications de la façon dont DynamoDB gère ces index. Lorsque vous créez un index secondaire local, vous spécifiez un attribut qui fait office de clé de tri pour l'index. Vous spécifiez également un type de données pour cet attribut. Cela signifie que chaque fois que vous écrivez un élément sur la table de base, si l'élément définit un attribut de clé d'index, son type doit correspondre au type de données du schéma de clé d'index. Dans le cas de LastPostIndex, la clé de tri LastPostDateTime de l'index est définie comme type de données String (chaîne). Si vous essayez d'ajouter un élément à la table Thread et spécifiez un autre type de données pour LastPostDateTime (Number, par exemple), DynamoDB renvoie une ValidationException en raison de l'incompatibilité des types de données. Si vous écrivez un élément sur une table, vous n'avez pas à spécifier les attributs des clés de tri des index secondaires locaux. En utilisant LastPostIndex à titre d'exemple, vous n'avez pas besoin de spécifier une valeur pour l'attribut LastPostDateTime pour pouvoir écrire un nouvel élément sur la table Thread. Dans ce cas, DynamoDB n'écrit aucune donnée sur l'index pour cet élément particulier. Il n'existe aucune exigence d'une relation un-à-un entre les éléments d'une table de base et les éléments d'un index secondaire local ; en fait, ce comportement peut être avantageux pour de nombreuses applications. Pour de plus amples informations, veuillez consulter Tirer profit des index partiellement alloués (p. 592). Une table avec de nombreux index secondaires locaux s'expose à des coûts plus élevés pour l'activité d'écriture qu'une table ayant moins d'index. Pour de plus amples informations, veuillez consulter Considérations sur le débit provisionné pour les index secondaires locaux (p. 393). Important Pour les tables avec index secondaires locaux, il existe une limite de taille 10 Go par valeur de clé de partition. Une table avec des index secondaires locaux peut stocker n'importe quel nombre d'éléments, aussi longtemps que la taille totale d'une valeur de clé de partition ne dépasse pas 10 Go. Pour de plus amples informations, veuillez consulter Taille limite de la collection d'éléments (p. 397). Considérations sur le débit provisionné pour les index secondaires locaux Lorsque vous créez une table dans DynamoDB, vous allouez les unités de capacité en lecture et en écriture pour la charge de travail attendue de la table. Cette charge de travail inclut l'activité en lecture et en écriture des index secondaires locaux de la table. Pour afficher les tarifs actuels de la capacité de débit alloué, consultez https://aws.amazon.com/ dynamodb/pricing. Unités de capacité en lecture Lors de l'interrogation d'un index secondaire local, le nombre d'unités de capacité en lecture consommées dépend de la façon dont les données sont accédées. Comme pour les requêtes de table, une requête d'index peut utiliser les lectures cohérentes à terme ou les lectures à cohérence forte selon la valeur de ConsistentRead. Une lecture à cohérence forte consomme une unité de capacité en lecture ; une lecture cohérente à terme en consomme uniquement API Version 2012-08-10 393 Amazon DynamoDB Manuel du développeur Index secondaires locaux la moitié. Par conséquent, en choisissant des lectures cohérentes à terme, vous pouvez réduire vos coûts d'unité de capacité en lecture. Pour les requêtes d'index qui ne demandent que les clés d'index et les attributs projetés, DynamoDB calcule l'activité en lecture allouée de la même manière que pour les requêtes sur les tables. La seule différence est que le calcul est basé sur les tailles des entrées d'index, plutôt que sur la taille de l'élément de la table de base. Le nombre d'unités de capacité en lecture est la somme des tailles de tous les attributs projetés de tous les éléments renvoyés ; le résultat est alors arrondi à la limite 4 KB suivante. Pour plus d'informations sur la façon dont DynamoDB calcule l'utilisation du débit alloué, consultez Spécification d'exigences de lecture et d'écriture pour des tables (p. 180). Pour les requêtes d'index lisant les attributs qui ne sont pas projetés sur l'index secondaire local, DynamoDB devra extraire ces attributs de la table de base, en plus de lire les attributs projetés à partir de l'index. Ces extractions se produisent lorsque vous incluez des attributs non projetés dans les paramètres Select ou ProjectionExpression de l'opération Query. La récupération entraîne une latence supplémentaire dans les réponses des requêtes et entraîne aussi une augmentation de coût du débit alloué : outre les lectures à partir de l'index secondaire local décrites ci-dessus, vous devrez régler les unités de capacité en lecture pour chaque élément de la table de base récupéré. Ces frais concernent la lecture de chaque élément complet de la table, et pas seulement les attributs requis. La taille maximale des résultats retournés par une opération Query est 1 MB ; cela inclut les tailles de tous les noms et valeurs d'attribut à travers l'ensemble des éléments retournés. Cependant, si une opération Query sur un index secondaire local conduit DynamoDB à extraire les attributs d'élément de la table de base, la taille maximale des données dans les résultats peut être inférieure. Dans ce cas, la taille du résultat est la somme des tailles suivantes : • La taille des éléments correspondants de l'index, arrondie à la 4 KB suivante. • La taille de chaque élément correspondant de la table de base, avec chaque élément arrondi individuellement à la 4 KB suivante. Avec cette formule, la taille maximale des résultats renvoyés par une opération Query est toujours 1 MB. Par exemple, imaginons une table où la taille de chaque élément est 300 octets. Il existe un index secondaire local sur cette table, mais uniquement 200 octets de chaque élément sont projetés sur l'index. Supposons maintenant que vous ayez exécuté une opération Query sur cet index, que la requête nécessite des extractions de table pour chaque élément et que la requête renvoie 4 éléments. DynamoDB calcule la somme totale de la façon suivante : • La taille des éléments correspondants de l'index : 200 octets × 4 éléments = 800 octets ; le résultat est ensuite arrondi à 4 KB. • La taille de chaque élément correspondant de la table de base : (300 octets, arrondis à 4 KB) × 4 éléments = 16 Ko. Par conséquent, la taille totale des données dans le résultat est 20 Ko. Unités de capacité en écriture Lorsqu'un élément d'une table est ajouté, mis à jour ou supprimé, la mise à jour des index secondaires locaux consomme les unités de capacité en écriture allouées pour la table. Le coût total du débit alloué pour une écriture correspond à la somme des unités de capacité en écriture utilisées par l'écriture sur la table et de celles utilisées par la mise à jour des index secondaires locaux. Le coût d'écriture d'un élément sur un index secondaire local dépend de plusieurs facteurs : • Si vous écrivez un nouvel élément sur la table qui définit un attribut indexé, ou que vous mettez à jour un élément existant pour définir un attribut indexé précédemment non défini, une opération d'écriture est nécessaire pour insérer l'élément dans l'index. API Version 2012-08-10 394 Amazon DynamoDB Manuel du développeur Index secondaires locaux • Si une mise à jour de la table change la valeur d'un attribut de clé indexée (de A en B), deux écritures sont requises, une pour supprimer l'élément précédent de l'index et une autre pour insérer le nouveau élément dans l'index. • Si un élément était présent dans l'index, mais qu'une écriture sur la table a entraîné la suppression de l'attribut indexé, une écriture est nécessaire pour supprimer de l'index la projection de l'ancien élément. • Si un élément n'est pas présent dans l'index avant ou après la mise à jour de l'élément, il n'y a aucun coût d'écriture supplémentaire pour l'index. Tous ces facteurs présument que la taille de chaque élément de l'index soit inférieure ou égale à la taille d'élément 1 KB pour le calcul des unités de capacité en écriture. Les plus grandes entrées d'index nécessitent des unités de capacité en écriture supplémentaires. Vous pouvez réduire vos coûts d'écriture en considérant les attributs que vos requêtes ont besoin de retourner et en projetant uniquement ces attributs dans l'index. Considérations sur le stockage des index secondaires locaux Lorsqu'une application écrit un élément dans une table, DynamoDB copie automatiquement le sousensemble approprié d'attributs sur les index secondaires locaux où ces attributs doivent apparaître. Votre compte AWS est facturé pour le stockage de l'élément dans la table de base, ainsi que pour le stockage des attributs dans les index secondaires locaux de cette table. La quantité d'espace utilisée par un élément de l'index est la somme des éléments suivants : • La taille en octets de la clé primaire de la table de base (clé de partition et clé de tri) • La taille en octets de l'attribut de clé d'index • La taille en octets des attributs projetés (le cas échéant) • 100 bytes de traitement par élément d'index Afin d'estimer les besoins de stockage d'un index secondaire local, vous pouvez estimer la taille moyenne d'un élément de l'index, puis la multiplier par le nombre d'éléments de la table de base. Si une table contient un élément dans lequel un attribut particulier n'est pas défini, mais que cet attribut est défini comme clé de tri d'index, DynamoDB n'écrit aucune donnée de cet élément sur l'index. Pour plus d'informations sur ce comportement, consultez Tirer profit des index partiellement alloués (p. 592). Collections d'éléments Note La section suivante s'applique uniquement aux tables ayant des index secondaires locaux. Dans DynamoDB, une collection d'éléments est un groupe d'éléments ayant la même valeur de clé de partition dans une table et dans l'ensemble de ses index secondaires locaux. Dans les exemples utilisés dans cette section, la clé de partition de la table Thread est ForumName et la clé de partition de LastPostIndex est également ForumName. Tous les éléments de table et d'index avec le même ForumName font partie de la même collection d'éléments. Par exemple, dans la table Thread et dans l'index secondaire local LastPostIndex, il existe une collection d'éléments pour le forum EC2 et une autre collection d'éléments pour le forum RDS. Le schéma suivant illustre la collection d'éléments du forum S3 : API Version 2012-08-10 395 Amazon DynamoDB Manuel du développeur Index secondaires locaux Dans ce schéma, la collection d'éléments se compose de tous les éléments de Thread et LastPostIndex où la valeur de clé de partition de ForumName est « S3 ». S'il y avait d'autres index secondaires locaux sur la table, tous les éléments de ces index dont ForumName est égal à « S3 » feraient également partie de la collection d'éléments. Vous pouvez utiliser l'une des opérations suivantes dans DynamoDB pour renvoyer des informations sur les collections : • BatchWriteItem • DeleteItem • PutItem • UpdateItem API Version 2012-08-10 396 Amazon DynamoDB Manuel du développeur Index secondaires locaux Chacune de ces opérations prend en charge le paramètre ReturnItemCollectionMetrics. Lorsque vous définissez ce paramètre sur SIZE, vous pouvez afficher les informations sur la taille de chaque collection d'éléments dans l'index. Example Voici un extrait de la sortie d'une opération UpdateItem sur la table Thread, avec la valeur de ReturnItemCollectionMetrics définie sur SIZE. Comme l'élément mis à jour avait la valeur « EC2 » pour ForumName, la sortie inclut des informations sur cette collection d'éléments. { ItemCollectionMetrics: { ItemCollectionKey: { ForumName: "EC2" }, SizeEstimateRangeGB: [0.0, 1.0] } } L'objet SizeEstimateRangeGB montre que la taille de cette collection d'éléments est comprise entre 0 et 1 Go. DynamoDB mettant régulièrement à jour l'estimation de la taille, les chiffres peuvent être différents lors de la prochaine modification de l'élément. Taille limite de la collection d'éléments La taille maximale d'une collection d'éléments est 10 Go. Cette limite ne s'applique pas aux tables sans index secondaires locaux ; seules les tables ayant un ou plusieurs index secondaires locaux sont concernées. Si une collection d'éléments dépasse la limite 10 Go, DynamoDB renvoie une ItemCollectionSizeLimitExceededException et vous ne pouvez pas ajouter plus d'éléments à la collection d'éléments ou accroître la taille des éléments qui se trouvent dans la collection d'éléments. (Les opérations de lecture et d'écriture permettant de diminuer la taille de la collection d'éléments restent autorisées.) Vous pouvez toujours ajouter des éléments à d'autres collections d'éléments. Pour réduire la taille d'une collection d'éléments, vous pouvez effectuer l'une des actions suivantes : • Supprimer tous les éléments inutiles avec la valeur de clé de partition en question. Lorsque vous supprimez ces éléments de la table de base, DynamoDB supprime aussi les entrées d'index ayant la même valeur de clé de partition. • Mettre à jour les éléments en supprimant des attributs ou en réduisant leur taille. Si ces attributs sont projetés sur des index secondaires locaux, DynamoDB réduit également la taille des entrées d'index correspondantes. • Créer une table avec les mêmes clé de partition et clé de tri, puis déplacer les éléments de l'ancienne table vers la nouvelle table. Ce peut être une bonne approche si une table possède des données historiques qui sont rarement consultées. Vous pouvez également envisager l'archivage de ces données historiques sur Amazon Simple Storage Service (Amazon S3). Lorsque la taille totale de la collection d'éléments devient inférieure à 10 Go, vous pouvez une fois encore ajouter des éléments avec la même valeur de clé de partition. Nous vous recommandons à titre de bonne pratique d'équiper votre application de telle sorte qu'elle surveille la taille de vos collections d'éléments. L'un des moyens de le faire consiste à définir le paramètre ReturnItemCollectionMetrics avec la valeur SIZE chaque fois que vous utilisez BatchWriteItem, DeleteItem, PutItem ou UpdateItem. Votre application doit examiner l'objet ReturnItemCollectionMetrics dans la sortie et enregistrer un message d'erreur chaque fois API Version 2012-08-10 397 Amazon DynamoDB Manuel du développeur Index secondaires locaux qu'une collection d'éléments dépasse une limite définie par l'utilisateur (8 Go, par exemple). Le fait de définir une limite inférieure à 10 Go fournit un système de première alerte précoce et vous savez ainsi qu'une collection d'éléments approche la limite en temps pour qu'il soit fait quelque chose à son sujet. Partitions et collections d'éléments Les données de table et d'index de chaque collection d'éléments sont stockées dans une seule partition. Si l'on se réfère à l'exemple de table Thread, tous les éléments de table de base et d'index avec le même attribut ForumName seront stockés dans la même partition. La collection d'éléments « S3 » sera stockée sur une seule partition, « EC2 » sur une autre partition et « RDS » sur une troisième partition. Vous devez concevoir vos applications de telle sorte que les données de la table soient uniformément distribuées entre les valeurs de clé de partition distinctes. Pour les tables avec des index secondaires locaux, vos applications ne doivent pas créer de « zones réactives » d'activité de lecture et d'écriture au sein d'une même collection d'éléments d'une même partition. Utilisation des Index local secondaire : Java Rubriques • Créer une table avec un index secondaire local (p. 398) • Décrire une Table avec un Index local secondaire (p. 400) • Interrogez un index secondaire local (p. 401) • Exemple : Index local secondaire à l'aide de l'API Document Java (p. 402) Vous pouvez utiliser l'API Document AWS SDK for Java pour créer une table avec un ou plusieurs local secondary index, décrire les index sur la table et exécuter des requêtes en utilisant les index. Voici les étapes courantes des opérations de table à l'aide de l'API Document de AWS SDK for Java. 1. Créez une instance de la classe DynamoDB. 2. Fournissez les paramètres obligatoires et facultatifs pour l'opération en créant les objets de requête correspondants. 3. Appelez la méthode appropriée fournie par le client que vous avez créée à l'étape précédente. Créer une table avec un index secondaire local Les index secondaires locaux doivent être créés en même temps que vous créez une table. Pour ce faire, utilisez la méthode createTable et fournissez vos spécifications pour un ou plusieurs local secondary index. L'extrait de code Java suivant crée une table qui contient des informations sur des morceaux d'une collection musicale. La clé de partition est Artist et la clé de tri est SongTitle. Un index secondaire, AlbumTitleIndex, facilite les requêtes par titre d'album. Voici les étapes pour créer une table avec un local secondary index, à l'aide de l'API document DynamoDB. 1. Créez une instance de la classe DynamoDB. 2. Créez une instance de la classe CreateTableRequest pour fournir l'information de requête. Vous devez fournir le nom de la table, sa clé primaire et les valeurs du débit alloué. Pour le local secondary index, vous devez fournir le nom d'index, le nom et le type de données pour la clé de tri d'index, le schéma de clés pour l'index et la projection d'attribut. 3. Appelez la méthode createTable en fournissant l'objet de requête comme paramètre. API Version 2012-08-10 398 Amazon DynamoDB Manuel du développeur Index secondaires locaux L'extrait de code Java suivant illustre les étapes précédentes. L'extrait crée une table (Music) avec un index secondaire sur l'attribut AlbumTitle. La clé de partition de table et la clé de tri, ainsi que la clé de tri d'index, sont les seuls attributs projetés dans l'index. DynamoDB dynamoDB = new DynamoDB(new AmazonDynamoDBClient( new ProfileCredentialsProvider())); String tableName = "Music"; CreateTableRequest createTableRequest = new CreateTableRequest().withTableName(tableName); //ProvisionedThroughput createTableRequest.setProvisionedThroughput(new ProvisionedThroughput().withReadCapacityUnits((long)5).withWriteCapacityUnits((long)5)); //AttributeDefinitions ArrayList<AttributeDefinition> attributeDefinitions= new ArrayList<AttributeDefinition>(); attributeDefinitions.add(new AttributeDefinition().withAttributeName("Artist").withAttributeType("S")); attributeDefinitions.add(new AttributeDefinition().withAttributeName("SongTitle").withAttributeType("S")); attributeDefinitions.add(new AttributeDefinition().withAttributeName("AlbumTitle").withAttributeType("S")); createTableRequest.setAttributeDefinitions(attributeDefinitions); //KeySchema ArrayList<KeySchemaElement> tableKeySchema = new ArrayList<KeySchemaElement>(); tableKeySchema.add(new KeySchemaElement().withAttributeName("Artist").withKeyType(KeyType.HASH)); //Partition key tableKeySchema.add(new KeySchemaElement().withAttributeName("SongTitle").withKeyType(KeyType.RANGE)); //Sort key createTableRequest.setKeySchema(tableKeySchema); ArrayList<KeySchemaElement> indexKeySchema = new ArrayList<KeySchemaElement>(); indexKeySchema.add(new KeySchemaElement().withAttributeName("Artist").withKeyType(KeyType.HASH)); //Partition key indexKeySchema.add(new KeySchemaElement().withAttributeName("AlbumTitle").withKeyType(KeyType.RANGE)); //Sort key Projection projection = new Projection().withProjectionType(ProjectionType.INCLUDE); ArrayList<String> nonKeyAttributes = new ArrayList<String>(); nonKeyAttributes.add("Genre"); nonKeyAttributes.add("Year"); projection.setNonKeyAttributes(nonKeyAttributes); LocalSecondaryIndex localSecondaryIndex = new LocalSecondaryIndex() API Version 2012-08-10 399 Amazon DynamoDB Manuel du développeur Index secondaires locaux .withIndexName("AlbumTitleIndex").withKeySchema(indexKeySchema).withProjection(projection); ArrayList<LocalSecondaryIndex> localSecondaryIndexes = new ArrayList<LocalSecondaryIndex>(); localSecondaryIndexes.add(localSecondaryIndex); createTableRequest.setLocalSecondaryIndexes(localSecondaryIndexes); Table table = dynamoDB.createTable(createTableRequest); System.out.println(table.getDescription()); Vous devez attendre que DynamoDB ait créé la table et défini l'état de la table sur ACTIVE. Après cela, vous pouvez commencer à mettre les éléments de données dans la table. Décrire une Table avec un Index local secondaire Pour obtenir des informations sur des local secondary index sur une table, utilisez la méthode describeTable. Pour chaque index, vous pouvez accéder à son nom, son schéma de clé et ses attributs projetés. Voici les étapes pour accéder aux informations local secondary index d'une table à l'aide de l'API Document AWS SDK for Java 1. Créez une instance de la classe DynamoDB. 2. Créez une instance de la classe Table. Vous devez fournir le nom de la table. 3. Appelez la méthode describeTable sur l'objet Table. L'extrait de code Java suivant illustre les étapes précédentes. DynamoDB dynamoDB = new DynamoDB(new AmazonDynamoDBClient( new ProfileCredentialsProvider())); String tableName = "Music"; Table table = dynamoDB.getTable(tableName); TableDescription tableDescription = table.describe(); List<LocalSecondaryIndexDescription> localSecondaryIndexes = tableDescription.getLocalSecondaryIndexes(); // This code snippet will work for multiple indexes, even though // there is only one index in this example. Iterator<LocalSecondaryIndexDescription> lsiIter = localSecondaryIndexes.iterator(); while (lsiIter.hasNext()) { LocalSecondaryIndexDescription lsiDescription = lsiIter.next(); System.out.println("Info for index " + lsiDescription.getIndexName() + ":"); Iterator<KeySchemaElement> kseIter = lsiDescription.getKeySchema().iterator(); while (kseIter.hasNext()) { KeySchemaElement kse = kseIter.next(); System.out.printf("\t%s: %s\n", kse.getAttributeName(), kse.getKeyType()); API Version 2012-08-10 400 Amazon DynamoDB Manuel du développeur Index secondaires locaux } Projection projection = lsiDescription.getProjection(); System.out.println("\tThe projection type is: " + projection.getProjectionType()); if (projection.getProjectionType().toString().equals("INCLUDE")) { System.out.println("\t\tThe non-key projected attributes are: " + projection.getNonKeyAttributes()); } } Interrogez un index secondaire local Vous pouvez utiliser l'opération Query sur un index secondaire local, de la même façon que vous exécutez une opération Query sur une table. Vous devez spécifier le nom d'index, les critères de requête de la clé de tri d'index et les attributs que vous souhaitez retourner. Dans cet exemple, l'index est AlbumTitleIndex et la clé de tri d'index est AlbumTitle. Les seuls attributs retournés sont ceux qui ont été projetés dans l'index. Vous pouvez modifier cette requête pour sélectionner aussi des attributs non-clés, mais cela nécessite une activité d'extraction de table qui est relativement coûteuse. Pour plus d'informations sur les extractions de table, consultez Projections d'attribut (p. 389). Voici les étapes pour interroger un local secondary index à l'aide de l'API Document de AWS SDK for Java. 1. Créez une instance de la classe DynamoDB. 2. Créez une instance de la classe Table. Vous devez fournir le nom de la table. 3. Créez une instance de la classe Index. Vous devez fournir le nom d'index. 4. Appelez la méthode query de la classe Index. L'extrait de code Java suivant illustre les étapes précédentes. DynamoDB dynamoDB = new DynamoDB(new AmazonDynamoDBClient( new ProfileCredentialsProvider())); String tableName = "Music"; Table table = dynamoDB.getTable(tableName); Index index = table.getIndex("AlbumTitleIndex"); QuerySpec spec = new QuerySpec() .withKeyConditionExpression("Artist = :v_artist and AlbumTitle = :v_title") .withValueMap(new ValueMap() .withString(":v_artist", "Acme Band") .withString(":v_title", "Songs About Life")); ItemCollection<QueryOutcome> items = index.query(spec); Iterator<Item> itemsIter = items.iterator(); while (itemsIter.hasNext()) { Item item = itemsIter.next(); System.out.println(item.toJSONPretty()); } API Version 2012-08-10 401 Amazon DynamoDB Manuel du développeur Index secondaires locaux Exemple : Index local secondaire à l'aide de l'API Document Java L'exemple de code Java suivant montre comment utiliser les local secondary index. L'exemple crée une table nommée CustomerOrders avec la clé de partition CustomerId et la clé de tri OrderId. Il existe deux index secondaires locaux sur la table : • OrderCreationDateIndex : la clé de tri est OrderCreationDate et les attributs suivants sont projetés dans l'index : • ProductCategory • ProductName • OrderStatus • ShipmentTrackingId • IsOpenIndex : la clé de tri est IsOpen et tous les attributs de la table sont projetés dans l'index. Après la création de la table CustomerOrders, le programme charge la table avec les données représentant les commandes des clients, puis interroge les données à l'aide des index secondaires locaux. Enfin, le programme supprime la table CustomerOrders. Pour obtenir les instructions pas à pas afin de tester l'exemple suivant, consultez Exemples de Code Java (p. 173). // Copyright 2012-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. // Licensed under the Apache License, Version 2.0. package com.amazonaws.codesamples.document; import java.util.ArrayList; import java.util.Iterator; import import import import import import import import import import import import import import import import import import import import import com.amazonaws.auth.profile.ProfileCredentialsProvider; com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient; com.amazonaws.services.dynamodbv2.document.DynamoDB; com.amazonaws.services.dynamodbv2.document.Index; com.amazonaws.services.dynamodbv2.document.Item; com.amazonaws.services.dynamodbv2.document.ItemCollection; com.amazonaws.services.dynamodbv2.document.PutItemOutcome; com.amazonaws.services.dynamodbv2.document.QueryOutcome; com.amazonaws.services.dynamodbv2.document.Table; com.amazonaws.services.dynamodbv2.document.spec.QuerySpec; com.amazonaws.services.dynamodbv2.document.utils.ValueMap; com.amazonaws.services.dynamodbv2.model.AttributeDefinition; com.amazonaws.services.dynamodbv2.model.CreateTableRequest; com.amazonaws.services.dynamodbv2.model.KeySchemaElement; com.amazonaws.services.dynamodbv2.model.KeyType; com.amazonaws.services.dynamodbv2.model.LocalSecondaryIndex; com.amazonaws.services.dynamodbv2.model.Projection; com.amazonaws.services.dynamodbv2.model.ProjectionType; com.amazonaws.services.dynamodbv2.model.ProvisionedThroughput; com.amazonaws.services.dynamodbv2.model.ReturnConsumedCapacity; com.amazonaws.services.dynamodbv2.model.Select; public class DocumentAPILocalSecondaryIndexExample { static DynamoDB dynamoDB = new DynamoDB(new AmazonDynamoDBClient( new ProfileCredentialsProvider())); public static String tableName = "CustomerOrders"; API Version 2012-08-10 402 Amazon DynamoDB Manuel du développeur Index secondaires locaux public static void main(String[] args) throws Exception { createTable(); loadData(); query(null); query("IsOpenIndex"); query("OrderCreationDateIndex"); deleteTable(tableName); } public static void createTable() { CreateTableRequest createTableRequest = new CreateTableRequest() .withTableName(tableName) .withProvisionedThroughput(new ProvisionedThroughput() .withReadCapacityUnits((long) 1) .withWriteCapacityUnits((long) 1)); // Attribute definitions for table partition and sort keys ArrayList<AttributeDefinition> attributeDefinitions = new ArrayList<AttributeDefinition>(); attributeDefinitions.add(new AttributeDefinition() .withAttributeName("CustomerId") .withAttributeType("S")); attributeDefinitions.add(new AttributeDefinition() .withAttributeName("OrderId") .withAttributeType("N")); // Attribute definition for index primary key attributes attributeDefinitions.add(new AttributeDefinition() .withAttributeName("OrderCreationDate") .withAttributeType("N")); attributeDefinitions.add(new AttributeDefinition() .withAttributeName("IsOpen") .withAttributeType("N")); createTableRequest.setAttributeDefinitions(attributeDefinitions); // Key schema for table ArrayList<KeySchemaElement> tableKeySchema = new ArrayList<KeySchemaElement>(); tableKeySchema.add(new KeySchemaElement() .withAttributeName("CustomerId") .withKeyType(KeyType.HASH)); //Partition key tableKeySchema.add(new KeySchemaElement() .withAttributeName("OrderId") .withKeyType(KeyType.RANGE)); //Sort key createTableRequest.setKeySchema(tableKeySchema); ArrayList<LocalSecondaryIndex> localSecondaryIndexes = new ArrayList<LocalSecondaryIndex>(); // OrderCreationDateIndex API Version 2012-08-10 403 Amazon DynamoDB Manuel du développeur Index secondaires locaux LocalSecondaryIndex orderCreationDateIndex = new LocalSecondaryIndex() .withIndexName("OrderCreationDateIndex"); // Key schema for OrderCreationDateIndex ArrayList<KeySchemaElement> indexKeySchema = new ArrayList<KeySchemaElement>(); indexKeySchema.add(new KeySchemaElement() .withAttributeName("CustomerId") .withKeyType(KeyType.HASH)); //Partition key indexKeySchema.add(new KeySchemaElement() .withAttributeName("OrderCreationDate") .withKeyType(KeyType.RANGE)); //Sort key orderCreationDateIndex.setKeySchema(indexKeySchema); // Projection (with list of projected attributes) for // OrderCreationDateIndex Projection projection = new Projection() .withProjectionType(ProjectionType.INCLUDE); ArrayList<String> nonKeyAttributes = new ArrayList<String>(); nonKeyAttributes.add("ProductCategory"); nonKeyAttributes.add("ProductName"); projection.setNonKeyAttributes(nonKeyAttributes); orderCreationDateIndex.setProjection(projection); localSecondaryIndexes.add(orderCreationDateIndex); // IsOpenIndex LocalSecondaryIndex isOpenIndex = new LocalSecondaryIndex() .withIndexName("IsOpenIndex"); // Key schema for IsOpenIndex indexKeySchema = new ArrayList<KeySchemaElement>(); indexKeySchema.add(new KeySchemaElement() .withAttributeName("CustomerId") .withKeyType(KeyType.HASH)); //Partition key indexKeySchema.add(new KeySchemaElement() .withAttributeName("IsOpen") .withKeyType(KeyType.RANGE)); //Sort key // Projection (all attributes) for IsOpenIndex projection = new Projection() .withProjectionType(ProjectionType.ALL); isOpenIndex.setKeySchema(indexKeySchema); isOpenIndex.setProjection(projection); localSecondaryIndexes.add(isOpenIndex); // Add index definitions to CreateTable request createTableRequest.setLocalSecondaryIndexes(localSecondaryIndexes); System.out.println("Creating table " + tableName + "..."); System.out.println(dynamoDB.createTable(createTableRequest)); // Wait for table to become active API Version 2012-08-10 404 Amazon DynamoDB Manuel du développeur Index secondaires locaux System.out.println("Waiting for " + tableName + " to become ACTIVE..."); try { Table table = dynamoDB.getTable(tableName); table.waitForActive(); } catch (InterruptedException e) { e.printStackTrace(); } } public static void query(String indexName) { Table table = dynamoDB.getTable(tableName); System.out .println("\n***********************************************************\n"); System.out.println("Querying table " + tableName + "..."); QuerySpec querySpec = new QuerySpec() .withConsistentRead(true) .withScanIndexForward(true) .withReturnConsumedCapacity(ReturnConsumedCapacity.TOTAL); if (indexName == "IsOpenIndex") { System.out.println("\nUsing index: '" + indexName + "': Bob's orders that are open."); System.out.println( "Only a user-specified list of attributes are returned\n"); Index index = table.getIndex(indexName); querySpec.withKeyConditionExpression("CustomerId = :v_custid and IsOpen = :v_isopen") .withValueMap(new ValueMap() .withString(":v_custid", "[email protected]") .withNumber(":v_isopen", 1)); querySpec.withProjectionExpression( "OrderCreationDate, ProductCategory, ProductName, OrderStatus"); ItemCollection<QueryOutcome> items = index.query(querySpec); Iterator<Item> iterator = items.iterator(); System.out.println("Query: printing results..."); while (iterator.hasNext()) { System.out.println(iterator.next().toJSONPretty()); } } else if (indexName == "OrderCreationDateIndex") { System.out.println("\nUsing index: '" + indexName + "': Bob's orders that were placed after 01/31/2015."); System.out.println("Only the projected attributes are returned \n"); Index index = table.getIndex(indexName); API Version 2012-08-10 405 Amazon DynamoDB Manuel du développeur Index secondaires locaux querySpec.withKeyConditionExpression("CustomerId = :v_custid and OrderCreationDate >= :v_orddate") .withValueMap(new ValueMap() .withString(":v_custid", "[email protected]") .withNumber(":v_orddate", 20150131)); querySpec.withSelect(Select.ALL_PROJECTED_ATTRIBUTES); ItemCollection<QueryOutcome> items = index.query(querySpec); Iterator<Item> iterator = items.iterator(); System.out.println("Query: printing results..."); while (iterator.hasNext()) { System.out.println(iterator.next().toJSONPretty()); } } else { System.out.println("\nNo index: All of Bob's orders, by OrderId: \n"); querySpec.withKeyConditionExpression("CustomerId = :v_custid") .withValueMap(new ValueMap() .withString(":v_custid", "[email protected]")); ItemCollection<QueryOutcome> items = table.query(querySpec); Iterator<Item> iterator = items.iterator(); System.out.println("Query: printing results..."); while (iterator.hasNext()) { System.out.println(iterator.next().toJSONPretty()); } } } public static void deleteTable(String tableName) { Table table = dynamoDB.getTable(tableName); System.out.println("Deleting table " + tableName + "..."); table.delete(); // Wait for table to be deleted System.out.println("Waiting for " + tableName + " to be deleted..."); try { table.waitForDelete(); } catch (InterruptedException e) { e.printStackTrace(); } } public static void loadData() { Table table = dynamoDB.getTable(tableName); System.out.println("Loading data into table " + tableName + "..."); API Version 2012-08-10 406 Amazon DynamoDB Manuel du développeur Index secondaires locaux Item item = new Item() .withPrimaryKey("CustomerId", "[email protected]") .withNumber("OrderId", 1) .withNumber("IsOpen", 1) .withNumber("OrderCreationDate", 20150101) .withString("ProductCategory", "Book") .withString("ProductName", "The Great Outdoors") .withString("OrderStatus", "PACKING ITEMS"); // no ShipmentTrackingId attribute PutItemOutcome putItemOutcome = table.putItem(item); item = new Item() .withPrimaryKey("CustomerId", "[email protected]") .withNumber("OrderId", 2) .withNumber("IsOpen", 1) .withNumber("OrderCreationDate", 20150221) .withString("ProductCategory", "Bike") .withString("ProductName", "Super Mountain") .withString("OrderStatus", "ORDER RECEIVED"); // no ShipmentTrackingId attribute putItemOutcome = table.putItem(item); item = new Item() .withPrimaryKey("CustomerId", "[email protected]") .withNumber("OrderId", 3) // no IsOpen attribute .withNumber("OrderCreationDate", 20150304) .withString("ProductCategory", "Music") .withString("ProductName", "A Quiet Interlude") .withString("OrderStatus", "IN TRANSIT") .withString("ShipmentTrackingId", "176493"); putItemOutcome = table.putItem(item); item = new Item() .withPrimaryKey("CustomerId", "[email protected]") .withNumber("OrderId", 1) // no IsOpen attribute .withNumber("OrderCreationDate", 20150111) .withString("ProductCategory", "Movie") .withString("ProductName", "Calm Before The Storm") .withString("OrderStatus", "SHIPPING DELAY") .withString("ShipmentTrackingId", "859323"); putItemOutcome = table.putItem(item); item = new Item() .withPrimaryKey("CustomerId", "[email protected]") .withNumber("OrderId", 2) // no IsOpen attribute .withNumber("OrderCreationDate", 20150124) .withString("ProductCategory", "Music") .withString("ProductName", "E-Z Listening") .withString("OrderStatus", "DELIVERED") .withString("ShipmentTrackingId", "756943"); putItemOutcome = table.putItem(item); API Version 2012-08-10 407 Amazon DynamoDB Manuel du développeur Index secondaires locaux item = new Item() .withPrimaryKey("CustomerId", "[email protected]") .withNumber("OrderId", 3) // no IsOpen attribute .withNumber("OrderCreationDate", 20150221) .withString("ProductCategory", "Music") .withString("ProductName", "Symphony 9") .withString("OrderStatus", "DELIVERED") .withString("ShipmentTrackingId", "645193"); putItemOutcome = table.putItem(item); item = new Item().withPrimaryKey("CustomerId", "[email protected]") .withNumber("OrderId", 4).withNumber("IsOpen", 1) .withNumber("OrderCreationDate", 20150222) .withString("ProductCategory", "Hardware") .withString("ProductName", "Extra Heavy Hammer") .withString("OrderStatus", "PACKING ITEMS"); // no ShipmentTrackingId attribute putItemOutcome = table.putItem(item); item = new Item().withPrimaryKey("CustomerId", "[email protected]") .withNumber("OrderId", 5) /* no IsOpen attribute */ .withNumber("OrderCreationDate", 20150309) .withString("ProductCategory", "Book") .withString("ProductName", "How To Cook") .withString("OrderStatus", "IN TRANSIT") .withString("ShipmentTrackingId", "440185"); putItemOutcome = table.putItem(item); item = new Item() .withPrimaryKey("CustomerId", "[email protected]") .withNumber("OrderId", 6) // no IsOpen attribute .withNumber("OrderCreationDate", 20150318) .withString("ProductCategory", "Luggage") .withString("ProductName", "Really Big Suitcase") .withString("OrderStatus", "DELIVERED") .withString("ShipmentTrackingId", "893927"); putItemOutcome = table.putItem(item); item = new Item().withPrimaryKey("CustomerId", "[email protected]") .withNumber("OrderId", 7) /* no IsOpen attribute */ .withNumber("OrderCreationDate", 20150324) .withString("ProductCategory", "Golf") .withString("ProductName", "PGA Pro II") .withString("OrderStatus", "OUT FOR DELIVERY") .withString("ShipmentTrackingId", "383283"); putItemOutcome = table.putItem(item); assert putItemOutcome != null; } API Version 2012-08-10 408 Amazon DynamoDB Manuel du développeur Index secondaires locaux } Utilisation de Index local secondaire : .NET Rubriques • Créer une table avec un index secondaire local (p. 409) • Décrire une Table avec un Index local secondaire (p. 411) • Interroger un index secondaire local (p. 412) • Exemple : Index local secondaire utilisant le SDK AWS pour l'API de bas niveau .NET (p. 413) Vous pouvez utiliser l'API de bas niveau du SDK AWS pour .NET afin de créer une table avec un ou plusieurs local secondary index, décrire les index de la table et exécuter les requêtes à l'aide des index. Ces opérations sont mappées avec les actions d'API DynamoDB de bas niveau correspondantes. Pour de plus amples informations, veuillez consulter Exemples de code .NET (p. 175). Voici les étapes courantes pour les opérations de table à l'aide de l'API de bas niveau .NET. 1. Créez une instance de la classe AmazonDynamoDBClient. 2. Fournissez les paramètres obligatoires et facultatifs pour l'opération en créant les objets de requête correspondants. Par exemple, créez un objet CreateTableRequest pour créer une table et un objet QueryRequest pour interroger une table ou un index. 3. Exécutez la méthode appropriée fournie par le client que vous avez créée à l'étape précédente. Créer une table avec un index secondaire local Les index secondaires locaux doivent être créés en même temps que vous créez une table. Pour ce faire, utilisez CreateTable et fournissez à vos spécifications un ou plusieurs local secondary index. L'extrait de code C# suivant crée une table qui contient les informations sur les morceaux d'une collection musicale. La clé de partition est Artist et la clé de tri est SongTitle. Un index secondaire, AlbumTitleIndex, facilite les requêtes par titre d'album. Voici les étapes pour créer une table avec un local secondary index, à l'aide de l'API de bas niveau .NET. 1. Créez une instance de la classe AmazonDynamoDBClient. 2. Créez une instance de la classe CreateTableRequest pour fournir l'information de requête. Vous devez fournir le nom de la table, sa clé primaire et les valeurs du débit alloué. Pour le local secondary index, vous devez fournir le nom d'index, le nom et le type de données de la clé de tri d'index, le schéma de clés pour l'index et la projection d'attribut. 3. Exécutez la méthode CreateTable en fournissant l'objet de requête comme paramètre. L'extrait de code C# suivant illustre les étapes précédentes. L'extrait crée une table (Music) avec un index secondaire sur l'attribut AlbumTitle. La clé de partition de table et la clé de tri, ainsi que la clé de tri d'index, sont les seuls attributs projetés dans l'index. AmazonDynamoDBClient client = new AmazonDynamoDBClient(); string tableName = "Music"; CreateTableRequest createTableRequest = new CreateTableRequest() { API Version 2012-08-10 409 Amazon DynamoDB Manuel du développeur Index secondaires locaux TableName = tableName }; //ProvisionedThroughput createTableRequest.ProvisionedThroughput = new ProvisionedThroughput() { ReadCapacityUnits = (long)5, WriteCapacityUnits = (long)5 }; //AttributeDefinitions List<AttributeDefinition> attributeDefinitions = new List<AttributeDefinition>(); attributeDefinitions.Add(new AttributeDefinition() { AttributeName = "Artist", AttributeType = "S" }); attributeDefinitions.Add(new AttributeDefinition() { AttributeName = "SongTitle", AttributeType = "S" }); attributeDefinitions.Add(new AttributeDefinition() { AttributeName = "AlbumTitle", AttributeType = "S" }); createTableRequest.AttributeDefinitions = attributeDefinitions; //KeySchema List<KeySchemaElement> tableKeySchema = new List<KeySchemaElement>(); tableKeySchema.Add(new KeySchemaElement() { AttributeName = "Artist", KeyType = "HASH" }); //Partition key tableKeySchema.Add(new KeySchemaElement() { AttributeName = "SongTitle", KeyType = "RANGE" }); //Sort key createTableRequest.KeySchema = tableKeySchema; List<KeySchemaElement> indexKeySchema = new List<KeySchemaElement>(); indexKeySchema.Add(new KeySchemaElement() { AttributeName = "Artist", KeyType = "HASH" }); //Partition key indexKeySchema.Add(new KeySchemaElement() { AttributeName = "AlbumTitle", KeyType = "RANGE" }); //Sort key Projection projection = new Projection() { ProjectionType = "INCLUDE" }; List<string> nonKeyAttributes = new List<string>(); nonKeyAttributes.Add("Genre"); nonKeyAttributes.Add("Year"); projection.NonKeyAttributes = nonKeyAttributes; LocalSecondaryIndex localSecondaryIndex = new LocalSecondaryIndex() { API Version 2012-08-10 410 Amazon DynamoDB Manuel du développeur Index secondaires locaux IndexName = "AlbumTitleIndex", KeySchema = indexKeySchema, Projection = projection }; List<LocalSecondaryIndex> localSecondaryIndexes = new List<LocalSecondaryIndex>(); localSecondaryIndexes.Add(localSecondaryIndex); createTableRequest.LocalSecondaryIndexes = localSecondaryIndexes; CreateTableResponse result = client.CreateTable(createTableRequest); Console.WriteLine(result.CreateTableResult.TableDescription.TableName); Console.WriteLine(result.CreateTableResult.TableDescription.TableStatus); Vous devez attendre que DynamoDB ait créé la table et défini l'état de la table sur ACTIVE. Après cela, vous pouvez commencer à mettre les éléments de données dans la table. Décrire une Table avec un Index local secondaire Pour obtenir des informations sur des local secondary index sur une table, utilisez l'API DescribeTable. Pour chaque index, vous pouvez accéder à son nom, son schéma de clé et ses attributs projetés. Voici les étapes pour accéder aux informations local secondary index sur une table à l'aide de l'API de bas niveau .NET. 1. Créez une instance de la classe AmazonDynamoDBClient. 2. Créez une instance de la classe DescribeTableRequest pour fournir l'information de requête. Vous devez fournir le nom de la table. 3. Exécutez la méthode describeTable en fournissant l'objet de requête comme un paramètre. L'extrait de code C# suivant illustre les étapes précédentes. AmazonDynamoDBClient client = new AmazonDynamoDBClient(); string tableName = "Music"; DescribeTableResponse response = client.DescribeTable(new DescribeTableRequest() { TableName = tableName }); List<LocalSecondaryIndexDescription> localSecondaryIndexes = response.DescribeTableResult.Table.LocalSecondaryIndexes; // This code snippet will work for multiple indexes, even though // there is only one index in this example. foreach (LocalSecondaryIndexDescription lsiDescription in localSecondaryIndexes) { Console.WriteLine("Info for index " + lsiDescription.IndexName + ":"); foreach (KeySchemaElement kse in lsiDescription.KeySchema) { Console.WriteLine("\t" + kse.AttributeName + ": key type is " + kse.KeyType); } Projection projection = lsiDescription.Projection; API Version 2012-08-10 411 Amazon DynamoDB Manuel du développeur Index secondaires locaux Console.WriteLine("\tThe projection type is: " + projection.ProjectionType); if (projection.ProjectionType.ToString().Equals("INCLUDE")) { Console.WriteLine("\t\tThe non-key projected attributes are:"); foreach (String s in projection.NonKeyAttributes) { Console.WriteLine("\t\t" + s); } } } Interroger un index secondaire local Vous pouvez utiliser Query sur un local secondary index, de la même façon que vous Query une table. Vous devez spécifier le nom d'index, les critères de requête de la clé de tri d'index et les attributs que vous souhaitez retourner. Dans cet exemple, l'index est AlbumTitleIndex et la clé de tri d'index est AlbumTitle. Les seuls attributs retournés sont ceux qui ont été projetés dans l'index. Vous pouvez modifier cette requête pour sélectionner aussi des attributs non-clés, mais cela nécessite une activité d'extraction de table qui est relativement coûteuse. Pour plus d'informations sur les extractions de table, consultez Projections d'attribut (p. 389). Voici les étapes pour interroger un local secondary index à l'aide de l'API de bas niveau .NET. 1. Créez une instance de la classe AmazonDynamoDBClient. 2. Créez une instance de la classe QueryRequest pour fournir l'information de requête. 3. Exécutez la méthode query en fournissant l'objet de requête comme un paramètre. L'extrait de code C# suivant illustre les étapes précédentes. QueryRequest queryRequest = new QueryRequest { TableName = "Music", IndexName = "AlbumTitleIndex", Select = "ALL_ATTRIBUTES", ScanIndexForward = true, KeyConditionExpression = "Artist = :v_artist and AlbumTitle = :v_title", ExpressionAttributeValues = new Dictionary<string, AttributeValue>() { {":v_artist",new AttributeValue {S = "Acme Band"}}, {":v_title",new AttributeValue {S = "Songs About Life"}} }, }; QueryResponse response = client.Query(queryRequest); foreach (var attribs in response.Items) { foreach (var attrib in attribs) { Console.WriteLine(attrib.Key + " ---> " + attrib.Value.S); } API Version 2012-08-10 412 Amazon DynamoDB Manuel du développeur Index secondaires locaux Console.WriteLine(); } Exemple : Index local secondaire utilisant le SDK AWS pour l'API de bas niveau .NET L'exemple de code C# suivant montre comment utiliser les local secondary index. L'exemple crée une table nommée CustomerOrders avec la clé de partition CustomerId et la clé de tri OrderId. Il existe deux index secondaires locaux sur la table : • OrderCreationDateIndex : la clé de tri est OrderCreationDate et les attributs suivants sont projetés dans l'index : • ProductCategory • ProductName • OrderStatus • ShipmentTrackingId • IsOpenIndex : la clé de tri est IsOpen et tous les attributs de la table sont projetés dans l'index. Après la création de la table CustomerOrders, le programme charge la table avec les données représentant les commandes des clients, puis interroge les données à l'aide des index secondaires locaux. Enfin, le programme supprime la table CustomerOrders. Pour obtenir les instructions pas à pas afin de tester l'exemple suivant, consultez Exemples de code .NET (p. 175). using using using using using using using using using System; System.Collections.Generic; System.Linq; Amazon.DynamoDBv2; Amazon.DynamoDBv2.DataModel; Amazon.DynamoDBv2.DocumentModel; Amazon.DynamoDBv2.Model; Amazon.Runtime; Amazon.SecurityToken; namespace com.amazonaws.codesamples { class LowLevelLocalSecondaryIndexExample { private static AmazonDynamoDBClient client = new AmazonDynamoDBClient(); private static string tableName = "CustomerOrders"; static void Main(string[] args) { try { CreateTable(); LoadData(); Query(null); Query("IsOpenIndex"); Query("OrderCreationDateIndex"); DeleteTable(tableName); API Version 2012-08-10 413 Amazon DynamoDB Manuel du développeur Index secondaires locaux Console.WriteLine("To continue, press Enter"); Console.ReadLine(); } catch (AmazonDynamoDBException e) { Console.WriteLine(e.Message); } catch (AmazonServiceException e) { Console.WriteLine(e.Message); } catch (Exception e) { Console.WriteLine(e.Message); } } private static void CreateTable() { var createTableRequest = new CreateTableRequest() { TableName = tableName, ProvisionedThroughput = new ProvisionedThroughput() { ReadCapacityUnits = (long)1, WriteCapacityUnits = (long)1 } }; var attributeDefinitions = new List<AttributeDefinition>() { // Attribute definitions for table primary key { new AttributeDefinition() {AttributeName = "CustomerId", AttributeType = "S"} }, { new AttributeDefinition() {AttributeName = "OrderId", AttributeType = "N"} }, // Attribute definitions for index primary key { new AttributeDefinition() {AttributeName = "OrderCreationDate", AttributeType = "N"} }, { new AttributeDefinition() {AttributeName = "IsOpen", AttributeType = "N" }} }; createTableRequest.AttributeDefinitions = attributeDefinitions; // Key schema for table var tableKeySchema = new List<KeySchemaElement>() { { new KeySchemaElement() {AttributeName = "CustomerId", KeyType = "HASH"} }, //Partition key { new KeySchemaElement() {AttributeName = "OrderId", KeyType = "RANGE"} } //Sort key }; createTableRequest.KeySchema = tableKeySchema; var localSecondaryIndexes = new List<LocalSecondaryIndex>(); // OrderCreationDateIndex LocalSecondaryIndex orderCreationDateIndex = new LocalSecondaryIndex() { IndexName = "OrderCreationDateIndex" API Version 2012-08-10 414 Amazon DynamoDB Manuel du développeur Index secondaires locaux }; // Key schema for OrderCreationDateIndex var indexKeySchema = new List<KeySchemaElement>() { { new KeySchemaElement() {AttributeName = "CustomerId", KeyType = "HASH"} }, //Partition key { new KeySchemaElement() {AttributeName = "OrderCreationDate", KeyType = "RANGE"} } //Sort key }; orderCreationDateIndex.KeySchema = indexKeySchema; // Projection (with list of projected attributes) for // OrderCreationDateIndex var projection = new Projection() { ProjectionType = "INCLUDE" }; var nonKeyAttributes = new List<string>() { "ProductCategory", "ProductName" }; projection.NonKeyAttributes = nonKeyAttributes; orderCreationDateIndex.Projection = projection; localSecondaryIndexes.Add(orderCreationDateIndex); // IsOpenIndex LocalSecondaryIndex isOpenIndex = new LocalSecondaryIndex() { IndexName = "IsOpenIndex" }; // Key schema for IsOpenIndex indexKeySchema = new List<KeySchemaElement>() { { new KeySchemaElement() {AttributeName = "CustomerId", KeyType = "HASH" }}, //Partition key { new KeySchemaElement() {AttributeName = "IsOpen", KeyType = "RANGE" }} //Sort key }; // Projection (all attributes) for IsOpenIndex projection = new Projection() { ProjectionType = "ALL" }; isOpenIndex.KeySchema = indexKeySchema; isOpenIndex.Projection = projection; localSecondaryIndexes.Add(isOpenIndex); // Add index definitions to CreateTable request createTableRequest.LocalSecondaryIndexes = localSecondaryIndexes; Console.WriteLine("Creating table " + tableName + "..."); client.CreateTable(createTableRequest); WaitUntilTableReady(tableName); } public static void Query(string indexName) { API Version 2012-08-10 415 Amazon DynamoDB Manuel du développeur Index secondaires locaux Console.WriteLine("\n*********************************************************** \n"); Console.WriteLine("Querying table " + tableName + "..."); QueryRequest queryRequest = new QueryRequest() { TableName = tableName, ConsistentRead = true, ScanIndexForward = true, ReturnConsumedCapacity = "TOTAL" }; String keyConditionExpression = "CustomerId = :v_customerId"; Dictionary<string, AttributeValue> expressionAttributeValues = new Dictionary<string, AttributeValue> { {":v_customerId", new AttributeValue { S = "[email protected]" }} }; if (indexName == "IsOpenIndex") { Console.WriteLine("\nUsing index: '" + indexName + "': Bob's orders that are open."); Console.WriteLine("Only a user-specified list of attributes are returned\n"); queryRequest.IndexName = indexName; keyConditionExpression += " and IsOpen = :v_isOpen"; expressionAttributeValues.Add(":v_isOpen", new AttributeValue { N = "1" }); // ProjectionExpression queryRequest.ProjectionExpression = "OrderCreationDate, ProductCategory, ProductName, OrderStatus"; } else if (indexName == "OrderCreationDateIndex") { Console.WriteLine("\nUsing index: '" + indexName + "': Bob's orders that were placed after 01/31/2013."); Console.WriteLine("Only the projected attributes are returned \n"); queryRequest.IndexName = indexName; keyConditionExpression += " and OrderCreationDate > :v_Date"; expressionAttributeValues.Add(":v_Date", new AttributeValue { N = "20130131" }); // Select queryRequest.Select = "ALL_PROJECTED_ATTRIBUTES"; } else { Console.WriteLine("\nNo index: All of Bob's orders, by OrderId:\n"); } API Version 2012-08-10 416 Amazon DynamoDB Manuel du développeur Index secondaires locaux queryRequest.KeyConditionExpression = keyConditionExpression; queryRequest.ExpressionAttributeValues = expressionAttributeValues; var result = client.Query(queryRequest); var items = result.Items; foreach (var currentItem in items) { foreach (string attr in currentItem.Keys) { if (attr == "OrderId" || attr == "IsOpen" || attr == "OrderCreationDate") { Console.WriteLine(attr + "---> " + currentItem[attr].N); } else { Console.WriteLine(attr + "---> " + currentItem[attr].S); } } Console.WriteLine(); } Console.WriteLine("\nConsumed capacity: " + result.ConsumedCapacity.CapacityUnits + "\n"); } private static void DeleteTable(string tableName) { Console.WriteLine("Deleting table " + tableName + "..."); client.DeleteTable(new DeleteTableRequest() { TableName = tableName }); WaitForTableToBeDeleted(tableName); } public static void LoadData() { Console.WriteLine("Loading data into table " + tableName + "..."); Dictionary<string, AttributeValue> item = new Dictionary<string, AttributeValue>(); item["CustomerId"] = new AttributeValue { S = "[email protected]" }; item["OrderId"] = new AttributeValue { N = "1" }; item["IsOpen"] = new AttributeValue { N = "1" }; item["OrderCreationDate"] = new AttributeValue { N = "20130101" }; item["ProductCategory"] = new AttributeValue { S = "Book" }; item["ProductName"] = new AttributeValue { S = "The Great Outdoors" }; item["OrderStatus"] = new AttributeValue { S = "PACKING ITEMS" }; /* no ShipmentTrackingId attribute */ PutItemRequest putItemRequest = new PutItemRequest { TableName = tableName, Item = item, API Version 2012-08-10 417 Amazon DynamoDB Manuel du développeur Index secondaires locaux ReturnItemCollectionMetrics = "SIZE" }; client.PutItem(putItemRequest); item = new Dictionary<string, AttributeValue>(); item["CustomerId"] = new AttributeValue { S = "[email protected]" }; item["OrderId"] = new AttributeValue { N = "2" }; item["IsOpen"] = new AttributeValue { N = "1" }; item["OrderCreationDate"] = new AttributeValue { N = "20130221" }; item["ProductCategory"] = new AttributeValue { S = "Bike" }; item["ProductName"] = new AttributeValue { S = "Super Mountain" }; item["OrderStatus"] = new AttributeValue { S = "ORDER RECEIVED" }; /* no ShipmentTrackingId attribute */ putItemRequest = new PutItemRequest { TableName = tableName, Item = item, ReturnItemCollectionMetrics = "SIZE" }; client.PutItem(putItemRequest); item = new Dictionary<string, AttributeValue>(); item["CustomerId"] = new AttributeValue { S = "[email protected]" }; item["OrderId"] = new AttributeValue { N = "3" }; /* no IsOpen attribute */ item["OrderCreationDate"] = new AttributeValue { N = "20130304" }; item["ProductCategory"] = new AttributeValue { S = "Music" }; item["ProductName"] = new AttributeValue { S = "A Quiet Interlude" }; item["OrderStatus"] = new AttributeValue { S = "IN TRANSIT" }; item["ShipmentTrackingId"] = new AttributeValue { S = "176493" }; putItemRequest = new PutItemRequest { TableName = tableName, Item = item, ReturnItemCollectionMetrics = "SIZE" }; client.PutItem(putItemRequest); item = new Dictionary<string, AttributeValue>(); item["CustomerId"] = new AttributeValue { S = "[email protected]" }; item["OrderId"] = new AttributeValue { N = "1" }; /* no IsOpen attribute */ item["OrderCreationDate"] = new AttributeValue { N = "20130111" }; item["ProductCategory"] = new AttributeValue { S = "Movie" }; item["ProductName"] = new AttributeValue { S = "Calm Before The Storm" }; item["OrderStatus"] = new AttributeValue { S = "SHIPPING DELAY" }; item["ShipmentTrackingId"] = new AttributeValue { S = "859323" }; putItemRequest = new PutItemRequest API Version 2012-08-10 418 Amazon DynamoDB Manuel du développeur Index secondaires locaux { TableName = tableName, Item = item, ReturnItemCollectionMetrics = "SIZE" }; client.PutItem(putItemRequest); item = new Dictionary<string, AttributeValue>(); item["CustomerId"] = new AttributeValue { S = "[email protected]" }; item["OrderId"] = new AttributeValue { N = "2" }; /* no IsOpen attribute */ item["OrderCreationDate"] = new AttributeValue { N = "20130124" }; item["ProductCategory"] = new AttributeValue { S = "Music" }; item["ProductName"] = new AttributeValue { S = "E-Z Listening" }; item["OrderStatus"] = new AttributeValue { S = "DELIVERED" }; item["ShipmentTrackingId"] = new AttributeValue { S = "756943" }; putItemRequest = new PutItemRequest { TableName = tableName, Item = item, ReturnItemCollectionMetrics = "SIZE" }; client.PutItem(putItemRequest); item = new Dictionary<string, AttributeValue>(); item["CustomerId"] = new AttributeValue { S = "[email protected]" }; item["OrderId"] = new AttributeValue { N = "3" }; /* no IsOpen attribute */ item["OrderCreationDate"] = new AttributeValue { N = "20130221" }; item["ProductCategory"] = new AttributeValue { S = "Music" }; item["ProductName"] = new AttributeValue { S = "Symphony 9" }; item["OrderStatus"] = new AttributeValue { S = "DELIVERED" }; item["ShipmentTrackingId"] = new AttributeValue { S = "645193" }; putItemRequest = new PutItemRequest { TableName = tableName, Item = item, ReturnItemCollectionMetrics = "SIZE" }; client.PutItem(putItemRequest); item = new Dictionary<string, AttributeValue>(); item["CustomerId"] = new AttributeValue { S = "[email protected]" }; item["OrderId"] = new AttributeValue { N = "4" }; item["IsOpen"] = new AttributeValue { N = "1" }; item["OrderCreationDate"] = new AttributeValue { N = "20130222" }; item["ProductCategory"] = new AttributeValue { S = "Hardware" }; item["ProductName"] = new AttributeValue { S = "Extra Heavy Hammer" }; item["OrderStatus"] = new AttributeValue { S = "PACKING ITEMS" }; /* no ShipmentTrackingId attribute */ putItemRequest = new PutItemRequest { API Version 2012-08-10 419 Amazon DynamoDB Manuel du développeur Index secondaires locaux TableName = tableName, Item = item, ReturnItemCollectionMetrics = "SIZE" }; client.PutItem(putItemRequest); item = new Dictionary<string, AttributeValue>(); item["CustomerId"] = new AttributeValue { S = "[email protected]" }; item["OrderId"] = new AttributeValue { N = "5" }; /* no IsOpen attribute */ item["OrderCreationDate"] = new AttributeValue { N = "20130309" }; item["ProductCategory"] = new AttributeValue { S = "Book" }; item["ProductName"] = new AttributeValue { S = "How To Cook" }; item["OrderStatus"] = new AttributeValue { S = "IN TRANSIT" }; item["ShipmentTrackingId"] = new AttributeValue { S = "440185" }; putItemRequest = new PutItemRequest { TableName = tableName, Item = item, ReturnItemCollectionMetrics = "SIZE" }; client.PutItem(putItemRequest); item = new Dictionary<string, AttributeValue>(); item["CustomerId"] = new AttributeValue { S = "[email protected]" }; item["OrderId"] = new AttributeValue { N = "6" }; /* no IsOpen attribute */ item["OrderCreationDate"] = new AttributeValue { N = "20130318" }; item["ProductCategory"] = new AttributeValue { S = "Luggage" }; item["ProductName"] = new AttributeValue { S = "Really Big Suitcase" }; item["OrderStatus"] = new AttributeValue { S = "DELIVERED" }; item["ShipmentTrackingId"] = new AttributeValue { S = "893927" }; putItemRequest = new PutItemRequest { TableName = tableName, Item = item, ReturnItemCollectionMetrics = "SIZE" }; client.PutItem(putItemRequest); item = new Dictionary<string, AttributeValue>(); item["CustomerId"] = new AttributeValue { S = "[email protected]" }; item["OrderId"] = new AttributeValue { N = "7" }; /* no IsOpen attribute */ item["OrderCreationDate"] = new AttributeValue { N = "20130324" }; item["ProductCategory"] = new AttributeValue { S = "Golf" }; item["ProductName"] = new AttributeValue { S = "PGA Pro II" }; item["OrderStatus"] = new AttributeValue { S = "OUT FOR DELIVERY" }; item["ShipmentTrackingId"] = new AttributeValue { S = "383283" }; putItemRequest = new PutItemRequest { API Version 2012-08-10 420 Amazon DynamoDB Manuel du développeur Index secondaires locaux TableName = tableName, Item = item, ReturnItemCollectionMetrics = "SIZE" }; client.PutItem(putItemRequest); } private static void WaitUntilTableReady(string tableName) { string status = null; // Let us wait until table is created. Call DescribeTable. do { System.Threading.Thread.Sleep(5000); // Wait 5 seconds. try { var res = client.DescribeTable(new DescribeTableRequest { TableName = tableName }); Console.WriteLine("Table name: {0}, status: {1}", res.Table.TableName, res.Table.TableStatus); status = res.Table.TableStatus; } catch (ResourceNotFoundException) { // DescribeTable is eventually consistent. So you might // get resource not found. So we handle the potential exception. } } while (status != "ACTIVE"); } private static void WaitForTableToBeDeleted(string tableName) { bool tablePresent = true; while (tablePresent) { System.Threading.Thread.Sleep(5000); // Wait 5 seconds. try { var res = client.DescribeTable(new DescribeTableRequest { TableName = tableName }); Console.WriteLine("Table name: {0}, status: {1}", res.Table.TableName, res.Table.TableStatus); } catch (ResourceNotFoundException) { tablePresent = false; } } } API Version 2012-08-10 421 Amazon DynamoDB Manuel du développeur Index secondaires locaux } } Utilisation des index secondaires locaux : PHP Rubriques • Créer une table avec un index secondaire local (p. 422) • Interroger un index secondaire local (p. 423) • Exemple : Index secondaires locaux avec l'API de bas niveau du SDK AWS pour PHP (p. 424) Vous pouvez utiliser l'API de bas niveau du SDK AWS pour PHP afin de créer une table avec un ou plusieurs index secondaires locaux, décrire les index de la table et exécuter les requêtes à l'aide des index. Ces opérations sont mappées à l'API DynamoDB correspondante. Pour de plus amples informations, veuillez consulter Exemples de Code PHP (p. 177). Voici les étapes courantes des opérations de table à l'aide du SDK AWS pour PHP. 1. Créer une instance du client DynamoDB. 2. Fournir les paramètres d'une opération DynamoDB, y compris les paramètres facultatifs. 3. Charger la réponse à partir de DynamoDB dans une variable locale pour votre application. Créer une table avec un index secondaire local Les index secondaires locaux doivent être créés en même temps que vous créez une table. Pour ce faire, utilisez CreateTable et fournissez à vos spécifications un ou plusieurs local secondary index. L'extrait de code PHP suivant crée une table qui contient les informations sur les chansons d'une collection musicale. La clé de partition est Artist et la clé de tri est SongTitle. Un index secondaire, AlbumTitleIndex, facilite les requêtes par titre d'album. La clé de partition de table et la clé de tri, ainsi que la clé de tri d'index, sont les seuls attributs projetés dans l'index. require 'vendor/autoload.php'; $sdk = new Aws\Sdk([ 'region' => 'us-west-2', 'version' => 'latest' ]); $dynamodb = $sdk->createDynamoDb(); $tableName = 'Music'; $result = $dynamodb->createTable([ 'TableName' => $tableName, 'AttributeDefinitions' => [ [ 'AttributeName' => 'Artist', 'AttributeType' => 'S' ], [ 'AttributeName' => 'SongTitle', 'AttributeType' => 'S' ], [ 'AttributeName' => 'AlbumTitle', 'AttributeType' => 'S' ] ], 'KeySchema' => [ [ 'AttributeName' => 'Artist', 'KeyType' => 'HASH' ], [ 'AttributeName' => 'SongTitle', 'KeyType' => 'RANGE' ] ], API Version 2012-08-10 422 Amazon DynamoDB Manuel du développeur Index secondaires locaux 'LocalSecondaryIndexes' => [ [ 'IndexName' => 'AlbumTitleIndex', 'KeySchema' => [ [ 'AttributeName' => 'Artist', 'KeyType' => 'HASH' ], [ 'AttributeName' => 'AlbumTitle', 'KeyType' => 'RANGE' ] ], 'Projection' => [ 'ProjectionType' => 'INCLUDE', 'NonKeyAttributes' => ['Genre', 'Year'] ] ] ], 'ProvisionedThroughput' => [ 'ReadCapacityUnits' => 5, 'WriteCapacityUnits' => 5 ] ]); Vous devez attendre que DynamoDB ait créé la table et défini l'état de la table sur ACTIVE. Après cela, vous pouvez commencer à mettre les éléments de données dans la table. Interroger un index secondaire local Vous pouvez utiliser l'opération Query sur un index secondaire local, de la même façon que vous exécutez une opération Query sur une table. Vous devez spécifier le nom d'index, les critères de requête de la clé de tri d'index et les attributs que vous souhaitez retourner. Dans cet exemple, l'index est AlbumTitleIndex et la clé de tri d'index est AlbumTitle. Les seuls attributs retournés sont ceux qui ont été projetés dans l'index. Vous pouvez modifier cette requête pour sélectionner aussi des attributs non-clés, mais cela nécessite une activité d'extraction de table qui est relativement coûteuse. Pour plus d'informations sur les extractions de table, consultez Projections d'attribut (p. 389). $tableName='Music'; $response = $dynamodb->query([ 'TableName' => $tableName, 'IndexName' => 'AlbumTitleIndex', 'KeyConditionExpression' => 'Artist = :v_artist and AlbumTitle >= :v_title', 'ExpressionAttributeValues' => [ ':v_artist' => ['S' => 'Acme Band'], ':v_title' => ['S' => 'Songs About Life'] ], 'Select' => 'ALL_ATTRIBUTES' ]); echo "Acme Band's Songs About Life:\n"; foreach($response['Items'] as $item) { echo " - " . $item['SongTitle']['S'] . "\n"; } API Version 2012-08-10 423 Amazon DynamoDB Manuel du développeur Index secondaires locaux Exemple : Index secondaires locaux avec l'API de bas niveau du SDK AWS pour PHP L'exemple de code PHP suivant montre comment utiliser les index secondaires locaux. L'exemple crée une table nommée CustomerOrders avec la clé de partition CustomerId et la clé de tri OrderId. Il existe deux index secondaires locaux sur la table : • OrderCreationDateIndex : la clé de tri est OrderCreationDate et les attributs suivants sont projetés dans l'index : • ProductCategory • ProductName • OrderStatus • ShipmentTrackingId • IsOpenIndex : la clé de tri est IsOpen et tous les attributs de la table sont projetés dans l'index. Après la création de la table CustomerOrders, le programme charge la table avec les données représentant les commandes des clients, puis interroge les données à l'aide des index secondaires locaux. Enfin, le programme supprime la table CustomerOrders. <?php require 'vendor/autoload.php'; date_default_timezone_set('UTC'); use Aws\DynamoDb\Exception\DynamoDbException; $sdk = new Aws\Sdk([ 'region' => 'us-west-2', 'version' => 'latest' ]); $dynamodb = $sdk->createDynamoDb(); $tableName = 'CustomerOrders'; echo "# Creating table $tableName...\n"; try { $response = $dynamodb->createTable([ 'TableName' => $tableName, 'AttributeDefinitions' => [ [ 'AttributeName' => 'CustomerId', 'AttributeType' => 'S' ], [ 'AttributeName' => 'OrderId', 'AttributeType' => 'N' ], [ 'AttributeName' => 'OrderCreationDate', 'AttributeType' => 'N' ], [ 'AttributeName' => 'IsOpen', 'AttributeType' => 'N' ] ], 'KeySchema' => [ [ 'AttributeName' => 'CustomerId', 'KeyType' => 'HASH' ], // Partition key [ 'AttributeName' => 'OrderId', 'KeyType' => 'RANGE' ] //Sort key ], 'LocalSecondaryIndexes' => [ [ 'IndexName' => 'OrderCreationDateIndex', 'KeySchema' => [ API Version 2012-08-10 424 Amazon DynamoDB Manuel du développeur Index secondaires locaux [ 'AttributeName' => 'CustomerId', 'KeyType' => 'HASH' ], //Partition key [ 'AttributeName' => 'OrderCreationDate', 'KeyType' => //Sort key ], 'Projection' => [ 'ProjectionType' => 'INCLUDE', 'NonKeyAttributes' => ['ProductCategory', 'ProductName'] ] ], [ 'IndexName' => 'IsOpenIndex', 'KeySchema' => [ [ 'AttributeName' => 'CustomerId', 'KeyType' => 'HASH' ], //Partition key [ 'AttributeName' => 'IsOpen', 'KeyType' => 'RANGE' ] // Sort key ], 'Projection' => [ 'ProjectionType' => 'ALL' ] ] ], 'ProvisionedThroughput' => [ 'ReadCapacityUnits' => 5, 'WriteCapacityUnits' => 5 ] ]); 'RANGE' ] echo " Waiting for table $tableName to be created.\n"; $dynamodb->waitUntil('TableExists', [ 'TableName' => $tableName, '@waiter' => [ 'delay' => 5, 'maxAttempts' => 20 ] ]); echo " Table $tableName has been created.\n"; } catch (DynamoDbException $e) { echo $e->getMessage() . "\n"; exit ("Unable to create table $tableName\n"); } ######################################### # Add items to the table echo "# Loading data into $tableName...\n"; $response = $dynamodb->putItem ( [ 'TableName' => $tableName, 'Item' => [ 'CustomerId' => ['S' => '[email protected]'], 'OrderId' => ['N' => '1'], 'IsOpen' => ['N' => '1'], 'OrderCreationDate' => ['N' => '20140101'], 'ProductCategory' => ['S' => 'Book'], 'ProductName' => ['S' => 'The Great Outdoors'], 'OrderStatus' => ['S' => 'PACKING ITEMS'] ] ]); API Version 2012-08-10 425 Amazon DynamoDB Manuel du développeur Index secondaires locaux $response = $dynamodb->putItem ( [ 'TableName' => $tableName, 'Item' => [ 'CustomerId' => ['S' => '[email protected]'], 'OrderId' => ['N' => '2'], 'IsOpen' => ['N' => '1'], 'OrderCreationDate' => ['N' => '20140221'], 'ProductCategory' => ['S' => 'Bike'], 'ProductName' => ['S' => 'Super Mountain'], 'OrderStatus' => ['S' => 'ORDER RECEIVED'] ] ]); $response = $dynamodb->putItem ( [ 'TableName' => $tableName, 'Item' => [ 'CustomerId' => ['S' => '[email protected]'], 'OrderId' => ['N' => '3'], // no IsOpen attribute 'OrderCreationDate' => ['N' => '20140304'], 'ProductCategory' => ['S' => 'Music'], 'ProductName' => ['S' => 'A Quiet Interlude'], 'OrderStatus' => ['S' => 'IN TRANSIT'], 'ShipmentTrackingId' => ['N' => '176493'] ] ]); $response = $dynamodb->putItem ( [ 'TableName' => $tableName, 'Item' => [ 'CustomerId' => ['S' => '[email protected]'], 'OrderId' => ['N' => '1'], // no IsOpen attribute 'OrderCreationDate' => ['N' => '20140111'], 'ProductCategory' => ['S' => 'Movie'], 'ProductName' => ['S' => 'Calm Before The Storm'], 'OrderStatus' => ['S' => 'SHIPPING DELAY'], 'ShipmentTrackingId' => ['N' => '859323'] ] ]); $response = $dynamodb->putItem ( [ 'TableName' => $tableName, 'Item' => [ 'CustomerId' => ['S' => '[email protected]'], 'OrderId' => ['N' => '2'], // no IsOpen attribute 'OrderCreationDate' => ['N' => '20140124'], 'ProductCategory' => ['S' => 'Music'], 'ProductName' => ['S' => 'E-Z Listening'], 'OrderStatus' => ['S' => 'DELIVERED'], 'ShipmentTrackingId' => ['N' => '756943'] ] ]); $response = $dynamodb->putItem ( [ 'TableName' => $tableName, 'Item' => [ 'CustomerId' => ['S' => '[email protected]'], API Version 2012-08-10 426 Amazon DynamoDB Manuel du développeur Index secondaires locaux 'OrderId' => ['N' => '3'], // no IsOpen attribute 'OrderCreationDate' => ['N' => '20140221'], 'ProductCategory' => ['S' => 'Music'], 'ProductName' => ['S' => 'Symphony 9'], 'OrderStatus' => ['S' => 'DELIVERED'], 'ShipmentTrackingId' => ['N' => '645193'] ] ]); $response = $dynamodb->putItem ( [ 'TableName' => $tableName, 'Item' => [ 'CustomerId' => ['S' => '[email protected]'], 'OrderId' => ['N' => '4'], 'IsOpen' => ['N' => '1'], 'OrderCreationDate' => ['N' => '20140222'], 'ProductCategory' => ['S' => 'Hardware'], 'ProductName' => ['S' => 'Extra Heavy Hammer'], 'OrderStatus' => ['S' => 'PACKING ITEMS'] ] ]); $response = $dynamodb->putItem ( [ 'TableName' => $tableName, 'Item' => [ 'CustomerId' => ['S' => '[email protected]'], 'OrderId' => ['N' => '5'], // no IsOpen attribute 'OrderCreationDate' => ['N' => '20140309'], 'ProductCategory' => ['S' => 'Book'], 'ProductName' => ['S' => 'How To Cook'], 'OrderStatus' => ['S' => 'IN TRANSIT'], 'ShipmentTrackingId' => ['N' => '440185'] ] ]); $response = $dynamodb->putItem ( [ 'TableName' => $tableName, 'Item' => [ 'CustomerId' => ['S' => '[email protected]'], 'OrderId' => ['N' => '6'], // no IsOpen attribute 'OrderCreationDate' => ['N' => '20140318'], 'ProductCategory' => ['S' => 'Luggage'], 'ProductName' => ['S' => 'Really Big Suitcase'], 'OrderStatus' => ['S' => 'DELIVERED'], 'ShipmentTrackingId' => ['N' => '893927'] ] ]); $response = $dynamodb->putItem ( [ 'TableName' => $tableName, 'Item' => [ 'CustomerId' => ['S' => '[email protected]'], 'OrderId' => ['N' => '7'], // no IsOpen attribute 'OrderCreationDate' => ['N' => '20140324'], 'ProductCategory' => ['S' => 'Golf'], API Version 2012-08-10 427 Amazon DynamoDB Manuel du développeur Index secondaires locaux 'ProductName' => ['S' => 'PGA Pro II'], 'OrderStatus' => ['S' => 'OUT FOR DELIVERY'], 'ShipmentTrackingId' => ['N' => '383283'] ] ]); ######################################### # Query for Bob's 5 most recent orders in 2014, retrieving attributes which # are projected into the index $response = $dynamodb->query([ 'TableName' => $tableName, 'IndexName' => 'OrderCreationDateIndex', 'KeyConditionExpression' => 'CustomerId = :v_id and OrderCreationDate >= :v_dt', 'ExpressionAttributeValues' => [ ':v_id' => ['S' => '[email protected]'], ':v_dt' => ['N' => '20140101'] ], 'Select' => 'ALL_PROJECTED_ATTRIBUTES', 'ScanIndexForward' => false, 'ConsistentRead' => true, 'Limit' => 5, 'ReturnConsumedCapacity' => 'TOTAL' ]); echo "# Querying for Bob's 5 most recent orders in 2014:\n"; foreach($response['Items'] as $item) { echo ' - ' . $item['CustomerId']['S'] . ' ' . $item['OrderCreationDate']['N'] . ' ' . $item['ProductName']['S'] . ' ' . $item['ProductCategory']['S'] . "\n"; } echo ' Provisioned Throughput Consumed: ' . $response['ConsumedCapacity']['CapacityUnits'] . "\n"; ######################################### # Query for Bob's 5 most recent orders in 2014, retrieving some attributes # which are not projected into the index $response = $dynamodb->query([ 'TableName' => $tableName, 'IndexName' => 'OrderCreationDateIndex', 'KeyConditionExpression' => 'CustomerId = :v_id and OrderCreationDate >= :v_dt', 'ExpressionAttributeValues' => [ ':v_id' => ['S' => '[email protected]'], ':v_dt' => ['N' => '20140101'] ], 'Select' => 'SPECIFIC_ATTRIBUTES', 'ProjectionExpression' => 'CustomerId, OrderCreationDate, ProductName, ProductCategory, OrderStatus', 'ScanIndexForward' => false, 'ConsistentRead' => true, 'Limit' => 5, 'ReturnConsumedCapacity' => 'TOTAL' API Version 2012-08-10 428 Amazon DynamoDB Manuel du développeur Index secondaires locaux ]); echo "# Querying for Bob's 5 most recent orders in 2014:" . "\n"; foreach($response['Items'] as $item) { echo ' - ' . $item['CustomerId']['S'] . ' ' . $item['OrderCreationDate']['N'] . ' ' . $item['ProductName']['S'] . ' ' . $item['ProductCategory']['S'] . ' ' . $item['OrderStatus']['S'] . "\n"; } echo ' Provisioned Throughput Consumed: ' . $response['ConsumedCapacity']['CapacityUnits'] . "\n"; ######################################### # Query for Alice's open orders, fetching all attributes # (which are already projected into the index) $response = $dynamodb->query([ 'TableName' => $tableName, 'IndexName' => 'IsOpenIndex', 'KeyConditionExpression' => 'CustomerId = :v_id', 'ExpressionAttributeValues' => [ ':v_id' => ['S' => '[email protected]'] ], 'Select' => 'ALL_ATTRIBUTES', 'ScanIndexForward' => false, 'ConsistentRead' => true, 'Limit' => 5, 'ReturnConsumedCapacity' => 'TOTAL' ]); echo "# Querying for Alice's open orders:" . "\n"; foreach($response['Items'] as $item) { echo ' - ' . $item['CustomerId']['S']. ' ' . $item['OrderCreationDate']['N'] . ' ' . $item['ProductName']['S'] . ' ' . $item['ProductCategory']['S'] . ' ' . $item['OrderStatus']['S'] . "\n"; } echo ' Provisioned Throughput Consumed: ' . $response['ConsumedCapacity']['CapacityUnits'] . "\n"; ######################################### # Delete the table try { $dynamodb->deleteTable(['TableName' => $tableName]); echo " Waiting for table $tableName to be deleted.\n"; $dynamodb->waitUntil('TableNotExists', [ 'TableName' => $tableName, '@waiter' => [ 'delay' => 5, 'maxAttempts' => 20 ] ]); API Version 2012-08-10 429 Amazon DynamoDB Manuel du développeur Utilisation des flux echo " Table $tableName has been deleted.\n"; } catch (DynamoDbException $e) { echo $e->getMessage() . "\n"; exit ("Unable to delete table $tableName\n"); } ?> Capture d'activité Table avec Flux DynamoDB De nombreuses applications peuvent bénéficier de la possibilité de capturer des modifications dans des éléments stockés dans une table DynamoDB au moment où de telles modifications se produisent. Voici quelques exemples de cas d'utilisation : • Une application dans une région AWS modifie les données dans une table DynamoDB. Une deuxième application dans une autre région AWS lit ces modifications de données et écrit les données dans une autre table, créant un réplica qui reste synchronisé avec la table d'origine. • Une application mobile populaire modifie les données dans une table DynamoDB, au rythme de milliers de mises à jour par seconde. Une autre application capture et stocke des données sur ces mises à jour, incluant des métriques d'utilisation presque en temps réel pour l'application mobile. • Un jeu multi-joueurs mondial a une topologie à multiples maîtres, stockant des données dans plusieurs régions AWS. Chaque maître reste synchronisé via l'utilisation et la relecture des modifications qui se produisent dans des régions à distance. • Une application envoie automatiquement des notifications sur les appareils mobiles de tous les amis dans un groupe dès qu'un ami télécharge une nouvelle image. • Un nouveau client ajoute des données à une table DynamoDB. Cet événement appelle une autre application qui envoie un e-mail de bienvenue au nouveau client. Flux DynamoDB permet des solutions telles que celles-là, et bien d'autres. Flux DynamoDB capture une séquence chronologique des modifications au niveau des éléments dans toute table DynamoDB et stocke ces informations dans un journal pendant 24 heures. Les applications ont accès à ce journal et affichent les éléments de données à mesure qu'ils s'affichent avant et après qu'ils ont été modifiés, pratiquement en temps réel. Un flux DynamoDB est un flux ordonné d'informations sur les modifications apportées aux éléments dans une table Amazon DynamoDB. Lorsque vous activez un flux sur une table, DynamoDB capture des informations sur chaque modification apportée à des éléments de données dans la table. Chaque fois qu'une application crée, met à jour ou supprime des éléments dans la table, Flux DynamoDB écrit un enregistrement de flux avec le ou les attributs clés primaires des éléments qui ont été modifiés. Un enregistrement de flux contient des informations sur une modification de données dans un seul élément dans une table DynamoDB. Vous pouvez configurer le flux de telle sorte que les enregistrements de flux capturent des informations supplémentaires, telles que les images « avant » et « après » d'éléments modifiés. Flux DynamoDB garantit ce qui suit : • Chaque enregistrement de flux s'affiche exactement une fois dans le flux. • Pour chaque élément qui est modifié dans une table DynamoDB, les enregistrements de flux apparaissent dans le même ordre que les modifications effectivement apportées à l'élément. Flux DynamoDB écrit des enregistrements de flux presque en temps réel, afin que vous puissiez développer des applications qui utilisent ces flux et entreprendre des actions basées sur le contenu. API Version 2012-08-10 430 Amazon DynamoDB Manuel du développeur Point de terminaisons pour Flux DynamoDB Point de terminaisons pour Flux DynamoDB AWS gère des points de terminaisons distincts pour DynamoDB et Flux DynamoDB. Pour travailler avec des index et des tables de base de données, votre application doit accéder à un point de terminaison DynamoDB. Pour lire et traiter des enregistrements Flux DynamoDB, votre application doit pouvoir accéder à un point de terminaison Flux DynamoDB dans la même région. La convention d'affectation de noms pour les points de terminaison Flux DynamoDB est streams.dynamodb.<region>.amazonaws.com. Par exemple, si vous utilisez le point de terminaison dynamodb.us-west-2.amazonaws.com pour accéder à DynamoDB, vous devez utiliser le point de terminaison streams.dynamodb.us-west-2.amazonaws.com pour accéder à Flux DynamoDB. Note Pour obtenir une liste complète de régions et de points de terminaison DynamoDB et Flux DynamoDB, consultez la page Régions et points de terminaison dans AWS General Reference. Les AWS SDK fournissent des clients distincts pour DynamoDB et Flux DynamoDB. En fonction de vos besoins, votre application peut accéder à un point de terminaison DynamoDB, un point de terminaison Flux DynamoDB, ou aux deux en même temps. Pour vous connecter aux deux points de terminaison, votre application doit instancier deux clients : un pour DynamoDB et un pour Flux DynamoDB. API Version 2012-08-10 431 Amazon DynamoDB Manuel du développeur Activation d'un flux Activation d'un flux Vous pouvez activer un flux sur une nouvelle table lorsque vous la créez. Vous pouvez également activer ou désactiver un flux dans une table existante ou modifier les paramètres d'un flux. Flux DynamoDB fonctionne de manière asynchrone, ainsi il n'y a aucun impact sur les performances d'une table si vous activez un flux. Le plus simple pour gérer Flux DynamoDB consiste à utiliser la AWS Management Console. 1. Ouvrez la console DynamoDB à l'adresse https://console.aws.amazon.com/dynamodb/. 2. Dans le tableau de bord de la console DynamoDB, choisissez Tables 3. 4. Sous l'onglet Overview, choisissez Manage Stream. Dans la fenêtre Manage Stream, choisissez les informations qui seront écrites dans le flux chaque fois que des données de la table seront modifiées : • Keys only – uniquement les attributs clés de l'élément modifié. • New image – l'élément entier, tel qu'il s'affiche une fois qu'il a été modifié. • Old image – l'élément entier, tel qu'il s'affichait avant sa modification. • New and old images – la nouvelle et l'ancienne images de l'élément. Lorsque les paramètres vous conviennent, choisissez Enable. 5. (Facultatif) Pour désactiver un flux existant, choisissez Manage Stream, puis Disable. Vous pouvez également utiliser les API CreateTable ou UpdateTable pour activer ou modifier un flux. Le paramètre StreamSpecification détermine la façon dont le flux est configuré : • StreamEnabled – indique si un flux de données est activé (true) ou désactivé (false) pour la table. • StreamViewType – spécifie les informations qui seront écrites dans le flux chaque fois que des données de la table seront modifiées : • KEYS_ONLY – uniquement les attributs clés de l'élément modifié. • NEW_IMAGE – l'élément entier, tel qu'il s'affiche une fois qu'il a été modifié. • OLD_IMAGE – l'élément entier, tel qu'il s'affichait avant sa modification. • NEW_AND_OLD_IMAGES – la nouvelle et l'ancienne images de l'élément. Vous pouvez activer ou désactiver un flux à tout moment. Cependant, veuillez noter que vous recevrez une ResourceInUseException si vous tentez d'activer un flux sur une table qui a déjà un flux, et que vous recevrez une ValidationException si vous essayez de désactiver un flux sur une table qui n'en a pas. Lorsque vous définissez StreamEnabled sur true, DynamoDB crée un flux avec un descripteur de flux unique qui lui est attribué. Si vous désactivez et puis réactivez un flux sur la table, un flux est créé avec un descripteur de flux différent. Chaque flux est identifié de manière unique par un Amazon Resource Name (ARN). Voici un exemple d'ARN pour un flux sur une table DynamoDB nommée TestTable : arn:aws:dynamodb:us-west-2:111122223333:table/TestTable/ stream/2015-05-11T21:21:33.291 Pour déterminer le dernier descripteur de flux pour une table, émettez une requête DescribeTable DynamoDB puis recherchez l'élément LatestStreamArn dans la réponse. API Version 2012-08-10 432 Amazon DynamoDB Manuel du développeur Lecture et traitement de flux Lecture et traitement de flux Pour lire et traiter un flux, votre application doit se connecter à un point de terminaison Flux DynamoDB et émettre des demandes d'API. Un flux se compose d'enregistrements de flux. Chaque enregistrement de flux représente une modification de donnée unique dans la table DynamoDB à laquelle le flux appartient. Chaque enregistrement de flux se voit attribuer un numéro de séquence, ce qui reflète l'ordre dans lequel l'enregistrement a été publié dans le flux. Les enregistrements de flux sont organisés en groupes, ou partitions. Chaque partition agit comme un conteneur pour plusieurs enregistrements de flux et contient les informations requises pour accéder à ces enregistrements et les itérer. Les enregistrements de flux au sein d'une partition sont automatiquement supprimés au bout de 24 heures. Les partitions sont éphémères. Elles sont créées et supprimées automatiquement, en fonction des besoins. Toute partition peut également se diviser en plusieurs partitions nouvelles. Cela se produit également automatiquement. (Notez qu'il est aussi possible pour une partition parent d'avoir une seule partition enfant). Une partition peut se diviser en réponse à des niveaux élevés d'activité d'écriture sur sa table parent, de telle sorte que les applications puissent traiter les enregistrements issus de plusieurs partitions en parallèle. Si vous désactivez un flux, toute partition ouverte sera fermée. Comme les partitions ont une lignée (parent et enfants), les applications doivent toujours traiter une partition parent avant de traiter une partition enfant. Cela garantit que les enregistrements de flux sont également traités dans l'ordre adéquat. (Si vous utilisez le Flux DynamoDB Kinesis Adapter, la gestion est automatique : votre application traite les partitions et les enregistrements de flux dans l'ordre adéquat et gère automatiquement les partitions nouvelles ou périmées, ainsi que les partitions qui se divisent tandis que l'application est en cours d'exécution. Pour de plus amples informations, veuillez consulter Utilisation de Flux DynamoDB Kinesis Adapter pour traiter les enregistrements de flux (p. 435).) Le schéma suivant illustre la relation entre un flux de données, les partitions dans le flux et les enregistrements de flux dans les partitions. API Version 2012-08-10 433 Amazon DynamoDB Manuel du développeur Lecture et traitement de flux Note Si vous effectuez une opération PutItem ou UpdateItem qui ne change aucune donnée dans un élément, alors Flux DynamoDB n'écrit pas un enregistrement de flux pour cette opération. Pour accéder à un flux de données et traiter les enregistrements de flux qu'il contient, vous devez effectuer les opérations suivantes : • Déterminer l'ARN (Amazon Resource Name) unique du flux auquel vous souhaitez accéder. • Déterminer quelles sont la ou les partitions dans le flux qui contiennent les enregistrements de flux qui vous intéressent. • Accéder aux partitions et récupérer les enregistrements de flux que vous voulez. Note Un maximum de 2 processus doivent lire simultanément à partir de la même partition de flux. Avoir plus de 2 lecteurs par partition peut entraîner une limitation. L'API Flux DynamoDB fournit les actions suivantes pour une utilisation par des programmes d'application : • ListStreams — renvoie une liste des descripteurs de flux pour le compte actuel et le point de terminaison. Vous pouvez en option demander uniquement les descripteurs de flux pour un nom de table particulier. • DescribeStream — renvoie des informations détaillées sur un flux donné. La file d'attente inclut une liste de partitions associées au flux, y compris les ID de partition. • GetShardIterator—renvoie un itérateur de partition qui décrit un emplacement au sein d'une partition. Vous pouvez demander que l'itérateur fournisse un accès au point le plus ancien, au point le plus récent ou à un point particulier dans le flux. • GetRecords—renvoie les enregistrements de flux au sein d'une partition donnée. Vous devez fournir l'itérateur de partition renvoyé à partir d'une requête GetShardIterator. Pour une description complète de ces actions d'API, y compris les exemples de requêtes et de réponses, accédez à Référence de l'API Amazon DynamoDB Flux. Limite de rétention des données pour Flux DynamoDB Toutes les données dans Flux DynamoDB sont soumises à une durée de vie de 24 heures. Vous pouvez récupérer et analyser les 24 dernières heures d'activité pour n'importe quelle table donnée. Cependant, les données de plus de 24 heures sont susceptibles d'être tronquées (supprimées) à tout moment. Si vous désactivez un flux sur une table, les données dans le flux continueront d'être lisibles pendant 24 heures. Passé ce délai, les données expirent et les enregistrements de flux sont supprimés automatiquement. Notez qu'il n'y a aucun mécanisme permettant de supprimer manuellement un flux existant. Vous devez simplement attendre que la limite de rétention expire (24 heures), alors tous les enregistrements de flux seront supprimés. API Version 2012-08-10 434 Amazon DynamoDB Manuel du développeur Utilisation de Flux DynamoDB Kinesis Adapter pour traiter les enregistrements de flux Utilisation de Flux DynamoDB Kinesis Adapter pour traiter les enregistrements de flux L'utilisation de Kinesis Adapter est la solution recommandée pour consommer les flux à partir de DynamoDB. L'API Flux DynamoDB est intentionnellement similaire à celle d'Amazon Kinesis Streams, un service de traitement en temps réel de diffusion en continu des données à une échelle massive. Dans les deux services, les flux de données sont composés de partitions, qui sont des conteneurs pour les enregistrements de flux. Les API des deux services contiennent les actions ListStreams, DescribeStream, GetShards et GetShardIterator. (Même si ces actions Flux DynamoDB sont similaires à leurs homologues dans Amazon Kinesis Streams, elles ne sont pas identiques à 100 %.) Vous pouvez écrire des applications pour Amazon Kinesis Streams à l'aide de l'Amazon Kinesis Client Library (KCL). Le KCL simplifie le codage en fournissant des abstractions utiles au-dessus de l'API de bas niveau Amazon Kinesis Streams. Pour plus d'informations sur le KCL, consultez Amazon Kinesis Developer Guide. En tant qu'utilisateur Flux DynamoDB, vous pouvez optimiser les modèles de conception disponibles au sein du KCL pour traiter les partitions et enregistrements de flux Flux DynamoDB. Pour ce faire, vous utilisez le Flux DynamoDB Kinesis Adapter. Le Kinesis implémente l'interface Amazon Kinesis Streams, afin que le KCL puisse être utilisé pour la consommation et le traitement des enregistrements de Flux DynamoDB. Le schéma suivant illustre comment ces bibliothèques interagissent entre elles. API Version 2012-08-10 435 Amazon DynamoDB Manuel du développeur Utilisation de Flux DynamoDB Kinesis Adapter pour traiter les enregistrements de flux Avec le Flux DynamoDB Kinesis Adapter en place, vous pouvez commencer à développer sur l'interface KCL, avec les appels d'API transmis en toute transparence au point de terminaison Flux DynamoDB. Lorsque votre application démarre, elle appelle le KCL pour instancier un travail. Vous devez fournir le travail avec les informations de configuration pour l'application, tels que le descripteur de flux et les informations d'identification AWS, et le nom d'une classe de jeu de processeur d'enregistrements que vous fournissez. Tandis qu'il s'exécute le code dans le processeur d'enregistrements, le travail effectue les tâches suivantes : • • • • • Se connecte au flux. Enumère les partitions au sein du flux. Coordonne les associations de partition avec les autres travaux (le cas échéant). Instancie un processeur d'enregistrements pour chaque partition qu'il gère. Extrait les enregistrements du flux. • Pousse les enregistrements sur le processeur d'enregistrements correspondant. API Version 2012-08-10 436 Amazon DynamoDB Manuel du développeur Utilisation de Flux DynamoDB Kinesis Adapter pour traiter les enregistrements de flux • Contrôle les enregistrements traités. • Equilibre les associations partition-travail lorsque le nombre d'instances de travail change. • Equilibre les associations partition-travail lorsque les partitions sont fractionnées. Note Pour une description des concepts KCL mentionnés ci-dessus, consultez Développement des consommateurs Amazon Kinesis à l'aide de la bibliothèque cliente Amazon Kinesis dans le manuel Amazon Kinesis Developer Guide. Procédure pas à pas : Flux DynamoDB Kinesis Adapter Cette section est la procédure pas à pas d'une application Java qui utilise la bibliothèque cliente Kinesis et le Flux DynamoDB Kinesis Adapter. L'application illustre un exemple de la réplication de données, où l'activité d'écriture d'une table est appliquée à une seconde table, avec le contenu des deux tables demeurant synchronisé. Pour le code source, consultez Programme complet : Flux DynamoDB Kinesis Adapter (p. 440). Le programme exécute les tâches suivantes : 1. Crée deux tables DynamoDB nommées KCL-Demo-src et KCL-Demo-dst. Chacune de ces tables dispose d'un flux activé sur elle-même. 2. Génère une activité de mise à jour de la table source en ajoutant, mettant à jour et supprimant des éléments. Cela entraîne l'écriture des données sur le flux de la table. 3. Lit les enregistrements du flux, les reconstruit en tant que demandes DynamoDB et applique les demandes sur la table de destination. 4. Analyse les tables source et de destination afin de s'assurer que leurs contenus sont identiques. 5. Elimine en supprimant les tables. Ces étapes sont décrites dans les sections suivantes et l'application complète est illustrée à la fin de la procédure pas à pas. Rubriques • Etape 1 : Créer les tables DynamoDB (p. 437) • Etape 2 : Générer une activité de mise à jour de la table source (p. 438) • Etape 3 : Traiter le flux (p. 438) • Etape 4 : S'assurer que les deux tables ont un contenu identique (p. 439) • Etape 5 : Nettoyage (p. 440) • Programme complet : Flux DynamoDB Kinesis Adapter (p. 440) Etape 1 : Créer les tables DynamoDB La première étape consiste à créer deux tables DynamoDB : une table source et une table destination. Le StreamViewType sur le flux de la table source est NEW_IMAGE, ce qui signifie que chaque fois qu'un élément est modifié dans la table, l'image « après » de l'élément est écrite dans le flux. De cette manière, le flux assure le suivi des toute l'activité d'écriture sur la table. L'extrait de code suivant illustre le code utilisé pour la création des deux tables. java.util.List<AttributeDefinition> attributeDefinitions = new ArrayList<AttributeDefinition>(); API Version 2012-08-10 437 Amazon DynamoDB Manuel du développeur Utilisation de Flux DynamoDB Kinesis Adapter pour traiter les enregistrements de flux attributeDefinitions.add(new AttributeDefinition().withAttributeName("Id").withAttributeType("N")); java.util.List<KeySchemaElement> keySchema = new ArrayList<KeySchemaElement>(); keySchema.add(new KeySchemaElement().withAttributeName("Id").withKeyType(KeyType.HASH)); Partition key // ProvisionedThroughput provisionedThroughput = new ProvisionedThroughput() .withReadCapacityUnits(2L).withWriteCapacityUnits(2L); StreamSpecification streamSpecification = new StreamSpecification(); streamSpecification.setStreamEnabled(true); streamSpecification.setStreamViewType(StreamViewType.NEW_IMAGE); CreateTableRequest createTableRequest = new CreateTableRequest() .withTableName(tableName) .withAttributeDefinitions(attributeDefinitions) .withKeySchema(keySchema) .withProvisionedThroughput(provisionedThroughput) .withStreamSpecification(streamSpecification); Etape 2 : Générer une activité de mise à jour de la table source L'étape suivante consiste à générer une activité d'écriture sur la table source. Tandis que cette activité a lieu, le flux de la table source est aussi mis à jour en temps quasi réel. L'application définit une classe d'assistance avec les méthodes qui appellent les actions d'API PutItem, UpdateItem et DeleteItem pour écrire les données. L'extrait de code suivant montre comment ces méthodes sont utilisées. StreamsAdapterDemoHelper.putItem(dynamoDBClient, tableName, "101", "test1"); StreamsAdapterDemoHelper.updateItem(dynamoDBClient, tableName, "101", "test2"); StreamsAdapterDemoHelper.deleteItem(dynamoDBClient, tableName, "101"); StreamsAdapterDemoHelper.putItem(dynamoDBClient, tableName, "102", "demo3"); StreamsAdapterDemoHelper.updateItem(dynamoDBClient, tableName, "102", "demo4"); StreamsAdapterDemoHelper.deleteItem(dynamoDBClient, tableName, "102"); Etape 3 : Traiter le flux Maintenant le programme commence à traiter le flux. Le Flux DynamoDB Kinesis Adapter agit comme couche transparente entre le KCL et le point de terminaison Flux DynamoDB, afin que le code puisse entièrement exploiter KCL plutôt que d'avoir à procéder à des appels Flux DynamoDB de bas niveau. Le programme effectue les tâches suivantes : • Il définit une classe de processeur d'enregistrements, StreamsRecordProcessor, avec des méthodes conformes à la définition de l'interface KCL : initialize, processRecords et shutdown. La méthode processRecords contient la logique nécessaire pour lire à partir du flux de la table source et écrire dans la table de destination. • Il définit une fabrique de classe pour la classe de processeur d'enregistrements (StreamsRecordProcessorFactory). Cette action est obligatoire pour les programmes Java qui utilisent le KCL. • Il instancie un nouveau KCL Worker, associé à la fabrique de classe. API Version 2012-08-10 438 Amazon DynamoDB Manuel du développeur Utilisation de Flux DynamoDB Kinesis Adapter pour traiter les enregistrements de flux • Il arrête le Worker lorsque le traitement des enregistrements est terminé. Pour en savoir plus sur la définition d'interface KCL, consultez Développement des consommateurs Amazon Kinesis à l'aide de la bibliothèque cliente Amazon Kinesis dans le manuel Amazon Kinesis Developer Guide. L'extrait de code suivant illustre la boucle principale dans StreamsRecordProcessor. L'instruction case détermine l'action à exécuter, en fonction de l'OperationType qui s'affiche dans l'enregistrement de flux. for(Record record : records) { String data = new String(record.getData().array(), Charset.forName("UTF-8")); System.out.println(data); if(record instanceof RecordAdapter) { com.amazonaws.services.dynamodbv2.model.Record streamRecord = ((RecordAdapter) record).getInternalObject(); switch(streamRecord.getEventName()) { case "INSERT" : case "MODIFY" : StreamsAdapterDemoHelper.putItem(dynamoDBClient, tableName, streamRecord.getDynamodb().getNewImage()); break; case "REMOVE" : StreamsAdapterDemoHelper.deleteItem(dynamoDBClient, tableName, streamRecord.getDynamodb().getKeys().get("Id").getN()); } } checkpointCounter += 1; if(checkpointCounter % 10 == 0) { try { checkpointer.checkpoint(); } catch(Exception e) { e.printStackTrace(); } } } } Etape 4 : S'assurer que les deux tables ont un contenu identique A ce stade, le contenu des tables source et destination est synchronisé. L'application émet des demandes Scan sur les deux tables afin de vérifier que leurs contenus sont, en fait, identiques. La classe DemoHelper contient une méthode ScanTable qui appelle l'API de bas niveau Scan. L'extrait de code suivant en illustre l'utilisation. if(StreamsAdapterDemoHelper.scanTable(dynamoDBClient, srcTable).getItems().equals(StreamsAdapterDemoHelper.scanTable(dynamoDBClient, destTable).getItems())) { System.out.println("Scan result is equal."); } else { System.out.println("Tables are different!"); } API Version 2012-08-10 439 Amazon DynamoDB Manuel du développeur Utilisation de Flux DynamoDB Kinesis Adapter pour traiter les enregistrements de flux Etape 5 : Nettoyage Comme la démonstration est terminée, l'application supprime les tables source et destination. Consultez l'extrait de code suivant. Même après que les tables sont supprimées, leurs flux demeurent accessibles 24 heures, délai audelà duquel ils sont automatiquement supprimés. dynamoDBClient.deleteTable(new DeleteTableRequest().withTableName(srcTable)); dynamoDBClient.deleteTable(new DeleteTableRequest().withTableName(destTable)); Programme complet : Flux DynamoDB Kinesis Adapter Voici le programme Java complet qui effectue les tâches décrites dans la procédure pas à pas. Lorsque vous l'exécutez, vous devez visualiser une sortie similaire à ce qui suit : Creating table KCL-Demo-src Creating table KCL-Demo-dest Table is active. Creating worker for stream: arn:aws:dynamodb:us-west-2:111122223333:table/ KCL-Demo-src/stream/2015-05-19T22:48:56.601 Starting worker... Scan result is equal. Done. Important Pour exécuter ce programme, veillez à ce que l'application cliente ait accès à DynamoDB et CloudWatch à l'aide des stratégies. Pour plus d'informations, consultez Utilisation des stratégies basées sur l'identité (stratégies IAM) pour Amazon DynamoDB (p. 471). Le code source se compose de quatre fichiers .java. StreamsAdapterDemo.java // Copyright 2012-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. // Licensed under the Apache License, Version 2.0. package com.amazonaws.codesamples.gsg; import com.amazonaws.ClientConfiguration; import com.amazonaws.auth.AWSCredentialsProvider; import com.amazonaws.auth.profile.ProfileCredentialsProvider; import com.amazonaws.services.cloudwatch.AmazonCloudWatchClient; import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient; import com.amazonaws.services.dynamodbv2.model.DeleteTableRequest; import com.amazonaws.services.dynamodbv2.model.DescribeTableResult; import com.amazonaws.services.dynamodbv2.streamsadapter.AmazonDynamoDBStreamsAdapterClient; import com.amazonaws.services.kinesis.clientlibrary.interfaces.IRecordProcessorFactory; import com.amazonaws.services.kinesis.clientlibrary.lib.worker.InitialPositionInStream; API Version 2012-08-10 440 Amazon DynamoDB Manuel du développeur Utilisation de Flux DynamoDB Kinesis Adapter pour traiter les enregistrements de flux import com.amazonaws.services.kinesis.clientlibrary.lib.worker.KinesisClientLibConfiguration; import com.amazonaws.services.kinesis.clientlibrary.lib.worker.Worker; public class StreamsAdapterDemo { private static Worker worker; private static KinesisClientLibConfiguration workerConfig; private static IRecordProcessorFactory recordProcessorFactory; private static AmazonDynamoDBStreamsAdapterClient adapterClient; private static AWSCredentialsProvider streamsCredentials; private static AmazonDynamoDBClient dynamoDBClient; private static AWSCredentialsProvider dynamoDBCredentials; private static AmazonCloudWatchClient cloudWatchClient; private private private private private static static static static static String String String String String serviceName = "dynamodb"; dynamodbEndpoint = "DYNAMODB_ENDPOINT_GOES_HERE"; streamsEndpoint = "STREAMS_ENDPOINT_GOES_HERE"; tablePrefix = "KCL-Demo"; streamArn; /** * @param args */ public static void main(String[] args) throws Exception { System.out.println("Starting demo..."); String srcTable = tablePrefix + "-src"; String destTable = tablePrefix + "-dest"; streamsCredentials = new ProfileCredentialsProvider(); dynamoDBCredentials = new ProfileCredentialsProvider(); recordProcessorFactory = new StreamsRecordProcessorFactory(dynamoDBCredentials, dynamodbEndpoint, serviceName, destTable); /* ===== REQUIRED ===== * Users will have to explicitly instantiate and configure the adapter, then pass it to * the KCL worker. */ adapterClient = new AmazonDynamoDBStreamsAdapterClient(streamsCredentials, new ClientConfiguration()); adapterClient.setEndpoint(streamsEndpoint); dynamoDBClient = new AmazonDynamoDBClient(dynamoDBCredentials, new ClientConfiguration()); dynamoDBClient.setEndpoint(dynamodbEndpoint); cloudWatchClient = new AmazonCloudWatchClient(dynamoDBCredentials, new ClientConfiguration()); setUpTables(); API Version 2012-08-10 441 Amazon DynamoDB Manuel du développeur Utilisation de Flux DynamoDB Kinesis Adapter pour traiter les enregistrements de flux workerConfig = new KinesisClientLibConfiguration("streams-adapterdemo", streamArn, streamsCredentials, "streams-demo-worker") .withMaxRecords(1000) .withIdleTimeBetweenReadsInMillis(500) .withInitialPositionInStream(InitialPositionInStream.TRIM_HORIZON); System.out.println("Creating worker for stream: " + streamArn); worker = new Worker(recordProcessorFactory, workerConfig, adapterClient, dynamoDBClient, cloudWatchClient); System.out.println("Starting worker..."); Thread t = new Thread(worker); t.start(); Thread.sleep(25000); worker.shutdown(); t.join(); if(StreamsAdapterDemoHelper.scanTable(dynamoDBClient, srcTable).getItems().equals(StreamsAdapterDemoHelper.scanTable(dynamoDBClient, destTable).getItems())) { System.out.println("Scan result is equal."); } else { System.out.println("Tables are different!"); } System.out.println("Done."); cleanupAndExit(0); } private static void setUpTables() { String srcTable = tablePrefix + "-src"; String destTable = tablePrefix + "-dest"; streamArn = StreamsAdapterDemoHelper.createTable(dynamoDBClient, srcTable); StreamsAdapterDemoHelper.createTable(dynamoDBClient, destTable); awaitTableCreation(srcTable); performOps(srcTable); } private static void awaitTableCreation(String tableName) { Integer retries = 0; Boolean created = false; while(!created && retries < 100) { DescribeTableResult result = StreamsAdapterDemoHelper.describeTable(dynamoDBClient, tableName); created = result.getTable().getTableStatus().equals("ACTIVE"); if (created) { System.out.println("Table is active."); return; } else { retries++; try { Thread.sleep(1000); } catch(InterruptedException e) { // do nothing API Version 2012-08-10 442 Amazon DynamoDB Manuel du développeur Utilisation de Flux DynamoDB Kinesis Adapter pour traiter les enregistrements de flux } } } System.out.println("Timeout after table creation. Exiting..."); cleanupAndExit(1); } private static void performOps(String tableName) { StreamsAdapterDemoHelper.putItem(dynamoDBClient, tableName, "101", "test1"); StreamsAdapterDemoHelper.updateItem(dynamoDBClient, tableName, "101", "test2"); StreamsAdapterDemoHelper.deleteItem(dynamoDBClient, tableName, "101"); StreamsAdapterDemoHelper.putItem(dynamoDBClient, tableName, "102", "demo3"); StreamsAdapterDemoHelper.updateItem(dynamoDBClient, tableName, "102", "demo4"); StreamsAdapterDemoHelper.deleteItem(dynamoDBClient, tableName, "102"); } private static void cleanupAndExit(Integer returnValue) { String srcTable = tablePrefix + "-src"; String destTable = tablePrefix + "-dest"; dynamoDBClient.deleteTable(new DeleteTableRequest().withTableName(srcTable)); dynamoDBClient.deleteTable(new DeleteTableRequest().withTableName(destTable)); System.exit(returnValue); } } StreamsRecordProcessor.java // Copyright 2012-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. // Licensed under the Apache License, Version 2.0. package com.amazonaws.codesamples.gsg; import java.nio.charset.Charset; import java.util.List; import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient; import com.amazonaws.services.dynamodbv2.streamsadapter.model.RecordAdapter; import com.amazonaws.services.kinesis.clientlibrary.interfaces.IRecordProcessor; import com.amazonaws.services.kinesis.clientlibrary.interfaces.IRecordProcessorCheckpointer; import com.amazonaws.services.kinesis.clientlibrary.types.ShutdownReason; import com.amazonaws.services.kinesis.model.Record; public class StreamsRecordProcessor implements IRecordProcessor { private Integer checkpointCounter; private final AmazonDynamoDBClient dynamoDBClient; API Version 2012-08-10 443 Amazon DynamoDB Manuel du développeur Utilisation de Flux DynamoDB Kinesis Adapter pour traiter les enregistrements de flux private final String tableName; public StreamsRecordProcessor(AmazonDynamoDBClient dynamoDBClient, String tableName) { this.dynamoDBClient = dynamoDBClient; this.tableName = tableName; } @Override public void initialize(String shardId) { checkpointCounter = 0; } @Override public void processRecords(List<Record> records, IRecordProcessorCheckpointer checkpointer) { for(Record record : records) { String data = new String(record.getData().array(), Charset.forName("UTF-8")); System.out.println(data); if(record instanceof RecordAdapter) { com.amazonaws.services.dynamodbv2.model.Record streamRecord = ((RecordAdapter) record).getInternalObject(); switch(streamRecord.getEventName()) { case "INSERT" : case "MODIFY" : StreamsAdapterDemoHelper.putItem(dynamoDBClient, tableName, streamRecord.getDynamodb().getNewImage()); break; case "REMOVE" : StreamsAdapterDemoHelper.deleteItem(dynamoDBClient, tableName, streamRecord.getDynamodb().getKeys().get("Id").getN()); } } checkpointCounter += 1; if(checkpointCounter % 10 == 0) { try { checkpointer.checkpoint(); } catch(Exception e) { e.printStackTrace(); } } } } @Override public void shutdown(IRecordProcessorCheckpointer checkpointer, ShutdownReason reason) { if(reason == ShutdownReason.TERMINATE) { try { checkpointer.checkpoint(); } catch (Exception e) { e.printStackTrace(); } } } API Version 2012-08-10 444 Amazon DynamoDB Manuel du développeur Utilisation de Flux DynamoDB Kinesis Adapter pour traiter les enregistrements de flux } StreamsRecordProcessorFactory.java // Copyright 2012-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. // Licensed under the Apache License, Version 2.0. package com.amazonaws.codesamples.gsg; import com.amazonaws.ClientConfiguration; import com.amazonaws.auth.AWSCredentialsProvider; import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient; import com.amazonaws.services.kinesis.clientlibrary.interfaces.IRecordProcessor; import com.amazonaws.services.kinesis.clientlibrary.interfaces.IRecordProcessorFactory; public class StreamsRecordProcessorFactory implements IRecordProcessorFactory { private final AWSCredentialsProvider dynamoDBCredentials; private final String dynamoDBEndpoint; private final String tableName; public StreamsRecordProcessorFactory( AWSCredentialsProvider dynamoDBCredentials, String dynamoDBEndpoint, String serviceName, String tableName) { this.dynamoDBCredentials = dynamoDBCredentials; this.dynamoDBEndpoint = dynamoDBEndpoint; this.tableName = tableName; } @Override public IRecordProcessor createProcessor() { AmazonDynamoDBClient dynamoDBClient = new AmazonDynamoDBClient(dynamoDBCredentials, new ClientConfiguration()); dynamoDBClient.setEndpoint(dynamoDBEndpoint); return new StreamsRecordProcessor(dynamoDBClient, tableName); } } StreamsAdapterDemoHelper.java // Copyright 2012-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. // Licensed under the Apache License, Version 2.0. package com.amazonaws.codesamples.gsg; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient; import com.amazonaws.services.dynamodbv2.model.AttributeAction; import com.amazonaws.services.dynamodbv2.model.AttributeDefinition; API Version 2012-08-10 445 Amazon DynamoDB Manuel du développeur Utilisation de Flux DynamoDB Kinesis Adapter pour traiter les enregistrements de flux import import import import import import import import import import import import import import import import import com.amazonaws.services.dynamodbv2.model.AttributeValue; com.amazonaws.services.dynamodbv2.model.AttributeValueUpdate; com.amazonaws.services.dynamodbv2.model.CreateTableRequest; com.amazonaws.services.dynamodbv2.model.CreateTableResult; com.amazonaws.services.dynamodbv2.model.DeleteItemRequest; com.amazonaws.services.dynamodbv2.model.DescribeTableRequest; com.amazonaws.services.dynamodbv2.model.DescribeTableResult; com.amazonaws.services.dynamodbv2.model.KeySchemaElement; com.amazonaws.services.dynamodbv2.model.KeyType; com.amazonaws.services.dynamodbv2.model.ProvisionedThroughput; com.amazonaws.services.dynamodbv2.model.PutItemRequest; com.amazonaws.services.dynamodbv2.model.ResourceInUseException; com.amazonaws.services.dynamodbv2.model.ScanRequest; com.amazonaws.services.dynamodbv2.model.ScanResult; com.amazonaws.services.dynamodbv2.model.StreamSpecification; com.amazonaws.services.dynamodbv2.model.StreamViewType; com.amazonaws.services.dynamodbv2.model.UpdateItemRequest; public class StreamsAdapterDemoHelper { /** * @return StreamArn */ public static String createTable(AmazonDynamoDBClient client, String tableName) { java.util.List<AttributeDefinition> attributeDefinitions = new ArrayList<AttributeDefinition>(); attributeDefinitions.add(new AttributeDefinition().withAttributeName("Id").withAttributeType("N")); java.util.List<KeySchemaElement> keySchema = new ArrayList<KeySchemaElement>(); keySchema.add(new KeySchemaElement().withAttributeName("Id").withKeyType(KeyType.HASH)); // Partition key ProvisionedThroughput provisionedThroughput = new ProvisionedThroughput() .withReadCapacityUnits(2L).withWriteCapacityUnits(2L); StreamSpecification streamSpecification = new StreamSpecification(); streamSpecification.setStreamEnabled(true); streamSpecification.setStreamViewType(StreamViewType.NEW_IMAGE); CreateTableRequest createTableRequest = new CreateTableRequest() .withTableName(tableName) .withAttributeDefinitions(attributeDefinitions) .withKeySchema(keySchema) .withProvisionedThroughput(provisionedThroughput) .withStreamSpecification(streamSpecification); try { System.out.println("Creating table " + tableName); CreateTableResult result = client.createTable(createTableRequest); return result.getTableDescription().getLatestStreamArn(); } catch(ResourceInUseException e) { System.out.println("Table already exists."); API Version 2012-08-10 446 Amazon DynamoDB Manuel du développeur Utilisation de Flux DynamoDB Kinesis Adapter pour traiter les enregistrements de flux return describeTable(client, tableName).getTable().getLatestStreamArn(); } } public static DescribeTableResult describeTable(AmazonDynamoDBClient client, String tableName) { return client.describeTable(new DescribeTableRequest().withTableName(tableName)); } public static ScanResult scanTable(AmazonDynamoDBClient client, String tableName) { return client.scan(new ScanRequest().withTableName(tableName)); } public static void putItem(AmazonDynamoDBClient client, String tableName, String id, String val) { java.util.Map<String, AttributeValue> item = new HashMap<String, AttributeValue>(); item.put("Id", new AttributeValue().withN(id)); item.put("attribute-1", new AttributeValue().withS(val)); PutItemRequest putItemRequest = new PutItemRequest() .withTableName(tableName) .withItem(item); client.putItem(putItemRequest); } public static void putItem(AmazonDynamoDBClient client, String tableName, java.util.Map<String, AttributeValue> items) { PutItemRequest putItemRequest = new PutItemRequest() .withTableName(tableName) .withItem(items); client.putItem(putItemRequest); } public static void updateItem(AmazonDynamoDBClient client, String tableName, String id, String val) { java.util.Map<String, AttributeValue> key = new HashMap<String, AttributeValue>(); key.put("Id", new AttributeValue().withN(id)); Map<String, AttributeValueUpdate> attributeUpdates = new HashMap<String, AttributeValueUpdate>(); AttributeValueUpdate update = new AttributeValueUpdate() .withAction(AttributeAction.PUT) .withValue(new AttributeValue().withS(val)); attributeUpdates.put("attribute-2", update); UpdateItemRequest updateItemRequest = new UpdateItemRequest() .withTableName(tableName) .withKey(key) .withAttributeUpdates(attributeUpdates); client.updateItem(updateItemRequest); } public static void deleteItem(AmazonDynamoDBClient client, String tableName, String id) { API Version 2012-08-10 447 Amazon DynamoDB Manuel du développeur Procédure pas à pas : API de bas niveau Flux DynamoDB java.util.Map<String, AttributeValue> key = new HashMap<String, AttributeValue>(); key.put("Id", new AttributeValue().withN(id)); DeleteItemRequest deleteItemRequest = new DeleteItemRequest() .withTableName(tableName) .withKey(key); client.deleteItem(deleteItemRequest); } } Procédure pas à pas : API de bas niveau Flux DynamoDB Cette section décrit la procédure pas à pas d'un programme Java qui affiche Flux DynamoDB en action. Pour le code source, consultez Programme complet : API Flux DynamoDB de bas niveau (p. 451). Le programme exécute les tâches suivantes : 1. Création d'une table DynamoDB avec un flux activé. 2. Description des paramètres de flux de cette table. 3. Modification des données de la table. 4. Description des partitions du flux. 5. Lecture des enregistrements de flux des partitions. 6. Nettoyage. Note Ce code ne gère pas toutes les exceptions et ne fonctionne pas de manière fiable dans les conditions de trafic intense. La solution recommandée pour utiliser les enregistrements Stream de DynamoDB s'effectue via la carte Kinesis Adapter à l'aide de la bibliothèque KCL (Amazon Kinesis Client Library), comme décrit dans Utilisation de Flux DynamoDB Kinesis Adapter pour traiter les enregistrements de flux (p. 435). Ces étapes sont décrites dans les sections suivantes et l'application complète est illustrée à la fin de la procédure pas à pas. Rubriques • Etape 1 : Créer une table avec un flux activé (p. 449) • Etape 2 : Décrire les paramètres de flux de la table (p. 449) • Etape 3 : Modifier les données de la table (p. 449) • Etape 4 : Décrire les partitions du flux (p. 450) • Etape 5 : Lire les enregistrements de flux (p. 450) • Etape 6 : Nettoyage (p. 451) • Programme complet : API Flux DynamoDB de bas niveau (p. 451) API Version 2012-08-10 448 Amazon DynamoDB Manuel du développeur Procédure pas à pas : API de bas niveau Flux DynamoDB Etape 1 : Créer une table avec un flux activé La première étape consiste à créer une table dans DynamoDB, comme dans l'extrait de code suivant. La table possède un flux activé, ce qui permettra de saisir les NEW_AND_OLD_IMAGES de chaque élément modifié. ArrayList<AttributeDefinition> attributeDefinitions = new ArrayList<AttributeDefinition>(); attributeDefinitions.add(new AttributeDefinition() .withAttributeName("Id") .withAttributeType("N")); ArrayList<KeySchemaElement> keySchema = new ArrayList<KeySchemaElement>(); keySchema.add(new KeySchemaElement() .withAttributeName("Id") .withKeyType(KeyType.HASH)); //Partition key StreamSpecification streamSpecification = new StreamSpecification(); streamSpecification.setStreamEnabled(true); streamSpecification.setStreamViewType(StreamViewType.NEW_AND_OLD_IMAGES); CreateTableRequest createTableRequest = new CreateTableRequest() .withTableName(tableName) .withKeySchema(keySchema) .withAttributeDefinitions(attributeDefinitions) .withProvisionedThroughput(new ProvisionedThroughput() .withReadCapacityUnits(1L) .withWriteCapacityUnits(1L)) .withStreamSpecification(streamSpecification); Etape 2 : Décrire les paramètres de flux de la table L'API DescribeTable vous permet d'afficher les paramètres de flux actuels d'une table. L'extrait de code suivant permet de confirmer que le flux est activé et qu'il capture les données appropriées. DescribeTableResult describeTableResult = dynamoDBClient.describeTable(tableName); String myStreamArn = describeTableResult.getTable().getLatestStreamArn(); StreamSpecification myStreamSpec = describeTableResult.getTable().getStreamSpecification(); System.out.println("Current stream ARN for " + tableName + ": "+ myStreamArn); System.out.println("Stream enabled: "+ myStreamSpec.getStreamEnabled()); System.out.println("Update view type: "+ myStreamSpec.getStreamViewType()); Etape 3 : Modifier les données de la table L'étape suivante consiste à apporter des modifications aux données de la table. L'extrait de code suivant ajoute un nouvel élément à la table, met à jour un attribut de l'élément, puis supprime l'élément. // Add a new item API Version 2012-08-10 449 Amazon DynamoDB Manuel du développeur Procédure pas à pas : API de bas niveau Flux DynamoDB int numChanges = 0; System.out.println("Making some changes to table data"); Map<String, AttributeValue> item = new HashMap<String, AttributeValue>(); item.put("Id", new AttributeValue().withN("101")); item.put("Message", new AttributeValue().withS("New item!")); dynamoDBClient.putItem(tableName, item); numChanges++; // Update the item Map<String, AttributeValue> key = new HashMap<String, AttributeValue>(); key.put("Id", new AttributeValue().withN("101")); Map<String, AttributeValueUpdate> attributeUpdates = new HashMap<String, AttributeValueUpdate>(); attributeUpdates.put("Message", new AttributeValueUpdate() .withAction(AttributeAction.PUT) .withValue(new AttributeValue().withS("This item has changed"))); dynamoDBClient.updateItem(tableName, key, attributeUpdates); numChanges++; // Delete the item dynamoDBClient.deleteItem(tableName, key); numChanges++; Etape 4 : Décrire les partitions du flux Les modifications des données de la table entraînent l'écriture des enregistrements du flux dans le flux de la table. Dans Etape 2 : Décrire les paramètres de flux de la table (p. 449), nous avons déterminé l'ARN du flux actuel et l'avons affecté à la variable myStreamArn. Nous pouvons l'utiliser avec l'action DescribeStream pour obtenir les partitions du flux. Etant donné que nous n'avons pas modifié beaucoup de données dans la table DynamoDB, il n'y aura qu'une partition dans la liste. L'extrait de code suivant montre comment obtenir ces informations. DescribeStreamResult describeStreamResult = streamsClient.describeStream(new DescribeStreamRequest() .withStreamArn(myStreamArn)); String streamArn = describeStreamResult.getStreamDescription().getStreamArn(); List<Shard> shards = describeStreamResult.getStreamDescription().getShards(); Etape 5 : Lire les enregistrements de flux Pour chaque partition de la liste, nous obtenons un itérateur de partition, que nous utilisons ensuite pour obtenir les enregistrements de flux et les afficher. L'extrait de code suivant utilise une boucle pour traiter la liste des partitions, même s'il n'y a qu'une seule partition. for (Shard shard : shards) { String shardId = shard.getShardId(); System.out.println( API Version 2012-08-10 450 Amazon DynamoDB Manuel du développeur Procédure pas à pas : API de bas niveau Flux DynamoDB "Processing " + shardId + " from stream "+ streamArn); // Get an iterator for the current shard GetShardIteratorRequest getShardIteratorRequest = new GetShardIteratorRequest() .withStreamArn(myStreamArn) .withShardId(shardId) .withShardIteratorType(ShardIteratorType.TRIM_HORIZON); GetShardIteratorResult getShardIteratorResult = streamsClient.getShardIterator(getShardIteratorRequest); String nextItr = getShardIteratorResult.getShardIterator(); while (nextItr != null && numChanges > 0) { // Use the iterator to read the data records from the shard GetRecordsResult getRecordsResult = streamsClient.getRecords(new GetRecordsRequest(). withShardIterator(nextItr)); List<Record> records = getRecordsResult.getRecords(); System.out.println("Getting records..."); for (Record record : records) { System.out.println(record); numChanges--; } nextItr = getRecordsResult.getNextShardIterator(); } } Etape 6 : Nettoyage La démonstration étant terminée, nous pouvons supprimer la table. Notez que le flux de données associé à la table demeure accessible en lecture, même si la table est supprimée. Le flux est automatiquement supprimé après 24 heures. dynamoDBClient.deleteTable(tableName); Programme complet : API Flux DynamoDB de bas niveau Voici un programme Java complet qui effectue les tâches décrites dans la procédure pas à pas. Lorsque vous l'exécutez, vous voyez chaque enregistrement de flux dans sa totalité : Issuing CreateTable request for TestTableForStreams Waiting for TestTableForStreams to be created... Current stream ARN for TestTableForStreams: arn:aws:dynamodb:uswest-2:111122223333:table/TestTableForStreams/stream/2015-05-19T23:03:50.641 Stream enabled: true Update view type: NEW_AND_OLD_IMAGES Making some changes to table data Processing shardId-00000001415575208348-98d954b6 from stream arn:aws:dynamodb:us-west-2:111122223333:table/TestTableForStreams/ stream/2015-05-19T23:03:50.641 Getting records... {eventID: 7f6ba6f037b9fdd5a43af22cb726f0cd,eventName: INSERT,eventVersion: 1.0,eventSource: aws:dynamodb,awsRegion: us-west-2,dynamodb: {Keys: {Id={N: API Version 2012-08-10 451 Amazon DynamoDB Manuel du développeur Procédure pas à pas : API de bas niveau Flux DynamoDB 101,}},NewImage: {Message={S: New item!,}, Id={N: 101,}},SequenceNumber: 100000000000000507337,SizeBytes: 26,StreamViewType: NEW_AND_OLD_IMAGES}} {eventID: 8f546e78ab6183d1441c0680ec03dcfc,eventName: MODIFY,eventVersion: 1.0,eventSource: aws:dynamodb,awsRegion: us-west-2,dynamodb: {Keys: {Id={N: 101,}},NewImage: {Message={S: This item has changed,}, Id={N: 101,}},OldImage: {Message={S: New item!,}, Id={N: 101,}},SequenceNumber: 200000000000000507338,SizeBytes: 59,StreamViewType: NEW_AND_OLD_IMAGES}} {eventID: d9bb1e7a1684dfd66c8a3fb8ca2f6977,eventName: REMOVE,eventVersion: 1.0,eventSource: aws:dynamodb,awsRegion: us-west-2,dynamodb: {Keys: {Id={N: 101,}},OldImage: {Message={S: This item has changed,}, Id={N: 101,}},SequenceNumber: 300000000000000507339,SizeBytes: 38,StreamViewType: NEW_AND_OLD_IMAGES}} Deleting the table... Demo complete // Copyright 2012-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved. // Licensed under the Apache License, Version 2.0. package com.amazonaws.codesamples.gsg; import import import import java.util.ArrayList; java.util.HashMap; java.util.List; java.util.Map; import import import import import import import import import import import import import import import import import import import import import import import import com.amazonaws.auth.profile.ProfileCredentialsProvider; com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient; com.amazonaws.services.dynamodbv2.AmazonDynamoDBStreamsClient; com.amazonaws.services.dynamodbv2.model.AttributeAction; com.amazonaws.services.dynamodbv2.model.AttributeDefinition; com.amazonaws.services.dynamodbv2.model.AttributeValue; com.amazonaws.services.dynamodbv2.model.AttributeValueUpdate; com.amazonaws.services.dynamodbv2.model.CreateTableRequest; com.amazonaws.services.dynamodbv2.model.DescribeStreamRequest; com.amazonaws.services.dynamodbv2.model.DescribeStreamResult; com.amazonaws.services.dynamodbv2.model.DescribeTableResult; com.amazonaws.services.dynamodbv2.model.GetRecordsRequest; com.amazonaws.services.dynamodbv2.model.GetRecordsResult; com.amazonaws.services.dynamodbv2.model.GetShardIteratorRequest; com.amazonaws.services.dynamodbv2.model.GetShardIteratorResult; com.amazonaws.services.dynamodbv2.model.KeySchemaElement; com.amazonaws.services.dynamodbv2.model.KeyType; com.amazonaws.services.dynamodbv2.model.ProvisionedThroughput; com.amazonaws.services.dynamodbv2.model.Record; com.amazonaws.services.dynamodbv2.model.Shard; com.amazonaws.services.dynamodbv2.model.ShardIteratorType; com.amazonaws.services.dynamodbv2.model.StreamSpecification; com.amazonaws.services.dynamodbv2.model.StreamViewType; com.amazonaws.services.dynamodbv2.util.Tables; public class StreamsLowLevelDemo { private static AmazonDynamoDBClient dynamoDBClient = new AmazonDynamoDBClient(new ProfileCredentialsProvider()); private static AmazonDynamoDBStreamsClient streamsClient = new AmazonDynamoDBStreamsClient(new ProfileCredentialsProvider()); API Version 2012-08-10 452 Amazon DynamoDB Manuel du développeur Procédure pas à pas : API de bas niveau Flux DynamoDB public static void main(String args[]) { dynamoDBClient.setEndpoint("DYNAMODB_ENDPOINT_GOES_HERE"); streamsClient.setEndpoint("STREAMS_ENDPOINT_GOES_HERE"); // Create the table String tableName = "TestTableForStreams"; ArrayList<AttributeDefinition> attributeDefinitions = new ArrayList<AttributeDefinition>(); attributeDefinitions.add(new AttributeDefinition() .withAttributeName("Id") .withAttributeType("N")); ArrayList<KeySchemaElement> keySchema = new ArrayList<KeySchemaElement>(); keySchema.add(new KeySchemaElement() .withAttributeName("Id") .withKeyType(KeyType.HASH)); //Partition key StreamSpecification streamSpecification = new StreamSpecification(); streamSpecification.setStreamEnabled(true); streamSpecification.setStreamViewType(StreamViewType.NEW_AND_OLD_IMAGES); CreateTableRequest createTableRequest = new CreateTableRequest() .withTableName(tableName) .withKeySchema(keySchema) .withAttributeDefinitions(attributeDefinitions) .withProvisionedThroughput(new ProvisionedThroughput() .withReadCapacityUnits(1L) .withWriteCapacityUnits(1L)) .withStreamSpecification(streamSpecification); System.out.println("Issuing CreateTable request for " + tableName); dynamoDBClient.createTable(createTableRequest); System.out.println("Waiting for " + tableName + " to be created..."); try { Tables.awaitTableToBecomeActive(dynamoDBClient, tableName); } catch (InterruptedException e) { e.printStackTrace(); } // Determine the Streams settings for the table DescribeTableResult describeTableResult = dynamoDBClient.describeTable(tableName); String myStreamArn = describeTableResult.getTable().getLatestStreamArn(); StreamSpecification myStreamSpec = describeTableResult.getTable().getStreamSpecification(); System.out.println("Current stream ARN for " + tableName + ": "+ myStreamArn); API Version 2012-08-10 453 Amazon DynamoDB Manuel du développeur Procédure pas à pas : API de bas niveau Flux DynamoDB System.out.println("Stream enabled: "+ myStreamSpec.getStreamEnabled()); System.out.println("Update view type: "+ myStreamSpec.getStreamViewType()); // Add a new item int numChanges = 0; System.out.println("Making some changes to table data"); Map<String, AttributeValue> item = new HashMap<String, AttributeValue>(); item.put("Id", new AttributeValue().withN("101")); item.put("Message", new AttributeValue().withS("New item!")); dynamoDBClient.putItem(tableName, item); numChanges++; // Update the item Map<String, AttributeValue> key = new HashMap<String, AttributeValue>(); key.put("Id", new AttributeValue().withN("101")); Map<String, AttributeValueUpdate> attributeUpdates = new HashMap<String, AttributeValueUpdate>(); attributeUpdates.put("Message", new AttributeValueUpdate() .withAction(AttributeAction.PUT) .withValue(new AttributeValue().withS("This item has changed"))); dynamoDBClient.updateItem(tableName, key, attributeUpdates); numChanges++; // Delete the item dynamoDBClient.deleteItem(tableName, key); numChanges++; // Get the shards in the stream DescribeStreamResult describeStreamResult = streamsClient.describeStream(new DescribeStreamRequest() .withStreamArn(myStreamArn)); String streamArn = describeStreamResult.getStreamDescription().getStreamArn(); List<Shard> shards = describeStreamResult.getStreamDescription().getShards(); // Process each shard for (Shard shard : shards) { String shardId = shard.getShardId(); System.out.println( "Processing " + shardId + " from stream "+ streamArn); // Get an iterator for the current shard GetShardIteratorRequest getShardIteratorRequest = new GetShardIteratorRequest() .withStreamArn(myStreamArn) .withShardId(shardId) .withShardIteratorType(ShardIteratorType.TRIM_HORIZON); GetShardIteratorResult getShardIteratorResult = API Version 2012-08-10 454 Amazon DynamoDB Manuel du développeur Réplication entre régions streamsClient.getShardIterator(getShardIteratorRequest); String nextItr = getShardIteratorResult.getShardIterator(); while (nextItr != null && numChanges > 0) { // Use the iterator to read the data records from the shard GetRecordsResult getRecordsResult = streamsClient.getRecords(new GetRecordsRequest(). withShardIterator(nextItr)); List<Record> records = getRecordsResult.getRecords(); System.out.println("Getting records..."); for (Record record : records) { System.out.println(record); numChanges--; } nextItr = getRecordsResult.getNextShardIterator(); } // Delete the table System.out.println("Deleting the table..."); dynamoDBClient.deleteTable(tableName); System.out.println("Demo complete"); } } } Réplication entre régions Important AWS offrait précédemment une solution de réplication inter-régions basée sur AWS CloudFormation. Cette solution est maintenant obsolète et a laissé place à un outil de ligne de commande open source. Pour plus d'informations, veuillez consulter les instructions détaillées sur GitHub : • https://github.com/awslabs/dynamodb-cross-region-library/blob/master/README.md La solution DynamoDB de réplication inter-régions utilise la bibliothèque de réplication inter-régions Amazon DynamoDB. Cette bibliothèque utilise Flux DynamoDB pour préserver la synchronisation des tables DynamoDB sur plusieurs régions presque en temps réel. Lorsque vous écrivez sur une table DynamoDB d'une région, ces modifications sont automatiquement propagées par la bibliothèque de réplication inter-régions sur vos tables des autres régions. Vous pouvez tirer parti de la bibliothèque de réplication inter-régions dans vos propres applications pour créer vos propres solutions de réplication avec Flux DynamoDB. Pour plus d'informations et pour télécharger le code source, consultez le référentiel GitHub suivant : • https://github.com/awslabs/dynamodb-cross-region-library Déclencheurs Flux DynamoDB et AWS Lambda Rubriques API Version 2012-08-10 455 Amazon DynamoDB Manuel du développeur Déclencheurs Flux DynamoDB et AWS Lambda • Didacticiel : Traitement de nouveaux éléments dans une table DynamoDB (p. 456) • Bonnes pratiques (p. 463) Amazon DynamoDB est intégré à AWS Lambda, afin que vous puissiez créer des déclencheurs, des éléments de code qui répondent automatiquement à des événements dans Flux DynamoDB. Avec des déclencheurs, vous pouvez créer des applications qui réagissent à des modifications de données dans des tables DynamoDB. Si vous activez Flux DynamoDB sur une table, vous pouvez associer le flux ARN avec une fonction Lambda que vous écrivez. Immédiatement après la modification d'un élément dans la table, un nouvel enregistrement apparaît dans le flux de la table. AWS Lambda interroge le flux et appelle votre fonction Lambda de façon synchrone quand il y détecte de nouveaux enregistrements de flux. La fonction Lambda peut effectuer toute action que vous spécifiez, comme envoyer une notification ou initier un flux de travail. Par exemple, vous pouvez écrire une fonction Lambda pour copier simplement chaque enregistrement en vue d'un stockage permanent, par exemple Amazon Simple Storage Service (Amazon S3), pour créer une piste d'audit permanente de l'activité d'écriture dans votre table. Ou supposons que vous ayez une application de jeux pour appareils mobiles qui écrive dans une table GameScores. Chaque fois que l'attribut TopScore de la table GameScores est mis à jour, un enregistrement de flux correspondant est écrit dans le flux de la table. Cet événement peut alors déclencher une fonction Lambda qui affiche un message de félicitations sur un réseau social. (La fonction ignorerait simplement tout enregistrement de flux qui ne serait pas des mises à jour de GameScores, ou qui ne modifierait pas l'attribut TopScore.) Pour plus d'informations sur AWS Lambda, consultez AWS Lambda Developer Guide. Didacticiel : Traitement de nouveaux éléments dans une table DynamoDB Rubriques • Etape 1 : Création d'une table DynamoDB avec un flux activé (p. 457) • Etape 2 : Créer un rôle d'exécution Lambda (p. 457) • Etape 3 : Créer une rubrique Amazon SNS (p. 459) • Étape 4 : Création et test d'une fonction Lambda (p. 459) • Étape 5 : Création et test d'un déclencheur (p. 462) Au cours de ce didacticiel, vous allez créer un déclencheur AWS Lambda pour traiter le flux d'une table DynamoDB. Le scénario de ce didacticiel est Woofer, un réseau social simple. Les utilisateurs de Woofer communiquent avec des aboiements (messages textuels brefs) qui sont envoyés à d'autres utilisateurs de Woofer. Le schéma suivant illustre les composants et le flux de travail de cette application : 1. Un utilisateur écrit un élément dans une table DynamoDB (BarkTable). Chaque élément de la table représente un aboiement. 2. Un nouvel enregistrement de flux est écrit pour refléter l'ajout de ce nouvel élément dans BarkTable. 3. Le nouvel enregistrement de flux déclenche une fonction AWS Lambda (publishNewBark). 4. Si l'enregistrement de flux indique qu'un nouvel élément a été ajouté à BarkTable, la fonction Lambda lit les données de l'enregistrement de flux et publie un message dans une rubrique dans Amazon Simple Notification Service (Amazon SNS). 5. Le message est reçu par des abonnés à la rubrique Amazon SNS. Dans le cadre de ce didacticiel, le seul abonné est une adresse e-mail. API Version 2012-08-10 456 Amazon DynamoDB Manuel du développeur Déclencheurs Flux DynamoDB et AWS Lambda Avant de commencer Ce didacticiel utilise l'AWS Command Line Interface. Si vous ne l'avez pas encore fait, suivez les instructions du manuel AWS Command Line Interface Guide de l'utilisateur pour configurer et installer l'AWS CLI. Etape 1 : Création d'une table DynamoDB avec un flux activé Au cours de cette étape, vous allez créer une table DynamoDB (BarkTable) pour stocker tous les aboiements des utilisateurs de Woofer. La clé principale est composée du Nomutilisateur (clé de partition) et de l'Horodatage (clé de tri). Les deux attributs sont de type string (chaîne). Un flux sera activé pour BarkTable. Pour loin dans ce didacticiel, vous allez créer un déclencheur en associant une fonction AWS Lambda au flux. 1. Tapez la commande suivante pour créer la table : aws dynamodb create-table \ --table-name BarkTable \ --attribute-definitions AttributeName=Username,AttributeType=S AttributeName=Timestamp,AttributeType=S \ --key-schema AttributeName=Username,KeyType=HASH AttributeName=Timestamp,KeyType=RANGE \ --provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5 \ --stream-specification StreamEnabled=true,StreamViewType=NEW_AND_OLD_IMAGES 2. Dans la sortie, recherchez le LatestStreamArn : ... "LatestStreamArn": "arn:aws:dynamodb:region:acccountID:table/BarkTable/ stream/timestamp ... Notez la region et l'accountID, car vous en aurez besoin pour les autres étapes de ce didacticiel. Etape 2 : Créer un rôle d'exécution Lambda Au cours de cette étape, vous allez créer un rôle IAM (WooferLambdaRole) et lui attribuer des autorisations. Ce rôle sera utilisé par la fonction Lambda que vous allez créer dans Étape 4 : Création et test d'une fonction Lambda (p. 459). Vous allez également créer une stratégie pour le rôle. Cette stratégie contiendra toutes les autorisations dont la fonction Lambda aura besoin lors de l'exécution. 1. Créez un fichier nommé trust-relationship.json avec le contenu suivant : { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { API Version 2012-08-10 457 Amazon DynamoDB Manuel du développeur Déclencheurs Flux DynamoDB et AWS Lambda "Service": "lambda.amazonaws.com" }, "Action": "sts:AssumeRole" } ] } 2. Tapez la commande suivante pour créer WooferLambdaRole : aws iam create-role --role-name WooferLambdaRole \ --path "/service-role/" \ --assume-role-policy-document file://trust-relationship.json 3. Créez un fichier nommé role-policy.json avec le contenu suivant. Remplacez region et accountID par votre région AWS et votre ID de compte. { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "lambda:InvokeFunction", "Resource": "arn:aws:lambda:region:accountID:function:publishNewBark*" }, { "Effect": "Allow", "Action": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents" ], "Resource": "arn:aws:logs:region:accountID:*" }, { "Effect": "Allow", "Action": [ "dynamodb:DescribeStream", "dynamodb:GetRecords", "dynamodb:GetShardIterator", "dynamodb:ListStreams" ], "Resource": "arn:aws:dynamodb:region:accountID:table/ BarkTable/stream/*" }, { "Effect": "Allow", "Action": [ "sns:Publish" ], "Resource": [ "*" ] } ] } API Version 2012-08-10 458 Amazon DynamoDB Manuel du développeur Déclencheurs Flux DynamoDB et AWS Lambda La stratégie comporte quatre instructions pour autoriser WooferLambdaRole à effectuer les opérations suivantes : • Exécuter une fonction Lambda (publishNewBark). Vous allez créer cette fonction plus tard dans le cadre de ce didacticiel. • Accéder à CloudWatch Logs. La fonction Lambda écrira des diagnostics dans CloudWatch Logs lors de l'exécution. • Lire les données du flux DynamoDB pour BarkTable. • Publier des messages dans Amazon SNS. 4. Tapez la commande suivante pour attacher la stratégie à WooferLambdaRole : aws iam put-role-policy --role-name WooferLambdaRole \ --policy-name WooferLambdaRolePolicy \ --policy-document file://role-policy.json Etape 3 : Créer une rubrique Amazon SNS Au cours de cette étape, vous allez créer une rubrique Amazon SNS (wooferTopic) et y abonner une adresse e-mail. Votre fonction Lambda utilisera cette rubrique pour publier de nouveaux aboiements de la part des utilisateurs de Woofer. 1. Tapez la commande suivante pour créer une rubrique Amazon SNS : aws sns create-topic --name wooferTopic 2. Tapez la commande suivante pour abonner une adresse e-mail à wooferTopic. Remplacez region et accountID par votre région AWS et votre ID de compte, puis remplacez [email protected] par une adresse e-mail valide. aws sns subscribe \ --topic-arn arn:aws:sns:region:accountID:wooferTopic \ --protocol email \ --notification-endpoint [email protected] 3. Amazon SNS enverra un message de confirmation à votre adresse e-mail. Cliquez sur le lien Confirm subscription de ce message pour finaliser le processus d'abonnement. Étape 4 : Création et test d'une fonction Lambda Au cours de cette étape, vous allez créer une fonction AWS Lambda (publishNewBark) pour traiter les enregistrements de flux de BarkTable. La fonction publishNewBark traite uniquement les événements de flux qui correspondent aux nouveaux éléments de BarkTable. La fonction lit les données d'un tel événement, puis appelle Amazon SNS pour le publier. 1. Créez un fichier nommé publishNewBark.js avec le contenu suivant. Remplacez region et accountID par votre région AWS et votre ID de compte. 'use strict'; var AWS = require("aws-sdk"); API Version 2012-08-10 459 Amazon DynamoDB Manuel du développeur Déclencheurs Flux DynamoDB et AWS Lambda var sns = new AWS.SNS(); exports.handler = (event, context, callback) => { event.Records.forEach((record) => { console.log('Stream record: ', JSON.stringify(record, null, 2)); if (record.eventName == 'INSERT') { var who = JSON.stringify(record.dynamodb.NewImage.Username.S); var when = JSON.stringify(record.dynamodb.NewImage.Timestamp.S); var what = JSON.stringify(record.dynamodb.NewImage.Message.S); var params = { Subject: 'A new bark from ' + who, Message: 'Woofer user ' + who + ' barked the following at ' + when + ':\n\n ' + what, TopicArn: 'arn:aws:sns:region:accountID:wooferTopic' }; sns.publish(params, function(err, data) { if (err) { console.error("Unable to send message. Error JSON:", JSON.stringify(err, null, 2)); callback(err, null); } else { console.log("Results from sending message: ", JSON.stringify(data, null, 2)); callback(null, data); } }); } }); callback(null, `Successfully processed ${event.Records.length} records.`); }; 2. Créez un fichier zip pour publishNewBark.js. Si vous disposez de l'utilitaire de ligne de commande pour zipper, vous pouvez taper la commande suivante : zip publishNewBark.zip publishNewBark.js 3. Lorsque vous créez la fonction Lambda, vous devez spécifier l'ARN de WooferLambdaRole, que vous avez créé dans Etape 2 : Créer un rôle d'exécution Lambda (p. 457). Tapez la commande suivante pour extraire cet ARN : aws iam get-role --role-name WooferLambdaRole Dans la sortie, recherchez l'ARN de WooferLambdaRole : ... "Arn": "arn:aws:iam::region:role/service-role/WooferLambdaRole" ... Tapez maintenant la commande suivante pour créer la fonction Lambda. Remplacez roleARN par l'ARN de WooferLambdaRole. API Version 2012-08-10 460 Amazon DynamoDB Manuel du développeur Déclencheurs Flux DynamoDB et AWS Lambda aws lambda create-function \ --region us-east-1 \ --function-name publishNewBark \ --zip-file fileb://publishNewBark.zip \ --role roleARN \ --handler publishNewBark.handler \ --timeout 5 \ --runtime nodejs4.3 4. Vous allez maintenant tester publishNewBark pour vérifier que cela fonctionne. Pour cela, vous entrez des informations similaires à un véritable enregistrement de Flux DynamoDB. Créez un fichier nommé payload.json avec le contenu suivant. { "Records": [ { "eventID": "7de3041dd709b024af6f29e4fa13d34c", "eventName": "INSERT", "eventVersion": "1.1", "eventSource": "aws:dynamodb", "awsRegion": "us-west-2", "dynamodb": { "ApproximateCreationDateTime": 1479499740, "Keys": { "Timestamp": { "S": "2016-11-18:12:09:36" }, "Username": { "S": "John Doe" } }, "NewImage": { "Timestamp": { "S": "2016-11-18:12:09:36" }, "Message": { "S": "This is a bark from the Woofer social network" }, "Username": { "S": "John Doe" } }, "SequenceNumber": "13021600000000001596893679", "SizeBytes": 112, "StreamViewType": "NEW_IMAGE" }, "eventSourceARN": "arn:aws:dynamodb:useast-1:123456789012:table/BarkTable/stream/2016-11-16T20:42:48.104" } ] } Tapez la commande suivante pour tester la fonction publishNewBark : API Version 2012-08-10 461 Amazon DynamoDB Manuel du développeur Déclencheurs Flux DynamoDB et AWS Lambda aws lambda invoke --function-name publishNewBark --payload file:// payload.json output.txt Si le test est réussi, vous verrez la sortie suivante : { "StatusCode": 200 } De plus, le fichier output.txt contiendra le texte suivant : "Successfully processed 1 records." Vous recevrez également un nouveau message électronique quelques minutes après. Note AWS Lambda écrit les informations de diagnostic dans Amazon CloudWatch Logs. Si vous rencontrez des erreurs avec la fonction Lambda, vous pouvez utiliser ces diagnostics à des fins de dépannage : 1. Ouvrez la console CloudWatch à l'adresse https://console.aws.amazon.com/ cloudwatch/. 2. Dans le volet de navigation, sélectionnez Logs. 3. Choisissez le groupe de journal suivant : /aws/lambda/publishNewBark 4. Choisissez le dernier flux de journal pour consulter la sortie (et les erreurs) de la fonction. Étape 5 : Création et test d'un déclencheur Dans Étape 4 : Création et test d'une fonction Lambda (p. 459), vous avez testé la fonction Lambda pour vérifier son exécution. Au cours de cette étape, vous allez créer un déclencheur en associant la fonction Lambda (publishNewBark) à une source d'événement (le flux BarkTable). 1. Lorsque vous créez le déclencheur, vous devez spécifier l'ARN du flux BarkTable. Tapez la commande suivante pour extraire cet ARN : aws dynamodb describe-table --table-name BarkTable Dans la sortie, recherchez le LatestStreamArn : ... "LatestStreamArn": "arn:aws:dynamodb:region:acccountID:table/BarkTable/ stream/timestamp ... 2. Tapez la commande suivante pour créer le déclencheur. Remplacez streamARN par l'ARN du flux. aws lambda create-event-source-mapping \ --region us-east-1 \ --function-name publishNewBark \ API Version 2012-08-10 462 Amazon DynamoDB Manuel du développeur Déclencheurs Flux DynamoDB et AWS Lambda --event-source streamARN \ --batch-size 1 \ --starting-position TRIM_HORIZON 3. Vous allez maintenant tester le déclencheur. Tapez la commande suivante pour ajouter un élément à BarkTable : aws dynamodb put-item \ --table-name BarkTable \ --item Username={S="Jane Doe"},Timestamp={S="2016-11-18:14:32:17"},Message={S="Testing...1...2...3"} 4. Vous devriez recevoir un nouveau message électronique quelques minutes après. Accédez à la console DynamoDB et ajoutez quelques éléments à BarkTable. Vous devez spécifier les valeurs des attributs Username et Timestamp. Vous devez également spécifier une valeur pour Message, bien que cela ne soit pas obligatoire. Vous devriez recevoir un nouveau message électronique pour chaque élément ajouté à BarkTable. La fonction Lambda traite uniquement les nouveaux éléments ajoutés à BarkTable. Si vous mettez à jour ou supprimez un élément dans la table, la fonction ne fait rien. Note AWS Lambda écrit les informations de diagnostic dans Amazon CloudWatch Logs. Si vous rencontrez des erreurs avec la fonction Lambda, vous pouvez utiliser ces diagnostics à des fins de dépannage. 1. Ouvrez la console CloudWatch à l'adresse https://console.aws.amazon.com/cloudwatch/. 2. Dans le volet de navigation, sélectionnez Logs. 3. Choisissez le groupe de journal suivant : /aws/lambda/publishNewBark 4. Choisissez le dernier flux de journal pour consulter la sortie (et les erreurs) de la fonction. Bonnes pratiques Une fonction AWS Lambda est exécutée avec un conteneur, un environnement d'exécution isolé des autres fonctions. Lorsque vous exécutez une fonction pour la première fois, AWS Lambda crée un conteneur et commence à exécuter le code de la fonction. Une fonction Lambda a un gestionnaire qui est exécuté une fois par appel. Le gestionnaire contient la logique métier principale de la fonction. Par exemple, la fonction Lambda illustrée dans Étape 4 : Création et test d'une fonction Lambda (p. 459) comporte un gestionnaire qui peut traiter des enregistrements dans un flux DynamoDB. Vous pouvez également fournir un code d'initialisation exécuté une seule fois, après la création du conteneur, mais avant l'exécution du gestionnaire par AWS Lambda pour la première fois. La fonction Lambda illustrée dans Étape 4 : Création et test d'une fonction Lambda (p. 459) a un code d'initialisation qui importe le Kit SDK pour JavaScript dans Node.js et crée un client pour Amazon SNS. Ces objets doivent être définis une seule fois, en dehors du gestionnaire. Après l'exécution de la fonction, AWS Lambda peut choisir de réutiliser le conteneur pour les appels suivants de la fonction. Dans ce cas, votre gestionnaire de fonction peut réutiliser les ressources que vous avez définies dans votre code d'initialisation. Notez que vous ne pouvez pas contrôler la durée de conservation du conteneur par AWS Lambda, ni la réutilisation du conteneur. Pour les déclencheurs DynamoDB qui utilisent AWS Lambda, nous recommandons les points suivants : API Version 2012-08-10 463 Amazon DynamoDB Manuel du développeur Déclencheurs Flux DynamoDB et AWS Lambda • Les clients du service AWS doivent être instanciés dans le code d'initialisation et non dans le gestionnaire. Cela permettra à AWS Lambda de réutiliser les connexions existantes pendant la durée de vie du conteneur. • En règle générale, vous n'avez pas besoin de gérer les connexions explicitement, ni d'implémenter les groupes de connexions car AWS Lambda s'en charge pour vous. Pour plus d'informations, accédez à Bonnes pratiques d'utilisation des fonctions AWS Lambda dans le manuel AWS Lambda Developer Guide. API Version 2012-08-10 464 Amazon DynamoDB Manuel du développeur Authentification Authentification et contrôle d'accès pour Amazon DynamoDB L'accès à Amazon DynamoDB requiert des informations d'identification. Ces informations d'identification doivent disposer d'autorisations pour accéder aux ressources AWS, telles qu'une table Amazon DynamoDB table ou une instance Amazon Elastic Compute Cloud (Amazon EC2). Les sections suivantes décrivent comment utiliser AWS Identity and Access Management (IAM) et DynamoDB pour contribuer à sécuriser l'accès à vos ressources. • Authentification (p. 465) • Contrôle d'accès (p. 467) Authentification Vous pouvez utiliser les types d'identité suivants pour accéder à AWS : • Utilisateur racine du compte AWS – Lorsque vous vous inscrivez à AWS, vous fournissez une adresse de messagerie et un mot de passe qui sont associés à votre compte AWS. Il s'agit de vos informations d'identification racine et elles fournissent un accès complet à l'ensemble de vos ressources AWS. Important Pour des raisons de sécurité, nous vous conseillons d'utiliser les informations d'identification racine uniquement pour créer un utilisateur administrateur, qui est un utilisateur IAM disposant des autorisations complètes sur votre compte AWS. Vous pouvez ensuite utiliser cet utilisateur administrateur pour créer d'autres utilisateurs IAM et des rôles dotés d'autorisations limitées. Pour plus d'informations, consultez Bonnes pratiques IAM et Création d'un utilisateurs administrateur et d'un groupe dans le manuel IAM Guide de l'utilisateur. • Utilisateur IAM; – Un utilisateur IAM est simplement une identité au sein de votre compte AWS qui dispose d'autorisations personnalisées spécifiques (par exemple, des autorisations pour créer a table dans DynamoDB). Vous pouvez utiliser un nom utilisateur et un mot de passe IAM pour vous connecter aux pages Web AWS sécurisées telles que AWS Management Console, les forums de discussion AWS et le AWS Support Center. API Version 2012-08-10 465 Amazon DynamoDB Manuel du développeur Authentification En plus de générer un nom utilisateur et un mot de passe, vous pouvez générer des clés d'accès pour chaque utilisateur. Vous pouvez utiliser ces clés lorsque vous accédez aux services AWS par programmation, soit par le biais d'un kit SDK soit à l'aide d'AWS Command Line Interface (CLI). Les outils de l'interface de ligne de commande et les kits SDK utilisent les clés d'accès pour signer de façon cryptographique votre demande. Si vous n'utilisez pas les outils AWS, vous devez signer la demande vous-même. DynamoDB prend en charge Signature Version 4, un protocole permettant l'authentification des demandes d'API entrantes. Pour plus d'informations sur l'authentification des demandes, consultez la rubrique Processus de signature Signature Version 4 dans la documentation AWS General Reference. • Rôle IAM – Un rôle IAM est une autre identité IAM que vous pouvez créer dans votre compte et qui dispose d'autorisations spécifiques. Le concept ressemble à celui d'utilisateur IAM, mais le rôle IAM n'est pas associé à une personne en particulier. Un rôle IAM vous permet d'obtenir des clés d'accès temporaires qui peuvent être utilisées pour accéder aux ressources et services AWS. Les rôles IAM avec des informations d'identification temporaires sont utiles dans les cas suivants : • Accès par des utilisateurs fédérés : au lieu de créer un utilisateur IAM, vous pouvez utiliser des identités d'utilisateur préexistantes provenant d'AWS Directory Service, de votre répertoire utilisateur d'entreprise ou d'un fournisseur d'identité web. Ces derniers sont appelés utilisateurs fédérés. AWS attribue un rôle à un utilisateur fédéré lorsque l'accès est demandé via un fournisseur d'identité. Pour plus d'informations sur les utilisateurs fédérés, consultez Utilisateurs fédérés et rôles dans le manuel IAM Guide de l'utilisateur. • Accès entre comptes : vous pouvez utiliser un rôle IAM de votre compte pour autoriser un autre compte AWS à accéder aux ressources de votre compte. Pour obtenir un exemple, consultez le Didacticiel : Déléguer l'accès entre des comptes AWS à l'aide de rôles IAM dans le manuel IAM Guide de l'utilisateur. • Accès au service AWS : vous pouvez utiliser un rôle IAM de votre compte pour autoriser un service AWS à accéder aux ressources de votre compte. Par exemple, vous pouvez créer un rôle qui permet à Amazon Redshift d'accéder à un compartiment Amazon S3 en votre nom, puis de charger les données stockées dans le compartiment dans un cluster Amazon Redshift. Pour plus d'informations, consultez Création d'un rôle pour déléguer des autorisations à un service AWS dans la documentation IAM Guide de l'utilisateur. • Applications qui s'exécutent sur Amazon EC2 : au lieu de stocker des clés d'accès au sein de l'instance EC2 afin qu'elles soient utilisées par les applications s'exécutant sur l'instance et d'émettre des demandes d'API AWS, vous pouvez utiliser un rôle IAM pour gérer des informations d'identification temporaires pour ces applications. Pour attribuer un rôle AWS à une instance EC2 et le rendre disponible pour toutes ses applications, vous pouvez créer un profil d'instance attaché à l'instance. Un profil d'instance contient le rôle et permet aux programmes qui s'exécutent sur l'instance EC2 d'obtenir des informations d'identification temporaires. Pour plus d'informations, consultez Utilisation de rôles pour des applications s'exécutant sur Amazon EC2 dans le manuel IAM Guide de l'utilisateur. API Version 2012-08-10 466 Amazon DynamoDB Manuel du développeur Contrôle d'accès Contrôle d'accès Vous pouvez disposer d'informations d'identification valides pour authentifier vos demandes, mais à moins d'avoir les autorisations requises, vous ne pouvez pas créer de ressources Amazon DynamoDB ni accéder à de telles ressources. Par exemple, vous devez disposer d'autorisations pour créer une application Amazon DynamoDB table. Les sections suivantes expliquent comment gérer les autorisations pour Amazon DynamoDB. Nous vous recommandons de commencer par lire la présentation. • Présentation de la gestion de l'accès (p. 467) • Utilisation des stratégies basées sur une identité (stratégies IAM) (p. 471) • Référence des autorisations d'API DynamoDB (p. 479) • Utilisation de conditions (p. 483) Présentation de la gestion des autorisations d'accès à vos ressources Amazon DynamoDB Chaque ressource AWS appartient à un compte AWS et les autorisations permettant de créer des ressources et d'y accéder sont régies par les stratégies d'autorisation. Un administrateur de compte peut attacher des stratégies d'autorisation aux identités IAM (c'est-à-dire aux utilisateurs, groupes et rôles), et certains services (tels que AWS Lambda) prennent également en charge l'attachement de stratégies d'autorisation aux ressources. Note Un administrateur de compte (ou utilisateur administrateur) est un utilisateur doté des privilèges d'administrateur. Pour plus d'informations, consultez Bonnes pratiques IAM dans le manuel IAM Guide de l'utilisateur. Lorsque vous accordez des autorisations, vous décidez qui doit les obtenir, à quelles ressources ces autorisations s'appliquent et les actions spécifiques que vous souhaitez autoriser sur ces ressources. Rubriques • Opérations et ressources Amazon DynamoDB (p. 467) • Présentation de la propriété des ressources (p. 468) • Gestion de l'accès aux ressources (p. 468) • Spécification des éléments d'une stratégie : actions, effets et mandataires (p. 470) • Spécification des conditions dans une stratégie (p. 470) Opérations et ressources Amazon DynamoDB Dans DynamoDB, les ressources principales sont les tables. DynamoDB prend aussi en charge les types de ressources supplémentaires, les index et les flux. Cependant, vous ne pouvez créer des index et des flux que dans le contexte d'une table DynamoDB existante. Celles-ci sont appelées sousressources. Ces ressources et sous-ressources ont un ARN (Amazon Resource Name) unique qui leur est associé, comme illustré dans le tableau suivant. API Version 2012-08-10 467 Amazon DynamoDB Manuel du développeur Présentation de la propriété des ressources Type de ressource Format ARN Tableau arn:aws:dynamodb:region:account-id:table/table-name Index arn:aws:dynamodb:region:account-id:table/table-name/ index/index-name Flux arn:aws:dynamodb:region:account-id:table/table-name/ stream/stream-label DynamoDB fournit un ensemble d'opérations à utiliser avec des ressources DynamoDB. Pour obtenir une liste des opérations disponibles, consultez Amazon DynamoDB Actions. Présentation de la propriété des ressources Le compte AWS possède les ressources qui sont créés dans le compte, indépendamment de la personne qui a créé les ressources. Plus spécifiquement, le propriétaire des ressources est le compte AWS de l'entité principale (à savoir, le compte racine, un utilisateur IAM ou un rôle IAM) qui authentifie la demande de création des ressources. Les exemples suivants illustrent comment cela fonctionne : • Si vous utilisez les informations d'identification du compte racine de votre compte AWS pour créer a table, votre compte AWS est le propriétaire de la ressource (dans DynamoDB, la ressource est a table). • Si vous créez un utilisateur IAM dans votre compte AWS et autorisez cet utilisateur à créer a table il peut créer a table. Toutefois, votre compte AWS, auquel l'utilisateur appartient, détient la ressource table. • Si vous créez un rôle IAM dans votre compte AWS avec des autorisations pour créer a table, quiconque capable d'assumer le rôle peut créer a table. Votre compte AWS, auquel l'utilisateur appartient, détient la ressource table. Gestion de l'accès aux ressources Une stratégie d'autorisation décrit qui a accès à quoi. La section suivante explique les options disponibles pour créer des stratégies d'autorisation. Note Cette section décrit l'utilisation d'IAM dans le contexte de DynamoDB. Elle ne fournit pas d'informations détaillées sur le service IAM. Pour accéder à la documentation complète d'IAM, consultez Qu'est-ce qu'IAM ? du manuel IAM Guide de l'utilisateur. Pour plus d'informations sur la syntaxe et les descriptions des stratégies IAM, consultez Référence de stratégie AWS IAM dans le manuel IAM Guide de l'utilisateur. Les stratégies attachées à une identité IAM sont appelées stratégies basées sur une entité (stratégies IAM) et les stratégies attachées à une ressource sont appelées stratégies basées sur une ressource. DynamoDB prend en charge uniquement les stratégies basées sur l'identité (stratégies IAM). Rubriques • Stratégies basées sur une identité (stratégies IAM) (p. 469) • Stratégies basées sur une ressource (p. 469) API Version 2012-08-10 468 Amazon DynamoDB Manuel du développeur Gestion de l'accès aux ressources Stratégies basées sur une identité (stratégies IAM) Vous pouvez attacher des stratégies à des identités IAM. Par exemple, vous pouvez effectuer les opérations suivantes : • Lier une stratégie d'autorisations à un utilisateur ou à un groupe de votre compte – pour accorder à un utilisateur l'autorisation relative à la création d'une ressource Amazon DynamoDB, comme a table, vous pouvez lier une stratégie d'autorisations à un utilisateur ou à un groupe auquel l'utilisateur appartient. • Attacher une stratégie d'autorisation à un rôle (accorder des autorisations entre comptes) – Vous pouvez attacher une stratégie d'autorisation basée sur une identité à un rôle IAM pour accorder des autorisations entre comptes. Par exemple, l'administrateur dans le compte A peut créer un rôle pour accorder des autorisations entre comptes à un autre compte AWS (par exemple, le compte B) ou à un service AWS comme suit : 1. L'administrateur du compte A crée un rôle IAM et lie une stratégie d'autorisation au rôle qui accorde des autorisations sur les ressources dans le compte A. 2. L'administrateur du compte A lie une stratégie d'approbation au rôle identifiant le compte B comme mandataire pouvant assumer ce rôle. 3. L'administrateur du compte B peut alors déléguer des autorisations pour assumer le rôle à tous les utilisateurs figurant dans le compte B. Les utilisateurs du compte B sont ainsi autorisés à créer des ressources ou à y accéder dans le compte A. Le mandataire dans la stratégie d'approbation peut également être un mandataire de service AWS si vous souhaitez accorder à un service AWS des autorisations pour assumer ce rôle. Pour plus d'informations sur l'utilisation d'IAM pour déléguer des autorisations, consultez Gestion de l'accès dans le manuel IAM Guide de l'utilisateur. Voici un exemple de stratégie qui accorde les autorisations pour une seule action DynamoDB (dynamodb:ListTables). Le caractère générique (*) présent dans la valeur Resource signifie que vous pouvez utiliser cette action pour obtenir les noms de toutes les tables appartenant au compte AWS de la région AWS active. { "Version": "2012-10-17", "Statement": [ { "Sid": "ListTables", "Effect": "Allow", "Action": [ "dynamodb:ListTables" ], "Resource": "*" } ] } Pour plus d'informations sur l'utilisation des stratégies basées sur une identité avec DynamoDB, consultez Utilisation des stratégies basées sur l'identité (stratégies IAM) pour Amazon DynamoDB (p. 471). Pour plus d'informations sur les utilisateurs, les groupes, les rôles et les autorisations, consultez Identités (utilisateurs, groupes et rôles) dans le manuel IAM Guide de l'utilisateur. Stratégies basées sur une ressource D'autres services, tels que Amazon S3, prennent également en charge les stratégies d'autorisation basées sur une ressource. Par exemple, vous pouvez attacher une stratégie à un compartiment API Version 2012-08-10 469 Amazon DynamoDB Manuel du développeur Spécification des éléments d'une stratégie : actions, effets et mandataires S3 pour gérer les autorisations d'accès à ce compartiment. DynamoDB ne prend pas en charge les stratégies basées sur les ressources. Spécification des éléments d'une stratégie : actions, effets et mandataires Pour chaque ressource DynamoDB, le service définit un ensemble d'opérations d'API. Pour accorder des autorisations pour ces opérations d'API, DynamoDB définit un ensemble d'actions que vous pouvez spécifier dans une stratégie. Certaines opérations d'API peuvent exiger des autorisations pour plusieurs actions afin de réaliser l'opération d'API. Pour plus d'informations sur les ressources et les opérations API, consultez Opérations et ressources Amazon DynamoDB (p. 467) et DynamoDB Actions. Voici les éléments les plus élémentaires d'une stratégie : • Ressource – Un Amazon Resource Name (ARN) identifie la ressource à laquelle la stratégie s'applique. Pour plus d'informations, consultez Opérations et ressources Amazon DynamoDB (p. 467). • Action – Vous utilisez des mots clés d'action pour identifier les opérations de ressource que vous voulez accorder ou refuser. Par exemple, vous pouvez utiliser et dynamodb:Query pour allows the user permissions to perform the DynamoDB Query operation. • Effet – Vous spécifiez l'effet produit, soit un accord ou un refus, lorsque l'utilisateur demande l'action spécifique. Si vous n'accordez pas explicitement l'accès pour (autoriser) une ressource, l'accès est implicitement refusé. Vous pouvez aussi explicitement refuser l'accès à une ressource, ce que vous pouvez faire afin de vous assurer qu'un utilisateur n'y a pas accès, même si une stratégie différente accorde l'accès. • Mandataire – Dans les stratégies basées sur une identité (stratégies IAM), l'utilisateur auquel la stratégie est attachée est le mandataire implicite. Pour les stratégies basées sur une ressource, vous spécifiez l'utilisateur, le compte, le service ou une autre entité qui doit recevoir les autorisations (s'applique uniquement aux stratégies basées sur une ressource). Stratégies basées sur les ressources DynamoDB doesn't support. Pour plus d'informations sur la syntaxe des stratégies IAM et pour obtenir des descriptions, consultez Référence de stratégie AWS IAM dans le manuel IAM Guide de l'utilisateur. Pour obtenir une des tableaux présentant toutes les opérations API d' Amazon DynamoDB ainsi que les ressources auxquelles elles s'appliquent, consultez Autorisations d'API DynamoDB : référence des actions, ressources et conditions (p. 479). Spécification des conditions dans une stratégie Lorsque vous accordez des autorisations, vous pouvez utiliser le langage d'access policy pour spécifier les conditions définissant quand une stratégie doit prendre effet. Par exemple, il est possible d'appliquer une stratégie après seulement une date spécifique. Pour plus d'informations sur la spécification de conditions dans un langage de stratégie, consultez Condition dans le manuel IAM Guide de l'utilisateur. Pour exprimer des conditions, vous utilisez des clés de condition prédéfinies. Il existe des clés de condition à l'échelle d'AWS et des clés spécifiques à DynamoDB que vous pouvez utiliser selon les besoins. Pour une liste complète des clés à l'échelle d'AWS, consultez Clés disponibles pour les conditions dans le IAM Guide de l'utilisateur. Pour obtenir la liste complète des clés spécifiques à DynamoDB, consultez Utilisation de conditions de stratégie IAM pour un contrôle d'accès précis (p. 483). API Version 2012-08-10 470 Amazon DynamoDB Manuel du développeur Utilisation des stratégies basées sur une identité (stratégies IAM) Utilisation des stratégies basées sur l'identité (stratégies IAM) pour Amazon DynamoDB Cette rubrique fournit des exemples de stratégies basées sur l'identité qui montrent comment un administrateur de compte peut attacher des stratégies d'autorisation à des identités IAM (autrement dit, des utilisateurs, groupes et rôles) et ainsi accorder des autorisations pour effectuer des opérations sur les ressources Amazon DynamoDB. Important Nous vous recommandons, tout d'abord, d'examiner les rubriques de présentation qui détaillent les concepts de base et les options disponibles pour gérer l'accès à vos ressources Amazon DynamoDB. Pour plus d'informations, consultez Présentation de la gestion des autorisations d'accès à vos ressources Amazon DynamoDB (p. 467). Les sections de cette rubrique couvrent les sujets suivants : • Autorisations requises pour utiliser la console Amazon DynamoDB (p. 471) • Stratégies gérées AWS (prédéfinies) pour Amazon DynamoDB (p. 472) • Exemples de stratégies gérées par le client (p. 472) Un exemple de stratégie d'autorisation est exposé ci-dessous. { "Version": "2012-10-17", "Statement": [ { "Sid": "DescribeQueryScanBooksTable", "Effect": "Allow", "Action": [ "dynamodb:DescribeTable", "dynamodb:Query", "dynamodb:Scan" ], "Resource": "arn:aws:dynamodb:us-west-2:account-id:table/Books" } ] } La stratégie possède une instruction qui accorde les autorisations pour trois actions DynamoDB (dynamodb:DescribeTable, dynamodb:Query et dynamodb:Scan) sur une table de la région uswest-2, qui appartient au compte AWS spécifié par account-id. L'ARN (Amazon Resource Name) de la valeur Resource spécifie la table à laquelle les autorisations s'appliquent. Autorisations requises pour utiliser la console Amazon DynamoDB Dans le cas d'un utilisateur qui travaille avec la console DynamoDB, il doit disposer d'un ensemble minimal d'autorisations qui permet à l'utilisateur de travailler avec les ressources DynamoDB de son compte AWS. Outre ces autorisations DynamoDB, la console nécessite les autorisations des services suivants : API Version 2012-08-10 471 Amazon DynamoDB Manuel du développeur Stratégies gérées AWS (prédéfinies) pour Amazon DynamoDB