Mongoose: DeprecationWarning:猫鼬:mpromise(猫鼬的默认Promise库)在4.8.0和4.8.1中已弃用

创建于 2017-02-02  ·  37评论  ·  资料来源: Automattic/mongoose

对于Mongoose版本4.8.0和4.8.1(节点版本为6.9.5,MongoDB版本为3.2.11),在启动应用程序后首次保存文档时,会生成以下警告(当在应用程序仍在运行时的第一次之后,随后的时间将执行相同的代码,但是,如果应用程序已关闭并重新启动,则在应用程序启动后第一次进行文档保存时会生成警告):

弃用警告:猫鼬:mpromise(猫鼬的默认诺言库)已过时,请插入您自己的诺言库: http ://mongoosejs.com/docs/promises.html

当使用与猫鼬版本4.7.9和更早版本完全相同的应用程序代码时,不会出现此问题。

设置猫鼬连接的代码如下:

`// Set up mongoose and DB connection
 var mongoose = require('mongoose');
 mongoose.Promise = require('bluebird');
 mongoose.connect('mongodb://localhost:27017/basedir', {server: { poolSize: 5 }});`
help wanted needs clarification

最有用的评论

如何解决弃用警告:

var mongoose = require('mongoose');

mongoose.Promise = global.Promise;
var schema = new mongoose.Schema({
 // definition
}, {
 // options
});

module.exports = mongoose.model('foobar', schema);

所有37条评论

您可以粘贴实际产生错误的代码吗? 该代码不会因为您尚未使用诺言(除非您说发布的连接片段确实会产生警告?)而已。

没有连接片段不会产生警告。 以下newuser保存代码段是产生警告的代码,但仅在应用程序启动后第一次执行该代码(再次,在猫鼬版本4.7.9和更早版本中不会发生警告):

 `                       var curDate = new Date();

                         var newuser = new user(
                         {                             
                                "userName": userName,
                                "hashed_password": hashed_password,
                                "emailReg": false,
                                "email": "~",
                                "firstName": "",
                                "lastName": "",
                                "address.streetAddress": "",
                                "address.city": "",
                                "address.state": "",
                                "address.postalCode": "",
                                "phoneNumbers": [],
                                "accessLevel": 2,
                                "active": true,
                                "trialStartDate": curDate,
                                "maxStorageByteLimit": constants.maxStorageBytesPerUser,
                                "signUpDate": curDate,
                                "passwordResetDate": curDate,
                                "salt": temp,
                                "storageBytesUsed": 0
                            });

                        if (phoneNumberValid != false)
                        {
                            newuser.phoneNumbers.push({
                                "type": "mobile",
                                "number": contactPhoneNumber,
                                "primary": true
                            });
                        }

                        wlogger.crit("Create new user by UserName: " + userName);

                        newuser.save(function (err)
                        {
                            if (err)
                            {
                                wlogger.error(err + " - when saving user "
                                    + " creation by UserName: " + userName);
                                callback({
                                    "response": false,
                                    "res": "User creation failed. "
                                    + " Please try again or contact us at [email protected]"
                                });
                            }
                            else
                            {
                                wlogger.crit("Saved new user info for UserName: "
                                    + userName);

                                return callback({
                                        "response": true,
                                        "res": "Created user by User Name " + userName,
                                        "user_id": newuser._id,
                                        "last_modified_date": curDate
                                });
                            }
                        })`

用户架构如下:

