续集:MariaDB和Postgres之间的多对多关系

时间:2019-06-23 12:54:09

标签: postgresql mariadb sequelize.js

小背景故事
这是我的情况,我的MariaDB中有一个名为Location的数据库,而我的Postgres中有一个User的数据库。我想将其中两个链接到我的Postgres DB中。因此,我有两个表usersuserLocations。哦,是的,值得注意的是,我只能从LocationDB读取(选择并创建视图),并且以root用户身份连接到UserDB。是的,我已经成功authenticate()他们两个。我什至可以从LocationDB接收数据,但是现在唯一的问题是在UserLocation之间建立这种关系。错误日志位于底部。

这是我的模特:
models/user.js

// ... Connection to UserDB (uses Postgres)
const UserDB = require('../datasources/user-db')

const User = UserDB.define('user', {
  id: { type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true },
  name: { type: Sequelize.STRING, allowNull: false }
})
module.exports = User

models/location.js

// Connection to LocationDB (uses MariaDB)
const LocationDB = require('../datasources/location-db')

const Location = LocationDB.define('ms_location', {
  id_Location: { type: Sequelize.INTEGER, primaryKey: true },
  name_Location: { type: Sequelize.STRING, allowNull: false }
}, { timestamps: false, freezeTableName: true })
module.exports = Location

models/user-location.js

// ... Connection to UserDB (uses Postgres)
const UserDB = require('../datasources/user-db')

const UserLocation = UserDB.define('userLocation', {
  id: { type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true }
})
module.exports = UserLocation

app.js

const Location = require('./models/location')
const User     = require('./models/user')
const UserLocation = require('./models/user-location')

User.belongsToMany(Location, { through: UserLocation })

这是此案例的精简版,如果您需要更多信息,请问一下,因为我还是sequelize的新手

错误日志:(对不起,我没有美化它的想法)

