Azure Table Storage of de Azure Cosmos DB for Table gebruiken vanuit Node.js

VAN TOEPASSING OP: Tabel

Tip

De inhoud in dit artikel is van toepassing op Azure Table Storage en Azure Cosmos DB for Table. De API voor Table is een premium-aanbieding voor tabelopslag met tabellen die zijn geoptimaliseerd voor doorvoer, wereldwijde distributie en automatische secundaire indexen.

In dit artikel leest u hoe u tabellen maakt, uw gegevens opslaat en CRUD-bewerkingen uitvoert op deze gegevens. De voorbeelden zijn geschreven in Node.js.

Een Azure-serviceaccount maken

U kunt in Azure Table Storage of in Azure Cosmos DB met tabellen werken. Zie het overzicht van de API voor Table voor meer informatie over de verschillen tussen tabelaanbiedingen in deze twee services. U moet een account maken voor de service die u gaat gebruiken. De volgende secties laten zien hoe u zowel een Azure Table Storage- als een Azure Cosmos DB-account maakt. U kunt echter slechts één daarvan gebruiken.

Een Azure-opslagaccount maken

De eenvoudigste manier om uw eerste Azure-opslagaccount te maken, is via de Azure-portal. Zie: Een opslagaccount maken voor meer informatie.

U kunt ook een Azure Storage-account maken met behulp van Azure PowerShell of de Azure CLI.

Als u op dit moment liever nog geen opslagaccount maakt, kunt u ook de Azure-opslagemulator gebruiken om de code in een lokale omgeving uit te voeren en te testen. Zie De Azure-opslagemulator gebruiken voor ontwikkelen en testen voor meer informatie.

Een Azure Cosmos DB for Table-account maken

Zie Een databaseaccount maken voor instructies voor het maken van een Azure Cosmos DB for Table-account.

Uw toepassing configureren voor toegang tot Table Storage

Als u Azure Storage of Azure Cosmos DB wilt gebruiken, hebt u de Azure Tables SDK nodig voor Node.js, waaronder een set handige bibliotheken die communiceren met de Storage REST-services.

Node Package Manager (NPM) gebruiken om het pakket te installeren

  1. Gebruik een opdrachtregelinterface zoals PowerShell (Windows), Terminal (Mac) of Bash (Unix) en ga naar de map waar u uw toepassing hebt gemaakt.
  2. Typ het volgende in het opdrachtvenster:
   npm install @azure/data-tables
  1. U kunt de ls-opdracht handmatig uitvoeren om te controleren of een node_modules-map is gemaakt. In die map vindt u het pakket @azure/gegevenstabellen , dat de bibliotheken bevat die u nodig hebt voor toegang tot tabellen.

Het pakket importeren

Voeg de volgende code toe aan het begin van het server.js-bestand in uw toepassing:

const { TableServiceClient, TableClient, AzureNamedKeyCredential, odata } = require("@azure/data-tables");

Verbinding maken met Azure Table-service

U kunt verbinding maken met het Azure-opslagaccount of het Azure Cosmos DB for Table-account. Haal de gedeelde sleutel of verbindingsreeks op op basis van het type account dat u gebruikt.

De Table Service-client maken op basis van een gedeelde sleutel

De Azure-module leest de omgevingsvariabelen AZURE_ACCOUNT en AZURE_ACCESS_KEY en AZURE_TABLES_ENDPOINT voor informatie die nodig is om verbinding te maken met uw Azure Storage-account of Azure Cosmos DB. Als deze omgevingsvariabelen niet zijn ingesteld, moet u de accountgegevens opgeven bij het aanroepen van TableServiceClient. Zo wordt met de volgende code een TableServiceClient-object gemaakt:

const endpoint = "<table-endpoint-uri>";
const credential = new AzureNamedKeyCredential(
  "<account-name>",
  "<account-key>"
);

const tableService = new TableServiceClient(
  endpoint,
  credential
);

De Table-serviceclient maken op basis van een verbindingsreeks

Als u een Verbinding met een Azure Cosmos DB- of Opslagaccount wilt toevoegen, maakt u een TableServiceClient object en geeft u uw accountnaam, primaire sleutel en eindpunt op. U kunt deze waarden kopiëren uit Instellingen> Verbinding maken ion string in Azure Portal voor uw Azure Cosmos DB-account of opslagaccount. Voorbeeld:

