Change column name Sequilize - node.js

I want to change default column name in my final output which comes from Mysql database when i am accessing database using NodeJS and Sequelize connection.
I am connecting using following code:-
import Sequelize from "sequelize";
let dbConnection = new Sequelize('DB', 'abc', 'password', {
host: '127.0.0.1',
port: 4242,
dialect: 'mysql',
dialectOptions: {
requestTimeout: 0,
},
});
const Listing = dbConnection.define('TableName', {
tour_title: {
type: Sequelize.STRING,
}
}, { freezeTableName: true, timestamps: false });
For example, I want to change tour_title by tour_name in the above column only in the final sequelize output. I do not want any change in database column names.

To change column name only in final output
TableName.findAll({
attributes: ['id', ['tour_title', 'tour_name']] /
})
.then((data) => {
console.log(data);
});
To change column name in database
This may help you, follow this steps
Step 1: npm install -g sequelize-cli
To install sequelize command line tool
Step 2: sequelize migration:create --name rename-column-tour_title-to-tour_name-in-tabelname
Step 3: Open newly created migration file and add below code
'use strict';
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.renameColumn('tableName', 'tour_title', 'tour_name');
},
down: (queryInterface, Sequelize) => {
return queryInterface.renameColumn('tableName', 'tour_name', 'tour_title');
}
};
Step 4: in command line run this below command
sequelize db:migrate
Now your column name changed successfully.

If you want an alias for a column name in the ouput , you can do something like this:
TableName.findAll({
attributes: ['id', ['tour_title', 'tour_name']] //id, tour_title AS tour_name
})
.then(function(data) {
res.json(data);
});
Whenever you fetch any records you can write the column name in a cascaded list and make an alias.
Check for the documentation here : http://docs.sequelizejs.com/manual/tutorial/querying.html

The above answers only works for the query results. If you want to keep your underscore name convention on the database and use for example camelCase for your javascript environment you need to do this:
const ChildTable = dbConnection.define('ChildTable', { //this table name is how you call it on sequelize
tourTitle: { //this is the name that you will use on javascript
field: 'tour_title', // this will be the name that you fetch on your db
type: Sequelize.STRING,
},
parentTableId: { // You need to define the field on the model, otherwise on sequelize you'll have to use the db name of the field
field: 'parent_table_id', //this is defined above on the association part
type: Sequelize.INTEGER,
}
}, { freezeTableName: true, timestamps: false, tableName: 'TableName', //this is the real name of the table on the db
underscored: true, });
ChildTable.associate = (models) => {
ChildTable.belongsTo(models.ParentTable, { as: 'ParentTable', foreignKey: 'parent_table_id', onDelete: 'cascade' });
};
This way you have an "alias" for your fields on all the Sequelize / javascript environment and you keep your names on the db. See also that you have to do the same with the foreign keys on associations, otherwise you'll have to use the original name.

I'd add something to #Deepak's answer. When I tried it the Step 4: (I am a newbie), it prompted that
"Cannot find config.json Have you run sequelize init? "
Then I executed that init command then it made a config.json file inside the config folder. So the file contained below objects.
{
"development": {
"username": "root",
"password": null,
"database": "database_development",
"host": "127.0.0.1",
"dialect": "mysql"
},
"test": {
"username": "root",
"password": null,
"database": "database_test",
"host": "127.0.0.1",
"dialect": "mysql"
},
"production": {
"username": "root",
"password": null,
"database": "database_production",
"host": "127.0.0.1",
"dialect": "mysql"
}
}
Then I executed the sequelize db:migrate. It prompted another error as
Sequelize CLI [Node: 18.7.0, CLI: 6.4.1, ORM: 6.21.4]
Loaded configuration file "config\config.json".
Using environment "development".
ERROR: Access denied for user 'root'#'localhost' (using password: NO)
Then what I did was I changed the config.json file to something like this -->
{
"development": {
"username": "root",
"password": "<this should include your root password>",
"database": "<this should include your db>",
"host": "127.0.0.1",
"dialect": "mysql"
},
"test": {
"username": "root",
"password": null,
"database": "database_test",
"host": "127.0.0.1",
"dialect": "mysql"
},
"production": {
"username": "root",
"password": null,
"database": "database_production",
"host": "127.0.0.1",
"dialect": "mysql"
}
}
And then migration was done successfully!

