Skip to content

Commit b4d0b4b

Browse files
committed
sync_alter.js
1 parent 6e15ee4 commit b4d0b4b

File tree

3 files changed

+177
-10
lines changed

3 files changed

+177
-10
lines changed

rootfs_overlay/lkmc/nodejs/sequelize/association.js

Lines changed: 65 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const sequelize = new Sequelize({
99
dialect: 'sqlite',
1010
storage: 'tmp.' + path.basename(__filename) + '.sqlite',
1111
});
12+
1213
(async () => {
1314
const Comment = sequelize.define('Comment', {
1415
body: { type: DataTypes.STRING },
@@ -45,7 +46,10 @@ await Comment.create({body: 'u1c0', UserId: u1.id});
4546
const u0Comments = await Comment.findAll({
4647
where: { UserId: u0.id },
4748
order: [['id', 'ASC']],
48-
include: [{ model: User }],
49+
include: User,
50+
// Equivalent alternatives in this case.
51+
//include: [User],
52+
//include: [{ model: User }],
4953
});
5054
assert(u0Comments[0].body === 'u0c0');
5155
assert(u0Comments[1].body === 'u0c1');
@@ -58,6 +62,7 @@ await Comment.create({body: 'u1c0', UserId: u1.id});
5862

5963
// Nicer higher level way.
6064
{
65+
console.log(Object.getOwnPropertyNames(u0));
6166
const u0Comments = await u0.getComments({
6267
include: [{ model: User }],
6368
});
@@ -79,14 +84,65 @@ await Comment.create({body: 'u1c0', UserId: u1.id});
7984
}
8085

8186
// Removal auto-cascades.
82-
const u0id = u0.id
83-
await u0.destroy()
84-
assert((await Comment.findAll({
85-
where: { UserId: u0id },
86-
})).length === 0);
87-
assert((await Comment.findAll({
88-
where: { UserId: u1.id },
89-
})).length === 1);
87+
{
88+
const u0id = u0.id
89+
await u0.destroy()
90+
assert((await Comment.findAll({
91+
where: { UserId: u0id },
92+
})).length === 0);
93+
assert((await Comment.findAll({
94+
where: { UserId: u1.id },
95+
})).length === 1);
96+
}
97+
98+
// as aliases.
99+
// Allows us to use a nicer name for a relation rather than the exact class name.
100+
// E.g. here we name the User of a Comment as a "author".
101+
// And mandatory do diambiguate multiple associations with a single type.
102+
{
103+
const CommentAs = sequelize.define('CommentAs', {
104+
body: { type: DataTypes.STRING },
105+
}, {});
106+
const UserAs = sequelize.define('UserAs', {
107+
name: { type: DataTypes.STRING },
108+
}, {});
109+
UserAs.hasMany(CommentAs)
110+
CommentAs.belongsTo(UserAs, {as: 'author'})
111+
await sequelize.sync({force: true});
112+
const u0 = await UserAs.create({name: 'u0'})
113+
const u1 = await UserAs.create({name: 'u1'})
114+
await CommentAs.create({body: 'u0c0', authorId: u0.id});
115+
await CommentAs.create({body: 'u0c1', authorId: u0.id});
116+
await CommentAs.create({body: 'u1c0', authorId: u1.id});
117+
118+
{
119+
const u0Comments = await CommentAs.findAll({
120+
where: { authorId: u0.id },
121+
order: [['id', 'ASC']],
122+
// Instead of include: UserAs
123+
include: 'author',
124+
});
125+
assert(u0Comments[0].body === 'u0c0');
126+
assert(u0Comments[1].body === 'u0c1');
127+
assert(u0Comments[0].authorId === u0.id);
128+
assert(u0Comments[1].authorId === u0.id);
129+
assert(u0Comments[0].author.name === 'u0');
130+
assert(u0Comments[1].author.name === 'u0');
131+
}
132+
133+
// Trying with the higher level getter.
134+
{
135+
// TODO
136+
// u0.getComments is not a function
137+
//const u0Comments = await u0.getComments({
138+
// include: 'author',
139+
//});
140+
//assert(u0Comments[0].body === 'u0c0');
141+
//assert(u0Comments[1].body === 'u0c1');
142+
//assert(u0Comments[0].author.name === 'u0');
143+
//assert(u0Comments[1].author.name === 'u0');
144+
}
145+
}
90146

91147
await sequelize.close();
92148
})();

rootfs_overlay/lkmc/nodejs/sequelize/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ await sequelize.authenticate();
4444
const IntegerNames = sequelize.define('IntegerNames', {
4545
value: {
4646
type: DataTypes.INTEGER,
47-
allowNull: false
47+
allowNull: false,
48+
unique: true,
4849
},
4950
name: {
5051
type: DataTypes.STRING,
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
#!/usr/bin/env node
2+
3+
// https://stackoverflow.com/questions/17708620/sequelize-changing-model-schema-on-production
4+
5+
const assert = require('assert');
6+
const path = require('path');
7+
8+
const { Sequelize, DataTypes } = require('sequelize');
9+
10+
(async () => {
11+
{
12+
const sequelize = new Sequelize({
13+
dialect: 'sqlite',
14+
storage: 'tmp.' + path.basename(__filename) + '.sqlite',
15+
});
16+
const IntegerNames = sequelize.define('IntegerNames', {
17+
value: { type: DataTypes.INTEGER, },
18+
name: { type: DataTypes.STRING, },
19+
}, {});
20+
await IntegerNames.sync({force: true})
21+
await IntegerNames.create({value: 2, name: 'two'});
22+
await IntegerNames.create({value: 3, name: 'three'});
23+
await sequelize.close();
24+
}
25+
26+
// Alter by adding column..
27+
{
28+
const sequelize = new Sequelize({
29+
dialect: 'sqlite',
30+
storage: 'tmp.' + path.basename(__filename) + '.sqlite',
31+
});
32+
const IntegerNames = sequelize.define('IntegerNames', {
33+
value: { type: DataTypes.INTEGER, },
34+
name: { type: DataTypes.STRING, },
35+
nameEs: { type: DataTypes.STRING, },
36+
}, {});
37+
await IntegerNames.sync({alter: true})
38+
await IntegerNames.create({value: 5, name: 'five' , nameEs: 'cinco'});
39+
await IntegerNames.create({value: 7, name: 'seven', nameEs: 'siete'});
40+
const integerNames = await IntegerNames.findAll({
41+
order: [['value', 'ASC']],
42+
});
43+
assert(integerNames[0].value === 2);
44+
assert(integerNames[0].name === 'two');
45+
assert(integerNames[0].nameEs === null);
46+
assert(integerNames[1].name === 'three');
47+
assert(integerNames[1].nameEs === null);
48+
assert(integerNames[2].name === 'five');
49+
assert(integerNames[2].nameEs === 'cinco');
50+
assert(integerNames[3].name === 'seven');
51+
assert(integerNames[3].nameEs === 'siete');
52+
await sequelize.close();
53+
}
54+
55+
// Alter by removing column. undefined instead of null,
56+
// because the values really aren't present in the database anymore.
57+
{
58+
const sequelize = new Sequelize({
59+
dialect: 'sqlite',
60+
storage: 'tmp.' + path.basename(__filename) + '.sqlite',
61+
});
62+
const IntegerNames = sequelize.define('IntegerNames', {
63+
value: { type: DataTypes.INTEGER, },
64+
name: { type: DataTypes.STRING, },
65+
}, {});
66+
await IntegerNames.sync({alter: true})
67+
const integerNames = await IntegerNames.findAll({
68+
order: [['value', 'ASC']],
69+
});
70+
assert(integerNames[0].value === 2);
71+
assert(integerNames[0].name === 'two');
72+
assert(integerNames[0].nameEs === undefined);
73+
assert(integerNames[1].name === 'three');
74+
assert(integerNames[1].nameEs === undefined);
75+
assert(integerNames[2].name === 'five');
76+
assert(integerNames[2].nameEs === undefined);
77+
assert(integerNames[3].name === 'seven');
78+
assert(integerNames[3].nameEs === undefined);
79+
await sequelize.close();
80+
}
81+
82+
// Alter a type.
83+
// Hmm, docs suggest data would get dropped, but I only see typecast without alter.drop,
84+
// so shy does it work still?. sqlite from CLI does confirm that it is now a VARCHAR(255)
85+
// column.
86+
{
87+
const sequelize = new Sequelize({
88+
dialect: 'sqlite',
89+
storage: 'tmp.' + path.basename(__filename) + '.sqlite',
90+
});
91+
const IntegerNames = sequelize.define('IntegerNames', {
92+
value: { type: DataTypes.STRING, },
93+
name: { type: DataTypes.STRING, },
94+
}, {});
95+
await IntegerNames.sync({alter: true})
96+
const integerNames = await IntegerNames.findAll({
97+
order: [['value', 'ASC']],
98+
});
99+
assert(integerNames[0].value === '2');
100+
assert(integerNames[0].name === 'two');
101+
assert(integerNames[1].value === '3');
102+
assert(integerNames[1].name === 'three');
103+
assert(integerNames[2].value === '5');
104+
assert(integerNames[2].name === 'five');
105+
assert(integerNames[3].value === '7');
106+
assert(integerNames[3].name === 'seven');
107+
await sequelize.close();
108+
}
109+
110+
})();

0 commit comments

Comments
 (0)