const tableService = TableServiceClient.fromConnectionString("<connection-string>");

Een tabel maken

Met de aanroep van createTable wordt een nieuwe tabel met de opgegeven naam gemaakt als de tabel nog niet bestaat. In het volgende voorbeeld wordt een nieuwe tabel genaamd 'mytable' gemaakt als deze nog niet bestaat:

await tableService.createTable('<table-name>');

De tabelclient maken

Als u met een tabel wilt werken, moet u een TableClient object maken met dezelfde referenties die u hebt gebruikt om de TableServiceClienttabel te maken. Hiervoor TableClient is ook de naam van de doeltabel vereist.

const tableClient = new TableClient(
  endpoint,
  '<table-name>',
  credential
);

Een entiteit toevoegen aan een tabel

Wanneer u een entiteit wilt toevoegen, moet u eerst een object maken dat uw entiteitseigenschappen definieert. Alle entiteiten moeten een partitionKey en rowKey bevatten. Dit zijn unieke id's voor de entiteit.

  • partitionKey : bepaalt de partitie waarin de entiteit wordt opgeslagen.
  • rowKey : identificeert de entiteit in de partitie uniek.

Zowel partitionKey als rowKey moeten tekenreekswaarden zijn.

Hier volgt een voorbeeld van het definiëren van een entiteit. dueDate is gedefinieerd als een type van Date. Het specificeren van het type is optioneel en als dit niet wordt opgegeven, wordt het type afgeleid.

const task = {
  partitionKey: "hometasks",
  rowKey: "1",
  description: "take out the trash",
  dueDate: new Date(2015, 6, 20)
};

Notitie

Er is ook een veld Timestamp voor elke record. Dit wordt door Azure ingesteld wanneer een entiteit wordt ingevoegd of bijgewerkt.

Wanneer u een entiteit wilt toevoegen aan de tabel, geeft u het entiteitsobject door aan de createEntity-methode.

let result = await tableClient.createEntity(task);
    // Entity create

Als de bewerking is geslaagd, result bevat u de ETag en informatie over de bewerking.

Voorbeeld van een reactie:

{ 
  clientRequestId: '94d8e2aa-5e02-47e7-830c-258e050c4c63',
  requestId: '08963b85-1002-001b-6d8c-12ae5d000000',
  version: '2019-02-02',
  date: 2022-01-26T08:12:32.000Z,
  etag: `W/"datetime'2022-01-26T08%3A12%3A33.0180348Z'"`,
  preferenceApplied: 'return-no-content',
  'cache-control': 'no-cache',
  'content-length': '0'
}

Een entiteit bijwerken

De verschillende modi voor updateEntity en upsertEntity methoden

  • Samenvoegen: Hiermee wordt een entiteit bijgewerkt door de eigenschappen van de entiteit bij te werken zonder de bestaande entiteit te vervangen.
  • Vervangen: Hiermee wordt een bestaande entiteit bijgewerkt door de hele entiteit te vervangen.

Het volgende voorbeeld laat zien hoe u een entiteit bijwerkt met upsertEntity:

// Entity doesn't exist in table, so calling upsertEntity will simply insert the entity.
let result = await tableClient.upsertEntity(task, "Replace");

Als de entiteit die wordt bijgewerkt niet bestaat, mislukt de updatebewerking; Als u daarom een entiteit wilt opslaan, ongeacht of deze al bestaat, gebruikt u upsertEntity.

De result voor geslaagde updatebewerkingen bevat de Etag van de bijgewerkte entiteit.

Werken met groepen entiteiten

Soms is het zinvol om meerdere bewerkingen samen in een batch te verzenden om te zorgen dat ze atomisch worden verwerkt door de server. Hiervoor maakt u een matrix met bewerkingen en geeft u deze door aan de submitTransaction methode op TableClient.

In het volgende voorbeeld ziet u hoe u twee entiteiten in een batch kunt verzenden.

