web-dev-qa-db-fra.com

Sequelize: utilisation de plusieurs bases de données

Dois-je créer plusieurs instances de Sequelize si je veux utiliser deux bases de données? Autrement dit, deux bases de données sur la même machine.

Sinon, quelle est la bonne façon de procéder? Il me semble exagéré de devoir me connecter deux fois pour utiliser deux bases de données, pour moi.

Ainsi, par exemple, j'ai différentes bases de données pour différentes fonctions, par exemple, disons que j'ai des données clients dans une base de données et des données statistiques dans une autre.

Donc, dans MySQL:

MySQL [customers]> show databases;
+--------------------+
| Database           |
+--------------------+
| customers          |
| stats              |
+--------------------+

Et je dois cela pour me connecter avec suite

// Create a connection....
var Sequelize = require('sequelize');
var sequelize = new Sequelize('customers', 'my_user', 'some_password', {
    Host: 'localhost',
    dialect: 'mysql',

    pool: {
        max: 5,
        min: 0,
        idle: 10000
    },
    logging: function(output) {
        if (opts.log_queries) {
            log.it("sequelize_log",{log: output});
        }
    }

});

// Authenticate it.
sequelize.authenticate().nodeify(function(err) {

    // Do stuff....

});

J'ai essayé de le "tromper" en définissant un modèle en utilisant la notation par points

var InterestingStatistics = sequelize.define('stats.interesting_statistics', { /* ... */ });

Mais cela crée la table customers.stats.interesting_statistics. J'ai besoin d'utiliser une table existante dans la base de données de statistiques.

Quelle est la bonne façon d'y parvenir? Merci.

14
dougBTV

Vous devez créer différentes instances de séquencement pour chaque connexion DB que vous souhaitez créer:

const Sequelize = require('Sequelize');
const userDb = new Sequelize(/* ... */);
const contentDb = new Sequelize(/* ... */);

Chaque instance créée à partir de sequelize a ses propres informations de base de données (db Host, url, user, pass, etc ...), et ces valeurs ne sont pas censées être modifiées, il n'y a donc pas de " correcte "pour créer plusieurs connexions avec une seule instance de séquelle.

À partir de leurs documents :

Sequelize configurera un pool de connexions lors de l'initialisation, vous devriez donc idéalement ne créer qu'une seule instance par base de données.

Une instance par base de données

Une approche "courante" pour ce faire consiste à disposer vos bases de données dans un config.json fichier et boucle dessus pour créer des connexions dinamicalement, quelque chose comme ça peut-être:

config.json

{
    /*...*/
    databases: {
        user: {
            path: 'xxxxxxxx'
        },
        content: {
            path: 'xxxxxxxx'
        }
    }
}

Votre application

const Sequelize = require('sequelize');
const config = require('./config.json');

// Loop through
const db = {};
const databases = Object.keys(config.databases);
for(let i = 0; i < databases.length; ++i) {
    let database = databases[i];
    let dbPath = config.databases[database];
    db[database] = new Sequelize( dbPath );
}

// Or a one liner
const db = Object.entries(config).reduce((r, db) => (r[db[0]] = db[1].path) && r, {});

// Sequelize instances:
// db.user
// db.content

Vous aurez besoin de faire un peu plus de codage pour le faire fonctionner, mais c'est une idée générale.

27
Aramil Rey

Pourquoi n'utilisez-vous pas la requête brute? Avec cela, vous pouvez vous connecter à une base de données et interroger l'autre. Voir l'exemple de code ci-dessous.

const sequelize = require('db_config');
function test(req, res){
  const qry = `SELECT * FROM db1.affiliates_order co
LEFT JOIN db2.affiliates m ON m.id = co.campaign_id`;
  sequelize.query(qry, null, {  raw: true}).then(result=>{
    console.log(result);
  })
}
1
Y Talansky

si vous essayez d'associer des objets dans le même RDS sur plusieurs bases de données, vous pouvez utiliser schema.

http://docs.sequelizejs.com/class/lib/model.js~Model.html#static-method-schema

cela ajoutera le nom de la base de données au nom de la table, donc, probablement, vos requêtes sortiront comme: SELECT A.ColA, B.ColB FROM SchemaA.ATable A INNER JOIN SchemaB.BTable B ON B.BId = A.BId

0
john ellis