Related

Typeorm is not saving data in table. How to do Migrations in typeorm?

I have this mutation
#Mutation(() => AuthResponse, { nullable: true })
async signUp(
#Ctx() { req }: MyContext,
#Arg("details") details: UsernamePasswordTypes
): Promise<AuthResponse> {
const { password, username } = details;
const user = await User.create({
username,
password: "hasedPassword"
});
try {
await user.save();
req.session.userId = user.id;
console.log("USER CREATED",user)
return {user}
} catch (e) {
return {
errors: [
{
field: "username",
message: "username already taken",
},
],
};
}
}
In this i can see USER created
I have 2 problems
It is not printing password field in console
It is not saving data in postgres db but it have created user table
Note : I am running this code for first time so i think i need to create table and fields so dont know how to. How to create migrations in typeorm ??
You have two ways to create migrations using TypeOrm.
There are two methods you must fill with your migration code: up and down. up has to contain the code you need to perform the migration. down has to revert whatever up changed. down method is used to revert the last migration.
You can manually create them using typeorm migration:create -n migrationName adding your up and down instructions:
import { MigrationInterface, QueryRunner } from 'typeorm';
export class PostRefactoringTIMESTAMP implements MigrationInterface {
async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`CREATE TABLE "users" ("create_date" TIMESTAMP NOT NULL DEFAULT now(), "update_date" TIMESTAMP NOT NULL DEFAULT now(), "delete_date" TIMESTAMP, "id" SERIAL NOT NULL, "firstName" character varying NOT NULL, "lastName" character varying NOT NULL, "email" character varying NOT NULL, "phone" character varying, "password" character varying NOT NULL)`);
}
async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`DROP TABLE "users"`);
}
}
Else, you can generate them from your entities using typeorm migration:generate -n generatedMigrationName.
When your migrations are done, you can run them with typeorm migration:run and typeorm migration:revert to use the down method.
Don't forget to setup your connection options properly:
{
"type": "mysql",
"host": "localhost",
"port": 3306,
"username": "test",
"password": "test",
"database": "test",
"entities": ["entity/*.js"],
"migrationsTableName": "custom_migration_table",
"migrations": ["migration/*.js"],
"cli": {
"migrationsDir": "migration"
}
}
If you have more questions, mind reading the TypeOrm documentation about migrations

Migrations with Separate Entity Definition

I am trying to update my database using the entities with separate entity definition.
The database isn't updated either with the option synchronize = true or with the command:
ts-node ./node_modules/typeorm/cli.js migration:generate -n CreateDatabase
which generates an empty migration file.
What am I forgetting?
Steps to reproduce or a small repository showing the problem:
ormconfig.json
{
"type": "postgres",
"host": "localhost",
"port": 5432,
"username": "postgres",
"password": "secret",
"database": "app",
"entities": ["src/**/entities/*.entity.ts"],
"migrations": ["src/database/migrations/*.ts"],
"cli": {
"migrationsDir": "src/database/migrations"
},
"synchronize": true
}
topic.entity.ts
export class Topic {
title: string
}
topic.schema.ts
import { EntitySchema, EntitySchemaColumnOptions } from 'typeorm'
import { Topic} from '../topic.entity'
export const TopicSchema = new EntitySchema<Topic>({
name: 'topics',
target: Topic,
columns: {
title: {
name: 'title',
type: 'text',
nullable: true,
} as EntitySchemaColumnOptions,
},
})
Try split the topic.entity.ts to topic.entity.ts and topic.schema.ts and use only the topic.schema.ts on your ormconfig.json.
Change the entities section from your ormconfig.json to:
"entities": ["src/**/entities/*.schema.ts"]
I was struggling with this. What I did was to split into
Model and Schema. Model is a common Class.
Session.ts
export class Session {
token: string;
userId: string;
}
Session.entity.ts
And Schema. If you forget target it unifies every entity into one table. Don't forget that. And use the same name as model so it matches properly.
import {EntitySchema} from "typeorm";
import { Session } from "../models/Session";
export const SessionEntity = new EntitySchema<Session>({
name: "Session", // BE CAREFUL: must be the same name as Model, STRING
target: Session, // This must be the Class itself, NOT STRING
columns: {
token: {
type: String,
primary: true,
generated: "uuid"
},
userId: {
type: String
}
}
});
And to use it
import { SessionEntity } from "../entities/Session.entity";
const connection = this.typeORMService.get("default");
const repository = this.ormService.connection.getRepository(SessionEntity);
const session = await repository.save({userId: "123"});
Another issue that you may have is that if you add your settings in the code and in ormconfig.json it will use the code settings. So be careful with that as well.
I prefer to setup settings in code like this:
const rootDir = __dirname;
#Configuration({
rootDir,
typeorm: [
{
name: "default",
synchronize: true,
type: "postgres",
url: process.env.DATABASE_URL || config.DATABASE_URL,
ssl: process.env.DATABASE_URL ? true : false, // If env var is not set then it is dev
"entities": [
`${rootDir}/**/*.entity.js`,
`${rootDir}/**/*.entity.{ts,js}`
],
"migrations": [`${rootDir}/migrations/**/*.js`],
subscribers: [
`${rootDir}/subscriber/*.js}`
]
}
]
})
I hope you find this useful. If you have any doubts please let me know.