const task1 = {
  partitionKey: "hometasks",
  rowKey: "1",
  description: "Take out the trash",
  dueDate: new Date(2015, 6, 20)
};
const task2 = {
  partitionKey: "hometasks",
  rowKey: "2",
  description: "Wash the dishes",
  dueDate: new Date(2015, 6, 20)
};

const tableActions = [
  ["create", task1],
  ["create", task2]
];

let result = await tableClient.submitTransaction(tableActions);
    // Batch completed

Voor geslaagde batchbewerkingen bevat result informatie voor elke bewerking in de batch.

Een entiteit ophalen op basis van sleutel

Als u een specifieke entiteit wilt retourneren op basis van de PartitionKey en RowKey, gebruikt u de methode getEntity.

let result = await tableClient.getEntity("hometasks", "1")
  .catch((error) => {
    // handle any errors
  });
  // result contains the entity

Nadat u deze bewerking is voltooid, bevat result de entiteit.

Een query uitvoeren voor een aantal entiteiten

In het volgende voorbeeld wordt een query gemaakt die de vijf belangrijkste items retourneert met een PartitionKey van 'hometasks' en alle entiteiten in de tabel weer geeft.

const topN = 5;
const partitionKey = "hometasks";

const entities = tableClient.listEntities({
  queryOptions: { filter: odata`PartitionKey eq ${partitionKey}` }
});

let topEntities = [];
const iterator = entities.byPage({ maxPageSize: topN });

for await (const page of iterator) {
  topEntities = page;
  break;
}

// Top entities: 5
console.log(`Top entities: ${topEntities.length}`);

// List all the entities in the table
for await (const entity of entities) {
console.log(entity);
}

Een query uitvoeren op een subset van entiteitseigenschappen

Met een query naar een tabel kunnen slechts enkele velden van een entiteit worden opgehaald. Dit verbruikt minder bandbreedte en kan de queryprestaties verbeteren, vooral bij grote entiteiten. Gebruik de select-component en geef de namen door van de velden die moeten worden geretourneerd. De volgende query retourneert bijvoorbeeld alleen de velden description en dueDate.

const topN = 5;
const partitionKey = "hometasks";

const entities = tableClient.listEntities({
  queryOptions: { filter: odata`PartitionKey eq ${partitionKey}`,
                  select: ["description", "dueDate"]  }
});

let topEntities = [];
const iterator = entities.byPage({ maxPageSize: topN });

for await (const page of iterator) {
  topEntities = page;
  break;
}

Een entiteit verwijderen

U kunt een entiteit verwijderen met behulp van zijn partities en rijsleutels. In dit voorbeeld bevat het taak1-object de waarden rowKey en partitionKey van de entiteit die u wilt verwijderen. Het object wordt doorgegeven aan de deleteEntity-methode.

const tableClient = new TableClient(
  tablesEndpoint,
  tableName,
  new AzureNamedKeyCredential("<accountName>", "<accountKey>")
);

await tableClient.deleteEntity("hometasks", "1");
    // Entity deleted

Notitie

Overweeg het gebruik van ETags bij het verwijderen van items om zeker te weten dat het item niet is gewijzigd door een ander proces. Zie Een entiteit bijwerken voor informatie over het gebruik van ETags.

Een tabel verwijderen

Met de volgende code wordt een tabel uit een opslagaccount verwijderd.

await tableClient.deleteTable(mytable);
        // Table deleted

Vervolgtokens gebruiken

Wanneer u query's uitvoert op tabellen en veel resultaten krijgt, let dan op de vervolgtokens. Mogelijk zijn er zonder dat u het weet grote hoeveelheden gegevens beschikbaar voor uw query als u in uw query geen rekening hebt gehouden met de aanwezigheid van vervolgtokens.

Het results-object geretourneerd tijdens het uitvoeren van een query op entiteitensets, stelt een continuationToken-eigenschap in wanneer een dergelijk token aanwezig is. Vervolgens kunt u deze bij het uitvoeren van een query gebruiken om door te gaan in de partitie- en tabelentiteiten.

Wanneer u een query uitvoert, kunt u een continuationToken-parameter opgeven tussen de queryobjectinstantie en de retouraanroepfunctie:

let iterator = tableClient.listEntities().byPage({ maxPageSize: 2 });
let interestingPage;

