【问题标题】:Query other tables in insert function of Azure Table Storage在 Azure 表存储的插入功能中查询其他表
【发布时间】:2019-02-13 22:55:27
【问题描述】:

我正在使用 Azure 表存储在插入新项目后发送推送通知。目前我正在尝试查询第二个表以检索我想用于推送通知的字符串。

我对 Node.js 还是很陌生,所以我编写了一些代码并尝试了以下方法来启动对 TestTable 的查询,以根据 TestProperty 找到正确的实体。找到正确的实体后,我想使用其中的特定属性进行处理。

这是我使用当前代码时遇到的错误:

TypeError: Cannot read property 'table' of undefined

我尝试查询第二个表的部分代码

var azureMobileApps = require('azure-mobile-apps'),
tables = require('azure-mobile-apps/src/express/tables'),
queries = require('azure-mobile-apps/src/query'),
logger = require('azure-mobile-apps/src/logger');

var table = azureMobileApps.table();

table.insert(function (context) {
    logger.info('Running TestTable1.insert');
    var testTable = azureMobileApps.tables.table('TestTable2');
    var query = queries.create('TestTable2').where({ TestProperty : context.item.testproperty }); 

    return context.execute()
        .then(function (results) {
        .....

【问题讨论】:

    标签: javascript node.js azure azure-table-storage azure-mobile-services


    【解决方案1】:

    由于 Azure 表存储是一种在云端存储非结构化 NoSQL 数据的服务,您可以参考https://azure.microsoft.com/en-us/documentation/articles/storage-dotnet-how-to-use-tables/ 了解更多信息。

    但是,azure-mobile-apps-node sdk 中的 tables 模块包含将表添加到 Azure 移动应用程序的功能。它返回一个路由器,该路由器可以附加到一个快速应用程序,并具有一些用于注册表的附加功能。它实际上利用了 Azure SQL(Azure 上的 SQL Server 数据库服务)。

    根据您的代码 sn-p,您似乎正在实施第二个概念。

    而且根据你的描述,如果我没有误解,你想在 EasyTables 脚本中的table1 操作中查询table2

    我们可以利用“use()”自定义中间件来指定要为针对表的每个请求执行的中间件,作为 azure-mobile-apps sdk 文档http://azure.github.io/azure-mobile-apps-node/module-azure-mobile-apps_express_tables_table.html#~use 上的描述。

    例如

    var queries = require('azure-mobile-apps/src/query');
    var insertMiddleware = function(req,res,next){
        var table = req.azureMobile.tables('table2'),
        query = queries.create('table2')
                .where({ TestProperty : req.body.testproperty });
        table.read(query).then(function(results) {
            if(results){
                req.someStoreData = somehander(results); //some hander operations here to get what you want to store and will use in next step
                next();
            }else{
                res.send("no data");
            }
        });
    };
    
    table.insert.use(insertMiddleware, table.operation);
    table.insert(function (context) {
       console.log(context.req.someStoreData);
       return context.execute();
    });
    

    另外,如果需要在 EasyTables 脚本中推送通知,可以参考 Github 上的示例https://github.com/Azure/azure-mobile-apps-node/blob/master/samples/push-on-insert/tables/TodoItem.js

    【讨论】:

    • 感谢您的回答 - 它帮助我更多地了解后端。我还有一个问题。当我使用 table.insert.use(insertMiddleware) 时,我没有可以访问插入项的上下文变量。你能帮我解决这个问题吗?
    • 中间件会在表操作之前运行,中间件接受requestresponsenext三个参数,更多可以参考expressjs.com/en/guide/writing-middleware.html。顺便说一句,对于我的道歉,我在代码 sn-p 中做错了,应该有一个context,如果我们想要获取变量,我们可以使用一些中间件,如body-parser,更多信息请参考expressjs.com/en/resources/middleware.html
    • 您很有帮助 - 我开始了解如何使用它。还有一件事你可以帮助我!我现在在结果变量中得到所需的值(似乎是一个数组)。我可以将结果变量的一个值存储在全局变量中,以便稍后在主 table.insert 函数中使用它吗?谢谢
    • 如果你只是想在下一步使用数据,一般情况下,我们不需要存储在全局变量中。请查看我的更新代码(我也修复了您可能会出现的几个问题)。而在node.js中,我们可以使用global.somevalue= somevalue来定义一个全局变量,参考hacksparrow.com/global-variables-in-node-js.html
    • 工作得很好!非常感谢!
    【解决方案2】:

    谢谢加里。这是非常有帮助的。 为了完成你的答案,你现在可以这样写:

    async function filterByAllowedDomain(context) {
      var domains = await context.tables('domains')
        .where({ allowed: true })
        .read();
    
      var categories = await context.tables('categories')
        .where(function (ids) {
            return this.domainId in ids;
        }, domains.map(d => d.id))
        .read();
    
      context.query.where(function (ids) {
        return this.categoryId in ids;
      }, categories.map(c => c.id));
    
      return context.execute(); }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-03-16
      • 1970-01-01
      • 2022-09-15
      • 1970-01-01
      • 2019-03-16
      • 1970-01-01
      • 2011-05-12
      相关资源
      最近更新 更多