Sequelize .create is not generating content for my model

I looked for this question everywhere but, I haven't found it.
I'm using Sequelize for Postgres, and I'm trying to add content to a model. It's not throwing any errors, except just a warning that says that string based operations have been deprecated, but this isn't an operation.
sequelize deprecated String based operators are now deprecated. Please use Symbol based operators for better security, read more at http://docs.sequelizejs.com/manual/tutorial/querying.html#operators
Here's my model and .create code
const Sequelize = require('sequelize');
const sequelizeInstance = new Sequelize('journal_entries', 'KupidoExportLLC',
{
dialect: 'postgres'
});
module.exports = function(sequelizeInstance, DataTypes){
const Entries = sequelizeInstance.define('entries', {
user: Sequelize.STRING,
title: Sequelize.STRING,
content: Sequelize.TEXT
})
Entries.sync().then(function(){
Entries.create({
user: 'I need to get this to work',
title: 'Ill be really happy when this does work',
content: 'It will work this time'
})
});
return Entries;
}
Here's what my commandline is showing
sequelize deprecated String based operators are now deprecated. Please use Symbol based operators for better security, read more at http://docs.sequelizejs.com/manual/tutorial/querying.html#operators node_modules/sequelize/lib/sequelize.js:242:13
When I go look at my table, it's empty
journal_entries=# SELECT * FROM entries;
id | user | title | content | createdAt | updatedAt
----+------+-------+---------+-----------+-----------
(0 rows)
I have no idea what else it could be
You need to turn off the warnings.
In your config.JSON file or (If you have initialize the connection in the same file)
Turn the warning off, as given:
IN Config.JSON
{
"development": {
"username": "root",
"password": "12345",
"database": "fasttrack",
"host": "localhost",
"dialect": "mysql",
"define": {
"timestamps": false
},
"operatorsAliases": false
},
"test": {
"username": "root",
"password": "12345",
"database": "fasttrack",
"host": "localhost",
"dialect": "mysql",
"define": {
"timestamps": false
},
"operatorsAliases": false
},
"production": {
"username": "root",
"password": "12345",
"database": "fasttrack",
"host": "localhost",
"dialect": "mysql",
"define": {
"timestamps": false
},
"operatorsAliases": false
}
}
Inline declaration of connection
const sequelize = new Sequelize(config.database, config.username, config.password, {
host: config.host,
dialect: config.dialect,
pool: {
max: 5,
min: 0,
idle: 10000
},
logging: false,
freezeTableName: true,
operatorsAliases: false
});
you are working with Promises here, you have either to await or return them.
if you have async await available in your node version you could just do:
module.exports = async function(sequelizeInstance, DataTypes){
const Entries = sequelizeInstance.define('entries', {
user: Sequelize.STRING,
title: Sequelize.STRING,
content: Sequelize.TEXT
});
await sequelizeInstance.sync();
await Entries.create({
user: 'I need to get this to work',
title: 'Ill be really happy when this does work',
content: 'It will work this time'
});
const entries = await Entries.findAll();
console.log(entries.map(e => e.get({ plain: true })));
return Entries;
};
or if not
module.exports = async function(sequelizeInstance, DataTypes){
const Entries = sequelizeInstance.define('entries', {
user: Sequelize.STRING,
title: Sequelize.STRING,
content: Sequelize.TEXT
});
return sequelizeInstance.sync().then(() => {
return Entries.create({
user: 'I need to get this to work',
title: 'Ill be really happy when this does work',
content: 'It will work this time'
});
})
.then(() => {
return Entries.findAll().then(entries => {
console.log(entries.map(e => e.get({ plain: true })));
return entries;
})
});
};

