刪除 Azure Table 裡所有使用者記錄的問題

今天遇到的問題是 Azure TableStorage 使用上的問題,我們的系統使用了一個 table來記錄使用者註冊時相關的資料,像是 email、facebook帳號… 這個 table 的 partition key 是 type,像是 “email” | “phone” | “facebook”… row key 則為儲存的 data,然後有一個欄位 userId,當使用者使用 email 來登錄系統時,我們就可以用像 pk=”email” rk=”user@gmail.com” 這樣的查詢很快的找到使用者是不是已經登錄過了。

我們的後台有個清除使用者資料的功能,可以用 userId 來清除相關的記錄,最近發現這個程式沒辦法清除所有的資料,而殘留的資料導致測試帳號不能再重複使用。原來清除記錄的程式如下:

var query = new azure.TableQuery().where("userId eq ?", userid);
tableService.queryEntities(tableName, query, null, null, async (err, results) => {
    for (var i = 0; i < results.entries.length; i++) {
        var pk = (<any>results.entries[i]).PartitionKey._;
        var rk = (<any>results.entries[i]).RowKey._;
        Logger.info("deleting table row from accounts.", pk, rk);
        log += "delete:" + pk + "," + rk + "\r\n";
        var deletingAccount = new TableContext.AccountInfo(pk, rk);
        await accountTableContext.deleteAsync(deletingAccount);
    }
});

修改後的程式如下:

let token;

const queryAndDeleteEntities = (tbl, qry, tok) => {
    tableService.queryEntities(tbl, qry, tok, (err, result) => {
        if (err) throw err;

        result.entries.forEach(e => {
            const row = new TableContext.AccountInfo((<any>e).PartitionKey._, (<any>e).RowKey._);
            accountTableContext.deleteAsync(row).then(result => {
                console.log("row deleted.", row, result);
            });
        });

        if (result.continuationToken) {
            queryAndDeleteEntities(tbl, qry, result.continuationToken);
        }
    });
};

queryAndDeleteEntities(tableName, query, token);

原本的程式犯了兩個錯誤,修正如下:

  1. line #4 tableService.queryEntities() 是 async function 整個程式的執行不會停下來,所以在裡面放 log += … 是認知上的錯誤,程式結尾所得到的 log 不會有 callback function 裡執行的東西。
  2. line #14 在查詢 Azure TableStorage 時因為不是 pk/rk 的 query,所以 Azure 會先傳回一部份資料,然後會在 result 上加個 continuationToken,我們必須要使用這個 token 再去要資料回來直到 Azure 告知沒有 continuation token 才結束。

因為須要呼叫 query and delete 好幾次,所以在 line #3 定義了 arrow function,然後在 line #20 才呼叫。

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s