I have a Postgres database using Sequelize (node/express) as ORM. I have a table called students, in it there are columns: id and name.
In this students table, I have several registered students, but a detail: the last registered ID is 34550 and the first is 30000, they come from an import from a previous database, I need to continue counting from 34550, or that is, from the last registered student. However, when I register a student via API, the generated ID is below 30000. I know that in mysql the ID field being AUTO INCREMENT would solve it, however, as I understand it, postgres works in a different way.
How could I solve this problem?
The migration used to create the table is as follows:
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.createTable('students', {
id: {
type: Sequelize.INTEGER,
allowNull: false,
autoIncrement: true,
primaryKey: true,
},
name: {
type: Sequelize.STRING,
allowNull: false,
},
});
},
down: (queryInterface) => {
return queryInterface.dropTable('students');
},
};
Table print:
Based on Frank comment, I was able to adjust using:
SELECT setval('public.students_id_seq', 34550, true);
Related
For example, I have db with table Users, which have some fields: (id, username).
Some later I decided add new field - email. Of course, I update model, migration and run sequelize db:migration. But nothing happened. Any ideas how to add it in Users?
Marat, if you change a migration file you had already ran into table within the database, you won't see the modifications, you have to create a new migrations file in which you're going to make references of the new field you want to create and in which table do you wanna it to be. like this for example. I decided that I need a status field in my Campaigns tables, so this is the right way to do it! hope it helps!
'use strict';
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.addColumn('Campaigns', 'status', {
type: Sequelize.ENUM,
values: ['Active', 'Inactive', 'Deleted'],
defaultValue: 'Active',
allowNull: false,
validate: {
notEmpty: true
},
});
},
down: (queryInterface, Sequelize) => {
return queryInterface.removeColumn('Campaigns', 'status');
}
};
I want to add some records in a table on the PostgreSQL db that Heroku offers. I am using Sequelize as ORM.
The query would be this one:
INSERT INTO "Categories" (name) VALUES ('Familie'), ('Liefde'), ('Tienertijd'), ('Kindertijd'), ('Hobbies');
However, I get this error that says I should also specify two more columns that are automatically created by Sequelize, namely createdAt and updatedAt.
ERROR: null value in column "createdAt" violates not-null constraint
DETAIL: Failing row contains (1, Familie, null, null).
How can I manually add these records, without going through Sequelize?
EDIT: this is the Sequelize model for Categories:
module.exports = (sequelize, DataTypes) =>
sequelize.define('Category', {
name: {
type: DataTypes.STRING,
unique: true
}
})
Since I didn't really need the timestamps, I realized you can specify not to use them as shown in the following snippet:
sequelize.define('Category', {
name: { type: DataTypes.STRING , unique: true},
}, {
timestamps: false
});
This way I don't need to specify the createdAt and updatedAt values when doing an INSERT.
I would like to find the parent table information of an object.
I have User hasMany Book
where Book has writer and assigned to user id.
Book has type, which is like fantasy, romance, history, scientific fiction... etc
So I want to find out the Book with type Scientific Fiction but not only for that, I also want the writer, which is User.
How can I find the book with its writer where where condition is given for books only? It seems like 'include' in Book.findAll( include: User) is not working; this tells me that include is only working for finding child tables not parent.
Here are some code for user
const User = sequelize.define('User', {
id: { type: DataTypes.STRING(6), field: 'ID', primaryKey : true }
}
associate: function(models) {
User.hasMany(models.Book, { foreignKey: 'userId' });
}
and book
const Book = sequelize.define('Book', {
id: { type: DataTypes.STRING(6), field: 'ID', primaryKey: true }, // primary key
userId: { type: DataTypes.STRING(6), field: 'USER_ID', primaryKey: true }
type: { type: DataTypes.STRING(20), field: 'TYPE'
}
Book has some more child table and I try to find those additional information in includes, so I guess I really need to find from Book.findAll(...)
Instead of User.findAll(include: Book).
Can anyone help?
I think I was making a mistake.
As soon as I changed
userId: { type: DataTypes.STRING(6), field: 'USER_ID', primaryKey: true }
to
userId: { type: DataTypes.STRING(6), field: 'USER_ID' }
include is working for belongsTo; and it finds the parent from child.
It seems like Sequelize has some problem with relation if there is more than one primary key declared in model...
If anyone does think this solves your problem, please share in reply so I can be more sure about it.
Thanks.
I'm writing a subdomain string to a Mongodb database (run on Compose.io), and I need to ensure that the subdomain.name string is unique.
I setup my document as
var SubdomainModel = function() {
var subdomainSchema = mongoose.Schema({
name: {type: String, require: true, index: true, unique: true, lowercase: true, trim: true},
createdBy: {type: mongoose.Schema.Types.ObjectId, require: true, ref: 'User'}
});
subdomainSchema.pre('save', function(next) {
var subdomain = this;
subdomain.name = subdomain.name.toLowerCase();
next();
});
return mongoose.model('Subdomain', subdomainSchema);
}
module.exports = new SubdomainModel();
I'm using frisby.js to run my tests (it's based on jasmine). In my test, I delete the subdomain document, then create new subdomains.
I also timestamp the subdomain name so I can make sure it is unique. I create the subdomain, then wait 15 seconds and create it again and ensure that my 2nd create call fails.
The test passes one time, then I re-run and it fails the next. When I look in the db, sure enough, there are two entries for the same subdomain.
{ name: "test-1425876399170", _id: ObjectId("54fd25af5ce2db7c0a7192d1"), __v: 0 }
{ name: "test-1425876399170", _id: ObjectId("54fd25be5ce2db7c0a7192d3"), __v: 0 }
Maybe the problem is being caused by the db being blown away, I'm not sure, but I'm amazed at how consistently it fails/passes/fails/passes.
Any idea how to resolve this?
I have two models
countries - from mysql server
Country = {
tableName: 'countries',
connection: 'someMysqlServer',
schema: true,
migrate: 'safe',
autoCreatedAt: false,
autoUpdatedAt: false,
attributes: {
country_id: {
type: 'integer',
primaryKey: true,
autoIncrement: true
},
....
}
};
User = {
connection: 'somePostgresqlServer',
attributes: {
id: {
type: 'integer',
primaryKey: true,
autoIncrement: true
},
country_id: {
model: 'country'
},
$> User.findOneById(1).populate('country_id').exec(console.log)
and get error
sails> Error (E_UNKNOWN) :: Encountered an unexpected error
: Unable to determine primary key for collection `countries` because an error was encountered acquiring the collection definition:
[TypeError: Cannot read property 'definition' of undefined]
at _getPK (/projects/foturist-server/node_modules/sails-postgresql/lib/adapter.js:923:13)
at StrategyPlanner.__FIND__.Cursor.$getPK (/projects/foturist-server/node_modules/sails-postgresql/lib/adapter.js:504:20)
.....
Details: Error: Unable to determine primary key for collection `countries` because an error was encountered acquiring the collection definition:
[TypeError: Cannot read property 'definition' of undefined]
Why country association uses with postgre-connection ?
Well, since the two models are on different database connections, you're not going to be able to do an actual SQL join. I would think what you'd need is a
User.find({id: 1}).exec(function(user) {
var theUser = user;
Country.find(user.country_id)
.exec(function(country) {
theUser.country = country;
return theUser;
}); });
I'm not sure what specific needs you're trying to address, but since a lookup table of countries is unlikely to frequently change, and is in an entirely different data store, I would suggest caching this data in something like Redis or Memcache. Then on your User find callback you can fetch the country by id from your cache store. This will be much faster unless you expect this data to change on a regular basis. You could write a service that does a lazy lookup in your other database and serves from the cache then on, or cache them all up front when your app launches.