loopbackjs: Attach a model to different datasources

前端 未结 3 1559
予麋鹿
予麋鹿 2021-01-02 16:14

I have defined several models that use a Datasource \"db\" (mysql) for my environment.

Is there any way to have several datasources attached to those models, so I wo

3条回答
  •  被撕碎了的回忆
    2021-01-02 16:57

    For anyone still looking for a working answer to this, the solution for switching databases on the fly was to write a middleware script that examined the request path and then created a new DataSource connector, passing in a variable based on the req.path variable. For example, if the request path is /orders, then "orders" as a string would be saved in a variable, then we attached a new Datasource, passing in that variable for "orders". Here's the complete working code.

    'use strict';
    
    const DataSource = require('loopback-datasource-juggler').DataSource;
    const app = require('../server.js');
    
    module.exports = function() {
      return function datasourceSelector(req, res, next) {
      // Check if the API request path contains one of our models.
      // We could use app.models() here, but that would also include
      // models we don't want.
      let $models = ['offers', 'orders', 'prducts'];
      // $path expects to be 'offers', 'orders', 'prducts'.
      let $path = req.path.toLowerCase().split("/")[1];
    
      // Run our function if the request path is equal to one of
      // our models, but not if it also includes 'count'. We don't
      // want to run this twice unnecessarily.
      if (($models.includes($path, 0)) && !(req.path.includes('count'))) {
        // The angular customer-select form adds a true value
        // to the selected property of only one customer model.
        // So we search the customers for that 'selected' = true.
        let customers = app.models.Customer;
        // Customers.find() returns a Promise, so we need to get
        // our selected customer from the results.
        customers.find({"where": {"selected": true}}).then(function(result){
          // Called if the operation succeeds.
          let customerDb = result[0].name;
          // Log the selected customer and the timestamp
          // it was selected. Needed for debugging and optimization.
          let date = new Date;
          console.log(customerDb, $path+req.path, date);
          // Use the existing veracore datasource config
          // since we can use its environment variables.
          let settings = app.dataSources.Veracore.settings;
          // Clear out the veracore options array since that
          // prevents us from changing databases.
          settings.options = null;
          // Add the selected customer to the new database value.
          settings.database = customerDb;
          try {
            let dataSource = new DataSource(settings);
            // Attach our models to the new database selection.
            app.models.Offer.attachTo(dataSource);
            app.models.Order.attachTo(dataSource);
            app.models.Prduct.attachTo(dataSource);
          } catch(err) {
            console.error(err);
          }
        })
        // Called if the customers.find() promise fails.
        .catch(function(err){
          console.error(err);
        });
      }
      else {
        //  We need a better solution for paths like '/orders/count'.
        console.log(req.path + ' was passed to datasourceSelector().');
      }
      next();
      };
    };
    

提交回复
热议问题