const page = await tableClient
   .listEntities()
   .byPage({ maxPageSize: 2, continuationToken: interestingPage })
   .next();

 if (!page.done) {
   for (const entity of page.value) {
     console.log(entity.rowKey);
   }
 }

Werken met handtekeningen voor gedeelde toegang

Shared Access Signatures (SAS) zijn een veilige manier om op detailniveau toegang te bieden tot tabellen zonder dat u de naam of sleutels van uw opslagaccount hoeft te geven. SAS wordt vaak gebruikt voor beperkte toegang tot uw gegevens, bijvoorbeeld om een mobiele app toe te staan om een query uit te voeren op records.

Een vertrouwde toepassing, zoals een cloudservice, genereert een SAS met behulp van de generateTableSas van de TableClient en biedt deze aan een niet-vertrouwde of semi-vertrouwde toepassing, zoals een mobiele app. De SAS wordt gegenereerd op basis van beleid, waarin de begin- en einddatum wordt vermeld voor de geldigheid van de SAS, evenals het toegangsniveau verleend aan de SAS-houder.

In het volgende voorbeeld wordt een nieuw beleid voor gedeelde toegang gegenereerd waarmee de SAS-houder de tabel kan opvragen ('r').

const tablePermissions = {
    query: true
// Allows querying entities
};

// Create the table SAS token
const tableSAS = generateTableSas('mytable', cred, {
  expiresOn: new Date("2022-12-12"),
  permissions: tablePermissions
});

De clienttoepassing gebruikt vervolgens de SAS met AzureSASCredential om bewerkingen uit te voeren op basis van de tabel. In het volgende voorbeeld wordt verbinding gemaakt met de tabel en een query uitgevoerd. Zie het artikel Beperkte toegang verlenen tot Azure Storage-resources via SAS (Shared Access Signatures) voor de indeling van tableSAS.

// Note in the following command, tablesUrl is in the format: `https://<your_storage_account_name>.table.core.windows.net` and the tableSAS is in the format: `sv=2018-03-28&si=saspolicy&tn=mytable&sig=9aCzs76n0E7y5BpEi2GvsSv433BZa22leDOZXX%2BXXIU%3D`;

const tableService = new TableServiceClient(tablesUrl, new AzureSASCredential(tableSAS));
const partitionKey = "hometasks";

const entities = tableService.listTables({
  queryOptions: { filter: odata`PartitionKey eq ${partitionKey}` }
});

Omdat de SAS alleen querytoegang biedt, wordt er een fout geretourneerd als u entiteiten wilt invoegen, bijwerken of verwijderen.

Toegangsbeheerlijsten

U kunt ook een ACL (Access Control List) gebruiken om het toegangsbeleid in te stellen voor een SAS. Dit is handig als u meerdere clients toegang wilt geven tot de tabel, maar voor elke client een ander toegangsbeleid wilt instellen.

Een ACL wordt geïmplementeerd met behulp van een matrix van toegangsbeleidregels, met een id die is gekoppeld aan elk beleid. In het volgende voorbeeld worden twee beleidsregels gedefinieerd, één voor 'gebruiker1' en één voor 'gebruiker2':

var sharedAccessPolicy = [{
  id:"user1",
  accessPolicy:{
    permission: "r" ,
    Start: startsOn,
    Expiry: expiresOn,
  }},
  {
  id:"user2",
  accessPolicy:{
    permissions: "a",
    Start: startsOn,
    Expiry: expiresOn,
  }},
]

In het volgende voorbeeld wordt de huidige ACL voor de hometasks-tabel opgehaald en wordt vervolgens het nieuwe beleid toegevoegd met behulp van setAccessPolicy. Deze aanpak biedt u de volgende mogelijkheid:

tableClient.getAccessPolicy();
tableClient.setAccessPolicy(sharedAccessPolicy);

Nadat de ACL is ingesteld, kunt u een SAS maken op basis van de id van een beleid. In het volgende voorbeeld wordt een nieuwe SAS voor 'gebruiker2' gemaakt:

tableSAS = generateTableSas("hometasks",cred,{identifier:'user2'});

Volgende stappen

Zie de volgende informatie bronnen voor meer informatie: