I am working on REST API based on node.js and i chose postgresql database to store data. Suppose that this database has two tables names User and Comment. Any Comment belongs to One User and when we decide to remove an User, the Comment's of him/her must be removed. So, I designed my table as follows:
CREATE TABLE User(
user_id SERIAL,
username VARCHAR(32) NOT NULL,
password VARCHAR(32) NOT NULL,
CONSTRAINT pk_user PRIMARY KEY (user_id),
CONSTRAINT uq_user UNIQUE (username)
)
CREATE TABLE Comment(
comment_id SERIAL,
user_id INTEGER NOT NULL,
content TEXT NOT NULL,
CONSTRAINT pk_cmnt PRIMARY KEY (comment_id),
CONSTRAINT fk_cmnt FOREIGN KEY (user_id) REFERENCES User(user_id)
ON UPDATE CASCADE ON DELETE CASCADE
)
But i don't run this code and use node-orm2 instead. I designed two simple models to handle this simple code:
var User = db.define('user', {
username: {
type: 'text',
size: 32, // VARCHAR(32)
required: true, // NOT NULL
unique: true // UNIQUE INDEX
},
password: {
type: 'text',
size: 32, // VARCHAR(32)
required: true // NOT NULL
}
}, {
id: 'user_id' //SERIAL
});
var Cmnt = db.define('comment', {
content: {
type: 'text',
required: true // NOT NULL
}
}, {
id: 'comment_id' //SERIAL
});
Cmnt.hasOne('user', User, {required: true}); // CREATE ASSOCIATION KEY
and synchronize database with these models :
db.sync();
Now, I want to insert new comment belongs to user which user_id doesn't exist. So, the Comment model accepts this and insert the row into comment table.
My question is, how can i do some things like REFERENCE KEY and the ON UPDATE CASCADE ON DELETE CASCADE ?
Thanks in advance :)
Try to use deferrable like this:
CREATE TABLE Comment(
comment_id SERIAL,
user_id INTEGER NOT NULL,
content TEXT NOT NULL,
CONSTRAINT pk_cmnt PRIMARY KEY (comment_id),
CONSTRAINT fk_cmnt FOREIGN KEY (user_id) REFERENCES User(user_id)
ON UPDATE CASCADE ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED
)
Related
I have the following association in PersonEntity:
#HasMany(() => SocialPostEntity, {
foreignKey: 'parentId',
foreignKeyConstraint: false,
})
posts?: SocialPostEntity[];
On the other hand the related column on SocialPostEntity:
#Column(DataType.INTEGER)
parentId: number;
The generated create table script has created the parentId column with a foreign key to PersonEntity. event though I have explicitly mentioned foreignKeyConstraint: false
Im not intended to use synchronize: true in production but I'm afraid that it means that my mapping is not accurate.
Bottom line I want parentId to be a simple integer, that's it.
Thanks
I'm using sequelize 6.5.0. I created a simple model to do two rudimentary things: a) find records, b) create records. I'm having trouble creating records; specifically, ones with primary key. If I designate the column as primaryKey like so:
const Table = sequelize.define('table', {
id: {
type: DataTypes.UUID,
primaryKey: true
},
datum: {...}
...
and try to create a record like so:
Table.create({datum: 'abc'})
then it will try (and fail) to set the primary key with:
INSERT INTO "table" ("id","datum") VALUES ($1,$2) RETURNING ...;
which is 50% what I did not ask it to do. Now, I don't need this to happen since default value for id is already handled at the database level. So, the next natural move was to not designate id as primaryKey:
const Table = sequelize.define('table', {
id: {
type: DataTypes.UUID,
// primaryKey: true
},
datum: {...}
...
But now sequelize attempts to get smart and throws a tantrum:
Uncaught Error: A column called 'id' was added to the attributes of 'table' but not marked with 'primaryKey: true'
Q) How do I get sequelize to NOT handle primary key on create?
I think you can skip the id field in the definition altogether, and PostgreSQL will still have one
I have a Employee and their dependents model defined in sequlieze. I have an employeeId foreign key column defined in the dependent table ( see my model class below) . but when i try to execute following command
models.Employee.findOne({where: { id: Number(id) }, include: [{ model: models.Dependent }]});
i get an error -> EagerLoadingError [SequelizeEagerLoadingError]: Dependent is not associated to Employee!
isn't specifying a foreign key in the dependent model , enough?
Employee model
module.exports = function(sequelize, DataTypes) {
const Employee = sequelize.define('Employee ', {
id : {
type: DataTypes.INTEGER(11),
allowNull: false,
autoIncrement:true,
primaryKey:true
},
Name : { ... }
Dependent model
module.exports = function(sequelize, DataTypes) {
const Dependent = sequelize.define('Dependent', {
id : {
type: DataTypes.INTEGER(11),
allowNull: false,
autoIncrement:true,
primaryKey:true
},
EmployeeId : {
type: DataTypes.INTEGER(11),
allowNull: true,
references : {
model : 'Employee ',
key:'id'
}
},
Name : { ... }
isn't specifying a foreign key in the dependent model, enough?
No, it's NOT enough if you want to use Eager Loading of sequelize.
You need to create sequelize associations for these models(Employee and Dependent for your case) in pairs, see Why associations are defined in pairs?
The references option in the model only creates an FK relationship between Dependent and Employee tables in the database(relationship for db level). Does not include associations of sequelize model(relationship for application level). When to use? see Enforcing a foreign key reference without constraints
Employee has many dependents and dependent belongs to one Employee. So you need to create One-To-Many relationships.
Employee.hasMany(Dependent);
Dependent.belongsTo(Employee);
create associations like above will create FK reference for tables implicitly.
Execution results:
Executing (default): CREATE TABLE IF NOT EXISTS "employees" ("id" SERIAL , "name" VARCHAR(255), PRIMARY KEY ("id"));
Executing (default): CREATE TABLE IF NOT EXISTS "dependents" ("id" SERIAL , "name" VARCHAR(255), "EmployeeId" INTEGER REFERENCES "employees" ("id") ON DELETE SET NULL ON UPDATE CASCADE, PRIMARY KEY ("id"));
I have a database with the following tables:
CREATE TABLE IF NOT EXISTS `app_user` (
`user_id` INT NOT NULL,
`user_name` VARCHAR(45) NOT NULL,
PRIMARY KEY (`user_id`))
ENGINE = InnoDB;
CREATE TABLE IF NOT EXISTS `user_folder` (
`user_id` INT NOT NULL,
`document_id` INT NOT NULL,
PRIMARY KEY (`user_id`, `document_id`),
CONSTRAINT `fk_user_document_user`
FOREIGN KEY (`user_id`)
REFERENCES `zinc`.`app_user` (`user_id`)
ON DELETE CASCADE
ON UPDATE CASCADE)
ENGINE = InnoDB;
CREATE TABLE IF NOT EXISTS `folder_content` (
`user_id` INT NOT NULL,
`document_id` INT NOT NULL,
`content_id` INT NOT NULL,
PRIMARY KEY (`user_id`, `document_id`, `content_id`),
CONSTRAINT `fk_folder_content_folder`
FOREIGN KEY (`user_id` , `document_id`)
REFERENCES `zinc`.`user_folder` (`user_id` , `document_id`)
ON DELETE CASCADE
ON UPDATE CASCADE)
ENGINE = InnoDB;
I need to create a Sequelize model to represent it. The only problem I have is with the relation folder_content and user_folder because of the composite key.
How can I create this sequelize model?
This is what I have so far:
var AppUser = sequelize.define('app_user',
{userId: {type: Sequelize.INTEGER, primaryKey: true, field: 'user_id'}, ... } );
var UserFolder = sequelize.define('user_folder',
{userId: {type: Sequelize.INTEGER, primaryKey: true, field: 'user_id'},
documentId: {type: Sequelize.INTEGER, primaryKey: true, field: 'document_id'}... });
var FolderContent = sequelize.define('folder_content', {
userId: {type: Sequelize.INTEGER, primaryKey: true, field: 'user_id'},
documentId: {type: Sequelize.INTEGER, primaryKey: true, field: 'document_id'},
contentId: {type: Sequelize.INTEGER, primaryKey: true, field: 'content_id'}... });
UserFolder.hasMany(FolderContent);
FolderContent.belongsTo(UserFolder, {foreingKey: !! });// <- PROBLEM
Now Sequelize doesn't support composite foreign keys. This creates several problems.
When Sequelize creates a table, the table definition does not have a composite FK.
To solve this problem I use the afterSync hook on the model and a function
that adds a FK to the table if it does not exist. Example code.
When I use the findAll method with include such model, I use the include[].on option of the findAll method. Or if you don't use as many joins as I do, you can use scope when creating an association (see).
does sequelize still not support composite foreign keys? i would like to have a table with 2 foreign keys as the composite primary key. i would rather have it this way than have a surrogate key as the primary key with a unique constraint over the 2 foreign key fields.
thanks
I am trying to stop duplicates in my Mongo DB Collection but they are still getting in. I am reading data from twitter and storing it like:
var data = {
user_name: response[i].user.screen_name,
profile_image: response[i].user.profile_image_url,
content: {
text: response[i].text
},
id: response[i].id_str,
};
and I have the following to stop any duplicates:
db[collection].ensureIndex( { id: 1, "content.text": 1 }, { unique: true, dropDups: true } );
The id field is working and no duplicates appear but "content.text" field does not work and duplicates are appearing. Any Ideas why?
When you enforce a unique constraint on a composite index, two documents are considered same only if the documents have the same value for both id and context.text fields and not for either key individually.
To enforce unique constraints on the fields, id and context.text individually, You could enforce it as below:
db.col.ensureIndex({"id":1},{unique:true}) and similarly for the other field.