代码之家  ›  专栏  ›  技术社区  ›  Sameer

如何根据每个客户端动态连接mysql数据库?

  •  0
  • Sameer  · 技术社区  · 8 年前

    我在这里使用mean stack m=mysql构建一个saas产品

    我使用sequelize作为orm for mysql,我的连接:

    const sequelize = new Sequelize('smallscale_superapp', 'root', 'root1', {
      host: '127.0.0.1',
      port: 3306,
      dialect: 'mysql',
      logging: false,
    });
    

    例如,我有一个管理超级应用程序,所以我创建了一个业务,例如业务代码 “001ABCD”,此业务代码存储在我的主管理数据库中,然后我告诉我的所有客户端转到一个名为“example.com”的特定URL。

    因此,如果他们输入url,主页将看起来像slack.com有一个输入框,在名为example.com的硬编码值之后

    所以现在我的客户在输入框中输入了我创建的业务代码并存储在我的主数据库中。

    将业务代码放入输入框后,将打开一个名为“001abcd.example.com”的新子域(我正在检查主数据库中的业务代码是否匹配,如果匹配,则创建动态子域)。

    因此,如果一切顺利,在创建子域客户端页面后,将显示为登录屏幕,在那里他们需要注册,注册详细信息需要在那里动态数据库

    注释 :创建业务时,我将在主数据库表中获取客户端数据库、用户名、主机和密码。

    如何使用sequencemysql来实现这一点?

    如何在客户端登录的基础上获得动态连接的续集连接?

    正如我之前所说,我在数据库中有客户机dbname等,我正试图创建这样的连接:

    exports.dynamicDatabase = (req, res) => {
      const { code } = req.params;
      Business.find({
        where: { code },
        raw: true,
      })
        .then((data) => {
          const sequelizeClient = new Sequelize(data.dbname, data.dbusername, data.dbpassword, {
            host: data.dbhost,
            port: 3306,
            dialect: 'mysql',
            logging: false,
          });
        })
        .catch((err) => { res.status(400).send(err.message); });
    };
    

    现在,在这个函数之外,我正尝试同步表,如下所示:

    sequelizeClient.authenticate().then((err) => {
      if (err) {
        console.log('There is connection in ERROR.');
      } else {
        console.log('Dynamic MYSQL Connection has been established successfully');
      }
    });
    sequelizeClient.sync().then(() => {
      console.log('Dynamic Missing Table Created');
    }, (err) => {
      console.log('An error occurred while creating the table:', err.message);
    });
    

    变量 后遗症 在函数内部,所以我无法访问?全球地。

    所以我把变量设为全局变量,但有一个问题

    我在函数中有sequellizeclient变量,这个函数只在url中输入我的域后执行,

    但是sequenceclient.sync()不在函数内部,所以当我启动node server.js时,它会抛出错误:

    sequelizeClient.authenticate().then((err) => {
    [0]                 ^
    [0]
    [0] TypeError: Cannot read property 'authenticate' of undefined
    
    2 回复  |  直到 8 年前
        1
  •  0
  •   Sameer    8 年前

    最后,我尝试了这个方法,并使其有效,但我不知道这是不是好的方法,所以告诉我这是不是好的方法?

    我正在按用户请求参数获取准确的数据:

    let sequelizeClient;
    let Login;
    exports.getDomain = (req, res) => {
      const { code } = req.params;
      Business.find({
        raw: true,
        where: { code },
      }).then((data) => {
        if (data === null) {
          res.status(400).send(data);
        } else {
          sequelizeClient = new Sequelize(data.dbname, data.dbusername, data.dbpassword, {
            host: data.dbhost,
            port: 3306,
            dialect: 'mysql',
            logging: false,
          });
    
          // end user connections
          sequelizeClient.authenticate().then((err) => {
            if (err) {
              console.log('There is connection in ERROR.');
            } else {
              console.log(`${data.code} MYSQL Connection has been established successfully`);
            }
          });
    
          sequelizeClient.sync().then(() => {
            console.log(`${data.code} Missing Table Created`);
          }, (err) => {
            console.log('An error occurred while creating the table:', err.message);
          });
    
          // mysql tables;
          Login = sequelizeClient.define('login', {
            username: Sequelize.STRING,
            firstName: Sequelize.STRING,
            lastName: Sequelize.STRING,
          });
        }
      });
    };
    

    我将表模式变量声明为全局变量,并在代码中使用:

    // api
    exports.signUp = (req, res) => {
      const user = {
        username: req.body.username,
        firstName: req.body.firstName,
        lastName: req.body.lastName,
    
      };
      Login.create(user)
        .then(data => res.status(200).send(data))
        .catch(Sequelize.ValidationError, err => res.status(422).send(err.errors[0].message))
        .catch(err => res.status(400).send(err.message));
    };
    
        2
  •  0
  •   Sameer    8 年前

    是的,经过大量搜索,我发现有三种数据库方法可以构建SaaS产品,

    1. 每个租户的单独数据库
    2. 为所有租户共享表和一个数据库

    最后,我决定使用选项2,我转向了postgresql而不是mysql,因为postgresql有基于模式的方法!

    现在我的最终代码:

    const postgresDB = new Sequelize('postgres://localhost:5432/test_enduser');
    
    postgresDB.authenticate().then((err) => {
      if (err) {
        console.log('There is connection in ERROR.');
      } else {
        console.log('Postgres Connection has been established successfully');
      }
    });
    
    postgresDB.define('inventory', {
      name: Sequelize.STRING,
    });
    
    const createSchema = () => {
      Business.findAll({
        raw: true,
      }).then((data) => {
        data.forEach((client) => {
          postgresDB.createSchema(client.code).then(() => {
            Object.keys(postgresDB.models).forEach((currentItem) => {
              postgresDB.models[currentItem].schema(client.code).sync();
            });
            // new schema is created
            console.log('Postgres schema created');
          }).catch((err) => {
            console.log(err.message);
          });
        });
      });
    };
    createSchema();
    
    
    // apis
    exports.getAllBusiness = (req, res) => {
      postgresDB.models.inventory.schema(req.user.code).findAll()
        .then((results) => {
          res.send(results);
        });
    };
    
    exports.postBusiness = (req, res) => {
      const user = {
        name: req.body.name,
      };
      postgresDB.models.inventory.schema(req.user.code).create(user)
        .then(data => res.status(200).send(data))
        .catch(Sequelize.ValidationError, err => res.status(422).send(err.errors[0].message))
        .catch(err => res.status(400).send(err.message));
    };
    
    1. 我正在设置我的Postgres连接
    2. 为了测试,我正在创建一个名为“inventory”的表
    3. 在我的申请中,一个在线的人来了,他注册了,而我正在那里存储业务代码到我的 业务 表(业务表来自单独的数据库,这是一个超级主应用程序数据库),因此我在postgres中查找业务代码和循环并生成动态模式

    4. 现在看看我的API,我正在基于req.user.code(从登录会话)执行crud,我最终根据特定的模式匹配显示数据,

    最后,我为每个客户机提供了清晰的单独模式。

    谢谢!