`var userSchema = mongoose.Schema({ 
token : String,
email: String,
userName: String,
deviceId: String,
devicePhoneNumber: String, 
hashed_password: String, 
hashed_admin_code: String,
maxStorageByteLimit: { type: Number, default: 1073741824 },
accessLevel: { type: Number, default: 2 },
lastAccessType: Number,
storageBytesUsed: { type: Number, default: 0 },
totalStorageBytesUsed: { type: Number, default: 0 },
deletedStorageBytesUsed: { type: Number, default: 0 },
salt : String,
salt1 : String,
temp_str: String,
syncInProcess: { type: Boolean, default: false },
syncStartDate: { type: Date, default: Date.now },
syncVersion : { type: Number, default: 0 },
active: { type: Boolean, default: false },
disabled: { type: Boolean, default: false },
emailReg: { type: Boolean, default: false },
regPending: { type: Boolean, default: false },
emailChangePending: { type: Boolean, default: false },
regCodeSendCount: { type: Number, default: 0 },
trialStartDate: Date,
signUpDate: Date,
passwordResetDate: Date,
lastLoginDate: Date,
lastModifiedDate: Date,
curLoginDate: Date,
apnDeviceTokens: [ String ],
curSessionIds: [ String ],
curIpAddr: { ipType: String, 
    upper64: Schema.Types.Long,
    lower64: Schema.Types.Long },
firstName: String,
lastName: String,
address: { streetAddress: String,
    city: String,
    state: String, postalCode: String },
phoneNumbers: [ phoneNumbersSchema ],
categories: [ categoriesSchema ],
providerCustomers: [ customerSchema ],
serviceProviders: [ providerSchema ],
ipAddrs: [ ipAddrSchema ],
recentUploads: [ recentUploadSchema ],
recentUploadsGizmo: [ recentUploadSchema ],
recentUploadsLife: [ recentUploadSchema ],
recentUploadsVehicle: [ recentUploadSchema ],
recentUploadsMisc: [ recentUploadSchema ],
recentViews: [ recentViewsSchema ],
recentAdds: [ recentAddsSchema ],
recentAddedFiles: [ recentAddedFilesSchema ],
locations: [ locationSchema ],
inMessages: [ inMessageSchema],
outMessages: [ outMessageSchema ]
  });`

我可以用猫鼬v4.8.1和node.js v7.5.0确认相同的问题。