sequelize seed unable to insert the data in SQLite

I am trying to insert the dummy data using sequelize-cli command
sequelize db:seed --seed seeders/20170212081140-subject_tags.js
here is my config file
{
"development": {
"username": "root",
"password": null,
"database": "database_development",
"host": "127.0.0.1",
"dialect": "sqlite",
"seederStorage": "sequelize",
"storage": "./test"
}
}
and here my seeder file
use strict';
module.exports = {
up: function(queryInterface, Sequelize) {
return
queryInterface.bulkUpdate('subject_tags', [
{
tag: 'agricultural-sciences',
tag_description: '',
subject_category: 'biological_&_medical_sciences',
createdAt: new Date(),
updatedAt: new Date()
}, {
tag: 'biochemistry',
tag_description: '',
subject_category: 'biological_&_medical_sciences',
createdAt: new Date(),
updatedAt: new Date()
}, {
tag: 'bioinformatics',
tag_description: '',
subject_category: 'biological_&_medical_sciences',
createdAt: new Date(),
updatedAt: new Date()
}
] , {});
},
down: function(queryInterface, Sequelize) {
return
queryInterface.bulkDelete('subject_tags', null, {});
}
};
Though I am getting the status
Using environment "development".
== 20170212081140-subject_tags: migrating =======
== 20170212081140-subject_tags: migrated (0.053s)
I tried bulkCreate and bulkInsert in the seed file , all of them run successful, but data does not get inserted into the table
the data does not get inserted. Is I am doing something wrong?
It seems to be issue with sequlizer, after return statement it unable to handle space with newline character
module.exports = {
up: function(queryInterface, Sequelize) {
//old code
//return
// queryInterface.bulkUpdate('subject_tags', [
//new code
return queryInterface.bulkUpdate('subject_tags', [
//.........
Javascript will automatically add a semi-colon after a dangling return statement.
It doesn't reach the bulkUpdate code.

Loopback [nodejs] automigrate/auto-updating model to mongodb

New to loopback and and I can't for the life of me migrate a single json model to my mongodb data source.
I've been fussing about with: https://docs.strongloop.com/display/public/LB/Creating+a+database+schema+from+models
And here's what I've tried so far:
I created a migration script bin/migrate.js which I plan on running every time I need to migrate changes using auto-update:
var path = require('path');
var app = require(path.resolve(__dirname, '../server/server'));
var ds = app.datasources.acme;
var appModels = ['Client'];
ds.isActual(appModels, function(err, actual) {
if (!actual) {
ds.autoupdate(appModels, function(err) {
if (err){
throw (err);
}
});
}
});
console.log("Migrated: " + appModels.join());
I checked both using robomongo and the mongo cli and I can't find the generated table:
> use acme
switched to db acme
> db.getCollectionNames();
[ ]
I'm also new to mongodb so there may be something wrong as well in how I'm checking if the migration succeeded.
I've tried the answer here but it didn't work for me: Migrating built-in models to Databases
Some other pertinent stuff:
datasources.json
{
"acme": {
"host": "127.0.0.1",
"port": 27017,
"database": "acme",
"username": "root",
"password": "password",
"name": "acme",
"connector": "mongodb",
"user": "root"
}
}
My model
{
"name": "Client",
"plural": "Clients",
"base": "User",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"contact_number": {
"type": "string"
}
},
"validations": [],
"relations": {},
"acls": [],
"methods": {}
}
Turns out that this was actually working. Coming from a mysql background, I didn't know that the you can only see a mongodb collection once there are documents inside it.
I got the visual confirmation I was looking for when I added the following:
app.models.Client.create([
{contact_number: '09xxxxxxx', password: 'password', email: 'acme#gmail.com'},
], function(err, clients) {
if (err){
throw err;
}
console.log('Models created: \n', clients);
});

Resources