每个客户端的 NestJs 多租户数据库 - 错误

Posted

技术标签:

【中文标题】每个客户端的 NestJs 多租户数据库 - 错误【英文标题】:NestJs multitenant database per client - error 【发布时间】:2021-04-30 15:30:41 【问题描述】:

好的!解决这个问题的第 2 天......我将不胜感激:

我正在使用此解决方案:https://github.com/databoxtech/nestjs-multi_tenant-multiple-database

我下载了解决方案,将软件包更新到最新版本如下:package.json


  "name": "school-graph",
  "version": "0.0.1",
  "description": "",
  "author": "",
  "private": true,
  "license": "UNLICENSED",
  "scripts": 
    "prebuild": "rimraf dist",
    "build": "nest build",
    "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
    "start": "nest start",
    "start:dev": "nest start --watch",
    "start:debug": "nest start --debug --watch",
    "start:prod": "node dist/main",
    "lint": "eslint \"src,apps,libs,test/**/*.ts\" --fix",
    "test": "jest",
    "test:watch": "jest --watch",
    "test:cov": "jest --coverage",
    "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
    "test:e2e": "jest --config ./test/jest-e2e.json"
  ,
  "dependencies": 
    "@nestjs/common": "^7.6.5",
    "@nestjs/core": "^7.6.5",
    "@nestjs/graphql": "^7.9.8",
    "@nestjs/jwt": "^7.2.0",
    "@nestjs/mongoose": "^7.2.2",
    "@nestjs/passport": "^7.1.5",
    "@nestjs/platform-express": "^7.6.5",
    "graphql": "^15.4.0",
    "graphql-tools": "^7.0.2",
    "mongoose": "^5.11.13",
    "passport": "^0.4.1",
    "passport-jwt": "^4.0.0",
    "passport-local": "^1.0.0",
    "reflect-metadata": "^0.1.13",
    "rimraf": "^3.0.2",
    "rxjs": "^6.6.3"
  ,
  "devDependencies": 
    "@nestjs/cli": "^7.5.4",
    "@nestjs/schematics": "^7.2.7",
    "@nestjs/testing": "^7.6.5",
    "@types/passport-jwt": "^3.0.3",
    "@types/passport-local": "^1.0.33",
    "@types/supertest": "^2.0.10",
    "@typescript-eslint/eslint-plugin": "^4.14.1",
    "@typescript-eslint/parser": "^4.14.1",
    "eslint": "^7.18.0",
    "eslint-config-prettier": "^7.2.0",
    "eslint-plugin-import": "^2.22.1",
    "jest": "^26.6.3",
    "prettier": "^2.2.1",
    "supertest": "^6.1.2",
    "ts-jest": "^26.4.4",
    "ts-loader": "^8.0.14",
    "ts-node": "^9.1.1",
    "tsconfig-paths": "^3.9.0",
    "typescript": "^4.1.3"
  ,
  "jest": 
    "moduleFileExtensions": [
      "js",
      "json",
      "ts"
    ],
    "rootDir": "src",
    "testRegex": ".spec.ts$",
    "transform": 
      "^.+\\.(t|j)s$": "ts-jest"
    ,
    "coverageDirectory": "../coverage",
    "testEnvironment": "node"
  


运行npm run start 后出现以下错误:

src/database/students/students.module.ts:9:58 - error TS2322: Type 'Schema<Student, Model<Student>>' is not assignable to type 'Schema<Document<any>, Model<Document<any>>>'.
  Type 'Model<Student>' is not assignable to type 'Model<Document<any>>'.
    The types returned by 'createCollection(...)' are incompatible between these types.
      Type 'Promise<Collection<Student>>' is not assignable to type 'Promise<Collection<Document<any>>>'.
        Type 'Collection<Student>' is not assignable to type 'Collection<Document<any>>'.
          Types of property 'bulkWrite' are incompatible.
            Type ' (operations: BulkWriteOperation<Student>[], callback: MongoCallback<BulkWriteOpResultObject>): void; (operations: BulkWriteOperation<...>[], options?: CollectionBulkWriteOptions): Promise<...>; (operations: BulkWriteOperation<...>[], options: CollectionBulkWriteOptions, callback: MongoCallback<...>): void; ' is not assignable to type ' (operations: BulkWriteOperation<Document<any>>[], callback: MongoCallback<BulkWriteOpResultObject>): void; (operations: BulkWriteOperation<...>[], options?: CollectionBulkWriteOptions): Promise<...>; (operations: BulkWriteOperation<...>[], options: CollectionBulkWriteOptions, callback: MongoCallback<...>): void; '.
              Types of parameters 'operations' and 'operations' are incompatible.
                Type 'BulkWriteOperation<Document<any>>[]' is not assignable to type 'BulkWriteOperation<Student>[]'.
                  Type 'BulkWriteOperation<Document<any>>' is not assignable to type 'BulkWriteOperation<Student>'.
                    Type 'BulkWriteInsertOneOperation<Document<any>>' is not assignable to type 'BulkWriteOperation<Student>'.
                      Type 'BulkWriteInsertOneOperation<Document<any>>' is not assignable to type 'BulkWriteInsertOneOperation<Student>'.
                        The types of 'insertOne.document' are incompatible between these types.
                          Type 'Pick<Document<any>, "update" | "get" | "delete" | "set" | "invalidate" | "populate" | "__v" | "$ignore" | "$isDefault" | "$isDeleted" | "$isEmpty" | "$isValid" | "$locals" | ... 39 more ... | "validateSync"> &  ...; ' is not assignable to type 'Pick<Student, "update" | "get" | "delete" | "set" | "invalidate" | "populate" | "__v" | "$ignore" | "$isDefault" | "$isDeleted" | "$isEmpty" | "$isValid" | "$locals" | ... 41 more ... | "birthday"> &  ...; '.
                            Type 'Pick<Document<any>, "update" | "get" | "delete" | "set" | "invalidate" | "populate" | "__v" | "$ignore" | "$isDefault" | "$isDeleted" | "$isEmpty" | "$isValid" | "$locals" | ... 39 more ... | "validateSync"> &  ...; ' is missing the following properties from type 'Pick<Student, "update" | "get" | "delete" | "set" | "invalidate" | "populate" | "__v" | "$ignore" | "$isDefault" | "$isDeleted" | "$isEmpty" | "$isValid" | "$locals" | ... 41 more ... | "birthday">': name, birthday

9   imports: [TenancyModule.forFeature([ name: 'Student', schema: StudentSchema ])],
                                                           ~~~~~~

  src/tenancy/interfaces/model-definition.interface.ts:5:5
    5     schema: Schema;
          ~~~~~~
    The expected type comes from property 'schema' which is declared here on type 'ModelDefinition'

Found 1 error(s).

npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! school-graph@0.0.1 start: `nest start`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the school-graph@0.0.1 start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:

完整的日志如下所示:

0 info it worked if it ends with ok
1 verbose cli [
1 verbose cli   'C:\\Program Files\\nodejs\\node.exe',
1 verbose cli   'C:\\Users\\USERNAME\\AppData\\Roaming\\npm\\node_modules\\npm\\bin\\npm-cli.js',
1 verbose cli   'run',
1 verbose cli   'start'
1 verbose cli ]
2 info using npm@6.14.11
3 info using node@v14.15.4
4 verbose run-script [ 'prestart', 'start', 'poststart' ]
5 info lifecycle school-graph@0.0.1~prestart: school-graph@0.0.1
6 info lifecycle school-graph@0.0.1~start: school-graph@0.0.1
7 verbose lifecycle school-graph@0.0.1~start: unsafe-perm in lifecycle true
8 verbose lifecycle school-graph@0.0.1~start: PATH: C:\Users\USERNAME\AppData\Roaming\npm\node_modules\npm\node_modules\npm-lifecycle\node-gyp-bin;C:\Users\USERNAME\Downloads\nestjs\node_modules\.bin;C:\Python39\Scripts\;C:\Python39\;C:\Program Files (x86)\VMware\VMware Workstation\bin\;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;C:\Program Files\Intel\WiFi\bin\;C:\Program Files\Common Files\Intel\WirelessCommon\;C:\Program Files\nodejs\;C:\ProgramData\chocolatey\bin;C:\Program Files\Git\cmd;C:\Users\USERNAME\AppData\Local\Microsoft\WindowsApps;;C:\Users\USERNAME\AppData\Local\Programs\Microsoft VS Code\bin;C:\Users\USERNAME\AppData\Roaming\npm
9 verbose lifecycle school-graph@0.0.1~start: CWD: C:\Users\USERNAME\Downloads\nestjs
10 silly lifecycle school-graph@0.0.1~start: Args: [ '/d /s /c', 'nest start' ]
11 silly lifecycle school-graph@0.0.1~start: Returned: code: 1  signal: null
12 info lifecycle school-graph@0.0.1~start: Failed to exec start script
13 verbose stack Error: school-graph@0.0.1 start: `nest start`
13 verbose stack Exit status 1
13 verbose stack     at EventEmitter.<anonymous> (C:\Users\USERNAME\AppData\Roaming\npm\node_modules\npm\node_modules\npm-lifecycle\index.js:332:16)
13 verbose stack     at EventEmitter.emit (events.js:315:20)
13 verbose stack     at ChildProcess.<anonymous> (C:\Users\USERNAME\AppData\Roaming\npm\node_modules\npm\node_modules\npm-lifecycle\lib\spawn.js:55:14)
13 verbose stack     at ChildProcess.emit (events.js:315:20)
13 verbose stack     at maybeClose (internal/child_process.js:1048:16)
13 verbose stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:288:5)
14 verbose pkgid school-graph@0.0.1
15 verbose cwd C:\Users\USERNAME\Downloads\nestjs
16 verbose Windows_NT 10.0.19042
17 verbose argv "C:\\Program Files\\nodejs\\node.exe" "C:\\Users\\USERNAME\\AppData\\Roaming\\npm\\node_modules\\npm\\bin\\npm-cli.js" "run" "start"
18 verbose node v14.15.4
19 verbose npm  v6.14.11
20 error code ELIFECYCLE
21 error errno 1
22 error school-graph@0.0.1 start: `nest start`
22 error Exit status 1
23 error Failed at the school-graph@0.0.1 start script.
23 error This is probably not a problem with npm. There is likely additional logging output above.
24 verbose exit [ 1, true ]

知道是什么问题吗...?

【问题讨论】:

【参考方案1】:

@nestjs/mongoose@7.2.2 似乎不适用于mongoose 版本&gt;=5.11.11

解决方案

降级到 5.11.10 就可以了。

npm install mongoose@5.11.10
npm uninstall @types/mongoose

uninstall 行适用于来自 Google 的用户,您似乎已经删除了仅适用于 Mongoose 5.10 及以下版本的 @types/mongoose 包)

原因

从 Mongoose 5.11 开始,类型包含在 Mongoose 中。因此,类型差异很少。

自从类型被转移以来,已经有一个TON of bugs 提交了关于此的文件。 还有更多here 和here。

替代解决方案

降级 Mongoose 软件包

如果你遇到更多问题,你也可以降级你的 mongoose 相关包

npm i @nestjs/mongoose@7.1.2 mongoose@5.10 @types/mongoose@5.10

禁用依赖类型检查

如果你真的可以通过在tsconfig.json 中添加这一行来跳过对node_modules 的类型检查

     "skipLibCheck": true,

标准警告适用。

一般警告

作为一般说明,具有单个提交和 0 星的 GitHub 代码通常不被视为生产就绪。特别是当它基于一个 9 星的存储库时,它会复制和修改代码而不是重新打包(使合并修复更加困难)。

话虽如此,这里可能有一些不错的工作。

【讨论】:

以上是关于每个客户端的 NestJs 多租户数据库 - 错误的主要内容,如果未能解决你的问题,请参考以下文章

如何识别来自不同租户nestjs多租户jwt的jwt令牌

多租户 PHP SaaS - 为每个客户端单独的数据库,或将它们分组?

为成熟的企业应用程序实施多租户

Shiro 的多租户

将单客户端 SQL Server 数据库转换为单数据库多租户

架构02-构建多租户