mongoose.Promise = global.Promise;
mongoose.connect(db.mongodb.uri, db.mongodb.options);
DeprecationWarning: Mongoose: mpromise (mongoose's default promise library) is deprecated, plug in your own promise library instead: http://mongoosejs.com/docs/promises.html

@ stevenelson74708感谢您的摘录,但是架构本身可能不是问题。 我正在寻找的是相对于打开连接/设置猫鼬Promise构造函数时如何导入和使用模式。

从声明如下的模式文件中导出模式:

`module.exports = mongoose.model('users', userSchema);   `

并将该架构导入到文件中,该文件将在其中使用newuser.save进行调用,如下所示:

`var user = require('config/models/users');`

我的第一篇文章中显示的connect片段(打开连接并设置了mongoose Promise构造函数)在app.js文件中出现,该文件在应用程序启动期间初始化时运行。

我的第二篇文章中显示的newuser.save代码段是从导入用户模式的文件中执行的,而当用户与应用程序交互并导致执行特定路由时,newuser.save代码将被执行,这在应用程序初始化之后就很好了已经完成。

该警告仅在应用程序启动后第一次执行newuser.save代码时发生,即使在启动后多次执行相同的newuser.save代码也是如此,并且在4.7.9和更早版本的猫鼬中似乎不会出现该警告。

@ stevenelson74708我将需要查看在应用程序启动中起作用的所有组件。 最近有很多人对此进行了公开讨论,并且每个人都源于对promise构造函数的不正确设置,所以我猜您在设置mongoose.Promise的顺序上做错

有什么办法可以看到您的代码?

以下是app.js初始化中与mongoose配置相关的所有代码(按顺序排列),包括设置mongoose.Promise。 执行初始化代码时不会发生该警告。 该警告仅在应用程序初始化后第一次执行newuser.save代码(在我的前一篇文章中显示)时发生。 有在保存之前执行的findOneAndUpdate调用不会引起警告,因此看来只是导致警告的保存功能。

猫鼬配置是初始化中首先发生的事情之一。 猫鼬配置是否应在初始化之后(例如在createServer功能之后)进行?

同样,在猫鼬版本4.7.9和更早版本中似乎没有出现该警告:

`// Set up mongoose and DB connection
var mongoose = require('mongoose');

mongoose.Promise = require('bluebird');
mongoose.connect('mongodb://localhost:27017/basedir', {server: { poolSize: 5 }});
var conn = mongoose.connection;

conn.once('open', function ()
{
    wlogger.info("Mongoose connection opened on process " + process.pid);
});`

不,可以先进行配置。 该文件是您应用程序的入口点还是在此文件之前?

app.js文件是应用程序的入口点。 可以通过在命令行中键入node app.js来调用该应用程序。

我对猫鼬4.8.1和节点7.5.0有相同的问题。 我也在使用Typescript并尝试将Bluebird插入Promise。 我发现如果添加以下代码,警告会消失:

`import * as mongoose from 'mongoose';
 import * as bluebird from 'bluebird';

 (<any>mongoose).Promise = bluebird;`

在每个从“猫鼬”中导入内容的文件中。 因此,我需要在每个模型文件(在其中定义我的架构的文件)中执行此操作,而不是仅在入口点文件中执行此操作。

// Set up mongoose and DB connection
var mongoose = require('mongoose');

mongoose.Promise = require('bluebird');
mongoose.connect('mongodb://localhost:27017/basedir', {server: { poolSize: 5 }});
var conn = mongoose.connection;

conn.once('open', function ()
{
    console.log('test');
});

不打印此警告,因此还有其他问题。

@vladimirdjurdjevic这意味着在设置promise lib之前,您正在使用猫鼬异步操作的某个地方。 我不使用TS,所以不知道是否与TS有关。

如上所示,我在应用程序的入口点app.js文件中设置了promise lib,然后如上所示执行了第一个newuser.save(设置了promise lib后很久),就会出现警告。 newuser.save是出现的第一个猫鼬异步操作,但是在为连接设置了lib后,它会很好地发生。

与在配置猫鼬连接时仅设置一次诺言库相反,是否必须在访问猫鼬异步功能的每个文件中都设置诺言库?

@ stevenelson74708我有同样的问题。 我以为我用以下方法解决了该问题:在应用程序的入口点使用mongoose.Promise = global.Promise 。 看起来在访问猫鼬承诺的每个文件中确实需要它。 真烦人。 只需在单独的文件中设置猫鼬配置,将其导出并在需要时将其导入即可。

我最近还注意到,尽管已在我的app.js文件中设置了promise,但我收到了此警告。 我试过使用本机和bluebird具有相同的结果。

// FILE: app.js
import bluebird from 'bluebird';
import mongoose from 'mongoose';

// use bluebird as default promise library
mongoose.Promise = bluebird;

我将猫鼬导入一些模型中,并在模式方法中使用它们。 我已经通过在可自行导入猫鼬的ever文件中设置promise库解决了该问题(请参见下面的代码片段中的TODO)。 我不记得几个月前看到过类似代码结构的警告。

// FILE: SessionModel.js
import bluebird from 'bluebird';
import mongoose from 'mongoose';

// TODO: remove this redundant bit of code
// use bluebird as default promise library
mongoose.Promise = bluebird;

SessionSchema.methods.getUser = function(callback) {
  return mongoose.model('User').findById(this.user, callback);
};

@mcfarljw您最好这样做:

// config.js
const bluebird = require('bluebird');
const mongoose = require('mongoose');
mongoose.Promise = bluebird;
mongoose.connect('mongodb://localhost:27017/myApp)
module.exports = { mongoose }
// SessionModel.js
const { mongoose } = require('./config')

SessionSchema.methods.getUser = function(callback) {
  return mongoose.model('User').findById(this.user, callback);
};

这样,您将不必多次编写“ mongoose.Promise = bluebird” :)

在我的情况下,在使用.then()语法对子文档执行操作时收到过时警告,但对父文档却不行。 因此,偶尔出现的警告使我认为我在处理子文档时遇到语法问题,但实际上是模型文件中缺少promise行,正如上面其他人所建议的那样。

是的,似乎在导出mongoose.model的模式文件中设置mongoose.Promise消除了Mongoose版本4.8及更高版本中的警告。

是的,绕过猫鼬单身人士作为自己的突变出口会解决这个问题,但是公认这有点麻烦。

在这一点上,我不清楚究竟是什么“适当的”猫鼬设置/配置可以避免警告。 这是当前猫鼬版本的警告吗,还是表明猫鼬设置不正确? 有建议的猫鼬设置可以防止出现此警告吗? 同样,此警告仅从猫鼬版本4.8.0开始出现。

在设置全局猫鼬时,我有同样的问题。

我已经找到了它,它可以将bluebird正确地设置为promise_provider,但是当我尝试取回promise时,它将返回ES6。

我刚经历并添加

mongoose.Promise = global.Promise

在使用它的每个源文件中都紧随猫鼬的需求/导入之后,尽管这是过分的,但它花了很少的思考,花了很多时间,并且确实将其完全修复。 因此,并不是真正最大的交易。

它确实挑战了我在需求和导入方式方面的有限知识。 我给人的印象是,无论您需要多少次请求,总是得到相同的实例,因此,只要考虑一次设置诺言就足够了。 因此,这有点违反直觉。

你好
我有一些导致问题的示例代码

import mongoose from 'mongoose';

mongoose.Promise = Promise;

import Test from './test.model';

mongoose.connect(uri, options);
mongoose.connection.on('error', err => console.error(`MongoDB connection error: ${err}`));

Test.create({ name: 'Hi'})
  .then(() => Test.findOne({}))
  .then(res => res.save())
  .then(() => console.log('Done'));

(test.model只是一个简单的模型,只有一个名称字段)

由于某种原因,在执行res.save();时首先出现问题。 没有它,一切都会照常工作。

我相信这个问题是由于babel在编译代码时更改顺序而引起的。 通货膨胀时,它将所有进口货移至顶部。 因此,在我的示例中导入test.model时,Promise-library仍分配给mpromise。

我正在使用Node.js 6.10.0和Mongoose 4.8.5,而我遇到了这个问题。

我保存我的用户对象:

var newUser = User({
    login       : 'john',
    password    : 'secret',
    firstname   : 'John',
    lastname    : 'Doe',
    avatar      : 'avatar.png'
});

newUser.save(function(err){
    if(err) throw err;

    console.log('User created !');
});

而且我有同样的错误。 我尝试过这种方式:

mongoose.Promise = require('bluebird');
mongoose.connect(conf.dbpath);

这样:

mongoose.Promise = global.Promise;
mongoose.connect(conf.dbpath);

但是我再次有过时的警告。 我怎样才能解决这个问题 ?

如何解决弃用警告:

var mongoose = require('mongoose');

mongoose.Promise = global.Promise;
var schema = new mongoose.Schema({
 // definition
}, {
 // options
});

module.exports = mongoose.model('foobar', schema);

是的,如果我将其放入模型中,它将起作用。 因此我们必须初始化mongoose.Promise每个模型中。

我说@ stevenelson74708在说At this point it's unclear to me as to exactly what the "proper" mongoose setup/configuration to avoid the warning is.时非常有意思

是的,一种解决方法是返回所有猫鼬模型文件,并在导入后添加mongoose.Promise = global.Promise ,但是由于这个问题是最近才出现的,因此能很好地得到有关其意图的详细答案或背后的原因。 在这一点上,我不确定这是猫鼬,通天塔还是两者的结合所致。

可能是#5030的欺骗。 尝试升级到> = 4.9.1。

根据记录, @ bricss解决方案对我来说效果很好:)