{ SequelizeDatabaseError: relation "ms_location" does not exist
    at Query.formatError (<path-to-project>/node_modules/.registry.npmjs.org/sequelize/5.8.6/node_modules/sequelize/lib/dialects/postgres/query.js:354:16)
    at query.catch.err (<path-to-project>/node_modules/.registry.npmjs.org/sequelize/5.8.6/node_modules/sequelize/lib/dialects/postgres/query.js:71:18)
    at tryCatcher (<path-to-project>/node_modules/.registry.npmjs.org/bluebird/3.5.5/node_modules/bluebird/js/release/util.js:16:23)
    at Promise._settlePromiseFromHandler (<path-to-project>/node_modules/.registry.npmjs.org/bluebird/3.5.5/node_modules/bluebird/js/release/promise.js:517:31)
    at Promise._settlePromise (<path-to-project>/node_modules/.registry.npmjs.org/bluebird/3.5.5/node_modules/bluebird/js/release/promise.js:574:18)
    at Promise._settlePromise0 (<path-to-project>/node_modules/.registry.npmjs.org/bluebird/3.5.5/node_modules/bluebird/js/release/promise.js:619:10)
    at Promise._settlePromises (<path-to-project>/node_modules/.registry.npmjs.org/bluebird/3.5.5/node_modules/bluebird/js/release/promise.js:695:18)
    at _drainQueueStep (<path-to-project>/node_modules/.registry.npmjs.org/bluebird/3.5.5/node_modules/bluebird/js/release/async.js:138:12)
    at _drainQueue (<path-to-project>/node_modules/.registry.npmjs.org/bluebird/3.5.5/node_modules/bluebird/js/release/async.js:131:9)
    at Async._drainQueues (<path-to-project>/node_modules/.registry.npmjs.org/bluebird/3.5.5/node_modules/bluebird/js/release/async.js:147:5)
    at Immediate.Async.drainQueues [as _onImmediate] (<path-to-project>/node_modules/.registry.npmjs.org/bluebird/3.5.5/node_modules/bluebird/js/release/async.js:17:14)
    at runCallback (timers.js:705:18)
    at tryOnImmediate (timers.js:676:5)
    at processImmediate (timers.js:658:5)
  name: 'SequelizeDatabaseError',
  parent:
   { error: relation "ms_location" does not exist
       at Connection.parseE (<path-to-project>/node_modules/.registry.npmjs.org/pg/7.11.0/node_modules/pg/lib/connection.js:602:11)
       at Connection.parseMessage (<path-to-project>/node_modules/.registry.npmjs.org/pg/7.11.0/node_modules/pg/lib/connection.js:399:19)
       at Socket.<anonymous> (<path-to-project>/node_modules/.registry.npmjs.org/pg/7.11.0/node_modules/pg/lib/connection.js:121:22)
       at Socket.emit (events.js:189:13)
       at addChunk (_stream_readable.js:284:12)
       at readableAddChunk (_stream_readable.js:265:11)
       at Socket.Readable.push (_stream_readable.js:220:10)
       at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)
     name: 'error',
     length: 107,
     severity: 'ERROR',
     code: '42P01',
     detail: undefined,
     hint: undefined,
     position: undefined,
     internalPosition: undefined,
     internalQuery: undefined,
     where: undefined,
     schema: undefined,
     table: undefined,
     column: undefined,
     dataType: undefined,
     constraint: undefined,
     file: 'namespace.c',
     line: '426',
     routine: 'RangeVarGetRelidExtended',
     sql:
      'CREATE TABLE IF NOT EXISTS "userLocations" ("id"  SERIAL , "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" INTEGER REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE, "msLocationIdLocation" INTEGER REFERENCES "ms_location" ("id_Location") ON DELETE CASCADE ON UPDATE CASCADE, UNIQUE ("userId", "msLocationIdLocation"), PRIMARY KEY ("id"));' },
  original:
   { error: relation "ms_location" does not exist
       at Connection.parseE (<path-to-project>/node_modules/.registry.npmjs.org/pg/7.11.0/node_modules/pg/lib/connection.js:602:11)
       at Connection.parseMessage (<path-to-project>/node_modules/.registry.npmjs.org/pg/7.11.0/node_modules/pg/lib/connection.js:399:19)
       at Socket.<anonymous> (<path-to-project>/node_modules/.registry.npmjs.org/pg/7.11.0/node_modules/pg/lib/connection.js:121:22)
       at Socket.emit (events.js:189:13)
       at addChunk (_stream_readable.js:284:12)
       at readableAddChunk (_stream_readable.js:265:11)
       at Socket.Readable.push (_stream_readable.js:220:10)
       at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)
     name: 'error',
     length: 107,
     severity: 'ERROR',
     code: '42P01',
     detail: undefined,
     hint: undefined,
     position: undefined,
     internalPosition: undefined,
     internalQuery: undefined,
     where: undefined,
     schema: undefined,
     table: undefined,
     column: undefined,
     dataType: undefined,
     constraint: undefined,
     file: 'namespace.c',
     line: '426',
     routine: 'RangeVarGetRelidExtended',
     sql:
      'CREATE TABLE IF NOT EXISTS "userLocations" ("id"  SERIAL , "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" INTEGER REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE, "msLocationIdLocation" INTEGER REFERENCES "ms_location" ("id_Location") ON DELETE CASCADE ON UPDATE CASCADE, UNIQUE ("userId", "msLocationIdLocation"), PRIMARY KEY ("id"));' },
  sql:
   'CREATE TABLE IF NOT EXISTS "userLocations" ("id"  SERIAL , "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL, "userId" INTEGER REFERENCES "users" ("id") ON DELETE CASCADE ON UPDATE CASCADE, "msLocationIdLocation" INTEGER REFERENCES "ms_location" ("id_Location") ON DELETE CASCADE ON UPDATE CASCADE, UNIQUE ("userId", "msLocationIdLocation"), PRIMARY KEY ("id"));' }

1 个答案:

答案 0 :(得分:1)

您已经告诉Sequelize,您有一个名为user的表和一个名为msLocation的表,并且两者通过另一个名为userLocation的表相关。 (或者是userLocations?您的代码和错误消息不一致。)

看起来Sequelize试图创建userLocationsUserDB,但是失败了,因为作为表定义的一部分,它试图创建对ms_location的外键引用:

"msLocationIdLocation" INTEGER REFERENCES "ms_location" ("id_Location")
ON DELETE CASCADE ON UPDATE CASCADE

失败,因为ms_location不在UserDB中,而在另一个数据库中。

我不知道Sequelize是否可以实际处理跨越多个数据库服务器的表,但我对此表示怀疑。创建跨越同一数据库中两个表的查询很容易,Sequelize可以只创建一个联接。如果表位于两个不同的服务器上,那就完全不一样了。现在,Sequelize将必须运行两个不同的查询并执行内存中的所有联接逻辑。这是一个很大的提升。

某些数据库可以在一个数据库中创建一个表,该表可以复制或转发到另一个数据库中的表。如果PostgreSQL支持这一点,则可以尝试使用它来复制或隐藏MariaDB表,这将使Sequelize将所有表视为UserDB的一部分。