- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
在尝试弄清楚为什么我的 Sequelize 模型不致力于他们的关系两天之后,我决定是时候向大家征求意见了。
这是故事。
我正在使用以 Sequelize 作为驱动程序的 Postgres (9.4) 数据库编写 Feathers JS 应用程序。我在 Feathers Docs 中完成了设置,经过一番劝说,我开始运行迁移。
据我所知,必须特别考虑使用 Sequelize 获得双向关系,因为如果 ModelA
引用 ModelB
,ModelB
必须已经定义,但是如果 ModelB
引用 ModelA
...那么,我们就会遇到依赖循环。
正是由于文档所说的“使用此处描述的方法定义您的模型”的依赖循环。 (好吧,从技术上讲,它只是“假设”使用了这样的结构。另外,我只能发布 2 个链接,否则我会链接那个傻瓜。对此感到抱歉。)我在 Feathers demo 中找到了相同的结构。 .
自然地,我反射(reflect)了所有这些(当然,除非我遗漏了一个小但重要的细节),但是......仍然没有骰子。
这是我正在查看的内容:
'use strict';
module.exports = {
up: function (queryInterface, Sequelize) {
// Make the accounts table if it doesn't already exist.
// "If it doesn't already exist" because we have the previous migrations
// from Laravel.
return queryInterface.showAllTables().then(function(tableNames) {
if (tableNames.accounts === undefined) {
queryInterface.createTable('accounts', {
// Field definitions here
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
name: Sequelize.STRING,
url_name: Sequelize.STRING,
createdAt: {
type: Sequelize.DATE,
allowNull: false
},
updatedAt: {
type: Sequelize.DATE,
allowNull: false
},
deletedAt: Sequelize.DATE
});
}
});
// See the create-user migration for an explanation of why I
// commented out the above code.
},
down: function (queryInterface, Sequelize) {
return queryInterface.dropTable('accounts');
}
};
'use strict';
module.exports = {
up: function (queryInterface, Sequelize) {
return queryInterface.showAllTables().then(function(tableNames) {
if (tableNames.users === undefined) {
queryInterface.createTable('users', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
accountId: {
type: Sequelize.INTEGER,
references: {
model: 'accounts',
key: 'id'
},
allowNull: false
},
email: {
type: Sequelize.STRING,
allowNull: false
},
[...]
});
}
});
},
down: function (queryInterface, Sequelize) {
return queryInterface.dropTable('users');
}
};
然后我启动了 psql 来查看引用是否正确:
databaseName=#\d accounts
:
Referenced by:
TABLE "users" CONSTRAINT "users_accountId_fkey" FOREIGN KEY ("accountId") REFERENCES accounts(id)
databaseName=#\d 用户
:
Foreign-key constraints:
"users_accountId_fkey" FOREIGN KEY ("accountId") REFERENCES accounts(id)
到目前为止还不错吧?
让我们看看这个程序的模型部分!
'use strict';
// account-model.js - A sequelize model
//
// See http://docs.sequelizejs.com/en/latest/docs/models-definition/
// for more of what you can do here.
const Sequelize = require('sequelize');
module.exports = function(app) {
// We assume we're being called from app.configure();
// If we're not, though, we need to be passed the app instance.
// Fair warning: I added this bit myself, so it's suspect.
if (app === undefined)
app = this;
const sequelize = app.get('sequelize');
// The rest of this is taken pretty much verbatim from the examples
const account = sequelize.define('account', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
name: Sequelize.STRING,
url_name: Sequelize.STRING,
}, {
paranoid: true,
timestamps: true,
classMethods: {
associate() {
const models = app.get('models');
this.hasMany(models['user'], {});
}
}
});
return account;
};
'use strict';
// user-model.js - A sequelize model
//
// See http://docs.sequelizejs.com/en/latest/docs/models-definition/
// for more of what you can do here.
const Sequelize = require('sequelize');
module.exports = function(app) {
// We assume we're being called from app.configure();
// If we're not, though, we need to be passed the app instance
if (app === undefined)
app = this;
const sequelize = app.get('sequelize');
const user = sequelize.define('user', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true
},
accountId: {
type: Sequelize.INTEGER,
references: {
model: 'accounts', // Table name...is that right? Made the migration work...
key: 'id'
}
},
email: Sequelize.STRING,
[... curtailed for brevity ...]
}, {
// Are these necessary here, or just when defining the model to make a
// psuedo-migration?
paranoid: true, // soft deletes
timestamps: true,
classMethods: {
associate() {
const models = app.get('models');
// This outputs like I'd expect:
// Just to be sure...From the user model, models["account"]: account
console.log('Just to be sure...From the user model, models["account"]:', models['account']);
this.belongsTo(models['account'], {});
}
}
});
return user;
};
// I blatantly ripped this from both the following:
// https://github.com/feathersjs/generator-feathers/issues/94#issuecomment-204165134
// https://github.com/feathersjs/feathers-demos/blob/master/examples/migrations/sequelize/src/models/index.js
const Sequelize = require('sequelize');
const _ = require('lodash');
// Import the models
const account = require('./account');
const user = require('./user');
module.exports = function () {
const app = this;
// Note: 'postgres' is found in config/default.json as the db url
const sequelize = new Sequelize(app.get('postgres'), {
dialect: app.get('db_dialect'),
logging: console.log
});
app.set('sequelize', sequelize);
// Configure the models
app.configure(account);
app.configure(user);
app.set('models', sequelize.models);
// Set associations
Object.keys(sequelize.models).forEach(modelName => {
if ('associate' in sequelize.models[modelName]) {
sequelize.models[modelName].associate();
}
});
sequelize.sync();
// Extra credit: Check to make sure the two instances of sequelize.models are the same...
// Outputs: sequelize.models after sync === app.get("models")
// I've also run this comparison on sequelize and app.get('sequelize'); _.eq() said they also were identical
if (_.eq(sequelize.models, app.get('models')))
console.log('sequelize.models after sync === app.get("models")');
else
console.log('sequelize.models after sync !== app.get("models")');
};
为了简洁起见,我从中删除了很多内容,我将模型加载到 app
中,如下所示:
const models = require('./models')
app.use(compress())
// Lots of other statements
.configure(models);
我一直在尝试制作一个命令行实用程序来更改密码、修改用户权限和其他实用程序任务,所以我使用了 Vorpal(同样,只有 2 个链接,所以你必须自己查找如果你不熟悉——抱歉)。以下是我的 Vorpal 程序的相关片段:
const vorpal = require('vorpal')();
const _ = require('lodash');
// Initialize app
// This seems a bit overkill since we don't need the server bit for this, but...
const app = require('./src/app');
const models = app.get('models');
// Get the models for easy access...
const User = models['user'];
const Account = models['account'];
// Run by issuing the command: node cli test
// Outputs to terminal
vorpal.command('test', 'A playground for testing the Vorpal environment.')
.action(function(args, callback) {
// User.belongsTo(Account); // <-- uncomment this and it works
User.findOne({ include: [{ model: Account }]}).then((user) => {
console.log("user.account.name:", user.account.name);
});
});
vorpal.show().parse(process.argv);
抱歉这么久才到这里,但我不知道这里面的哪一部分是相关的,所以我只好吐了。
运行 node cli test
给我一个错误
Just to be sure...From the user model, models["account"]: account
sequelize.models after sync === app.get("models")
connect:
Unhandled rejection Error: account is not associated to user!
at validateIncludedElement (/vagrant/node_modules/sequelize/lib/model.js:550:11)
at /vagrant/node_modules/sequelize/lib/model.js:432:29
at Array.map (native)
at validateIncludedElements (/vagrant/node_modules/sequelize/lib/model.js:428:37)
at .<anonymous> (/vagrant/node_modules/sequelize/lib/model.js:1364:32)
at tryCatcher (/vagrant/node_modules/bluebird/js/release/util.js:16:23)
at Promise._settlePromiseFromHandler (/vagrant/node_modules/bluebird/js/release/promise.js:504:31)
at Promise._settlePromise (/vagrant/node_modules/bluebird/js/release/promise.js:561:18)
at Promise._settlePromise0 (/vagrant/node_modules/bluebird/js/release/promise.js:606:10)
at Promise._settlePromises (/vagrant/node_modules/bluebird/js/release/promise.js:685:18)
at Async._drainQueue (/vagrant/node_modules/bluebird/js/release/async.js:138:16)
at Async._drainQueues (/vagrant/node_modules/bluebird/js/release/async.js:148:10)
at Immediate.Async.drainQueues (/vagrant/node_modules/bluebird/js/release/async.js:17:14)
at runCallback (timers.js:574:20)
at tryOnImmediate (timers.js:554:5)
at processImmediate [as _immediateCallback] (timers.js:533:5)
啊!
但是,如果我取消注释 User.findOne()
正上方的行,它会像一个魅力。
为什么我必须在查询关系之前立即明确设置关系?为什么在用户模型的 associate() 方法中建立的关系(大概)没有坚持?据我所知,它正在被调用——而且是在正确的模型上。它是否以某种方式被覆盖? app
是否出于某种奇怪的原因,在建立关联时在用户模型中与在 cli.js
中不同?
我真的很困惑。非常感谢你们能提供的任何帮助。
最佳答案
我不知道为什么会这样,但我确实通过进行以下更改使其正常工作。
我在导出函数末尾附近注释掉了以下 block :
Object.keys(sequelize.models).forEach(modelName => {
if ('associate' in sequelize.models[modelName]) {
sequelize.models[modelName].associate();
}
});
然后我将它移动到 src/relate-models.js
中:
/**
* This is workaround for relating models.
* I don't know why it works, but it does.
*
* @param app The initialized app
*/
module.exports = function(app) {
const sequelize = app.get('sequelize');
// Copied this from src/models/index.js
Object.keys(sequelize.models).forEach(modelName => {
if ('associate' in sequelize.models[modelName]) {
sequelize.models[modelName].associate();
}
});
}
在 src/app.js
中,我调用了那个函数,然后......很快就成功了。
const models = require('./models')
app.use(compress())
// Lots of other statements
.configure(models);
require('./relate-models')(app);
结束。如果有人能解释为什么以后做完全相同的事情会奏效,请告诉我,但现在……它奏效了。
关于node.js - Sequelize 和羽毛 : When Relationships Fall Apart,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39151050/
我制作了一个不透明度为 30% 的表单,我希望它覆盖在我的屏幕上,这样我就可以在上面绘制一个网格,同时仍然能够控制下面的任何程序。所以我希望我用网格创建的表单忽略我的鼠标事件,这样我就可以点击进入下面
我在一个放置在控件下的窗体上有一个面板。我将使用该面板绘制从黑色到透明的渐变,以模拟从控件转换的阴影。但是,面板下方会有其他控件,并且面板会捕获针对其下方面板的点击。 我怎样才能获得点击以“穿过”面板
我实现了这个有趣的页面: http://www.xthema.it/misc/christmas-matrix.html 我重试了三种不同的方式,但每次我都无法通过 Firefox 获得良好的性能结果
为什么当我大幅缩小时我的网站会“崩溃”? 是否有某些 CSS 属性可以解决这个问题? 这是指向相关网页的链接: http://www.raycavanaugh.com/per%20word.html
爱情就像是一团火焰,而我们就像是飞蛾。虽然知道自己可能会粉身碎骨,但是还是义无反顾的向前冲不回头。不过恋爱经历那两个月甜蜜期以后就是正常的了,所以很多人能够恋爱却走不到最后。
我尝试创建一个效果视频,例如:花落。我有一个主视频(main.mp4)和一个效果视频(flower_fall.mp4)。我想制作一个将 2 个视频合并的 output.mp4 视频,结果看起来主视频是
我正在处理汉字。我的某些字符不存在于 Unicode 中。我正在使用 PUA .ttf 来支持我的非通用字符。 当我打电话 UIFont fontWithName:@"BabelStoneHanPUA
TL; 博士 customize 中是否有一些标准的回退处理? 系统,用于处理部分无效的复合定制 变量,例如一个条目不是缺点的列表? 长版 emacs 的自定义机制非常强大,使用 复合 Materia
什么//$FALL-THROUGH$ Eclipse 中的评论是什么意思?我做了谷歌,但找不到任何东西。 最佳答案 它抑制了一个警告,告诉您没有 break;来自 case . 关于eclipse -
当我必须编写多个条件语句时,我通常使用 switch 语句,通常有三个或更多明确定义的条件。 但是,要处理包含失败行为的双条件语句,我经常在简单的if、else if、else 语句和 之间犹豫不决切
以下工作代码在接收 BOOT_COMPLETED 广播的 BroadcastReceiver 中运行。 //Create a transparent, untouchable view and att
这是我第一次尝试在面包板上编写 Raspberry Pi 和硬件按钮的代码。程序很简单,当检测到按下按钮时,打开面包板上的 LED 1 秒钟。我的代码似乎有效,但奇怪的是,每隔一段时间按下一个按钮就会
在第9讲中,老师说numberOfSectionsInTableView:方法默认返回1,但是当我创建自己的项目时,发现它默认返回0,导致我的表格 View 单元格消失了!我找到了问题所在,并通过使
所以我应该为大学项目制作一个 Javascript 版本的落石游戏。玩家控制一个矩形,该矩形应该从左向右移动而不会被掉落的物体击中。到达每一侧都会增加分数,而被击中则会减少分数。比赛结束为 0 分。
目前我正在开发一个应用程序,它从 Twitter API 读取流并将其解析为对象。目前我读取流并使用 DataContractJsonSerializer 中的 ReadObject(...) 制作我
我使用 Eclipse,所以对我来说,使用 //$FALL-THROUGH$ 注释是 switch 语句等的常见做法。但是我的同事使用 Netbeans 并质疑我到底用这些做什么。试图用谷歌搜索任何带
我正在解析文本文档并将大部分数据转换为关系格式。整个过程中使用了多种日期格式,但其中之一是“1997 年秋季”。 存储此信息的最佳方法是什么,该信息在某种意义上是非特定的(不是绝对日期),同时又不会丢
我想创建一个 UIView 来为下雨设置动画,它应该高于所有其他 View ,在最前面,但是透明的,并且它不应该在所有,因此在我实现它之前,点击它背后的 UI 的行为应该与现在完全一样。它会充当覆盖层
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: Why was the switch statement designed to need a break?
题目地址:https://leetcode.com/problems/minimum-falling-path-sum/description/ 题目描述 Given a square array
我是一名优秀的程序员,十分优秀!