首先,解决方案来自@ steve-p-com。 不是来自@bricss。
@ vkarpov15与4.9.3相同的警告。
@stillesjo与babel无关。 该警告也会在节点7.8.0上没有Babel的nativ上发生。

自版本4.9.3起,我没有任何警告。

即使我们在每个模型上设置mongoose.Promise = global.Promise; ,我也认为这不是_ideal_修复对吗? 为什么不使用global.Promise作为默认值,让用户根据需要进行更改?

单元测试我的模型。 我必须包括它,因此在本地或在CI上运行测试时,我们不会看到警告。
我在节点v7.10.0使用"mongoose": "4.10.4" v7.10.0

@lesterzone

只是向其中添加一个DRY解决方案,而是在您通过数据库初始化连接的地方进行设置,而不是在每个模型中进行设置。

const mongoose = require('mongoose');
mongoose.Promise = global.Promise;
mongoose.connect('mongodb://...');

似乎有效

但这不一定对每个人都有效。 这取决于您的代码结构。 例如,如果带有连接代码的文件需要来自单独源文件的模型,则require起作用的方式意味着将在包含连接代码的文件中设置全局promise之前加载这些源文件。 这些模型将继续使用默认值作为promise。 安全的方法只是在每个需要猫鼬的源文件中设置全局承诺。

这对我有用
``
从“猫鼬”进口猫鼬;
从'./config'导入配置;
从“ bluebird”导入bluebird;

导出默认回调=> {
猫鼬Promise =蓝鸟;
//从配置文件中的数据库实例连接到数据库
让db = mongoose.connect(config.mongoUrl,{useMongoClient:true});
回调(db);
}
``

我就是那样做的。

var colors = require('colors');
var mongo = require('mongodb');
var mongoose = require('mongoose');
mongoose.Promise = require('bluebird');

var db = mongoose.connection;

mongoose.connect('mongodb://localhost:27017/db', { useMongoClient: true })
.then(function(){
  console.log(" Connected to dbName ".green);

}).catch(err => console.error(err));

您必须使用猫鼬随附的.create函数,而不是.save,
我换了我的,它解决了问题

我在4.13.9上并且仍然存在。 @ Gilbert136解决方案解决了这个问题,虽然让我感到奇怪。 .create调用.save,那么为什么没有弃用警告呢?

此页面是否有帮助?
0 / 5 - 0 等级