So I am using typeorm with ormconfig.json.
Since synchronize cannot be used in production, how can I run the migrations based on entities?
my ormconfig.json file
{
"type": "postgres",
"host": "localhost",
"port": 5432,
"username": "",
"password": "",
"database": "backend-api",
"synchronize": false,
"logging": true,
"migrationsRun": true,
"entities": ["dist/entity/**/*.js"],
"migrations": ["dist/migration/**/*.js"],
"subscribers": ["dist/subscriber/**/*.js"],
"cli": {
"entitiesDir": "src/entity",
"migrationsDir": "src/migration",
"subscribersDir": "src/subscriber"
}
}
Also here is my only Todo.ts entity file
import {
BaseEntity,
Column,
CreateDateColumn,
Entity,
PrimaryGeneratedColumn,
UpdateDateColumn,
} from 'typeorm';
#Entity()
export class Todo extends BaseEntity {
#PrimaryGeneratedColumn()
id: number;
#Column('text')
text: string;
#Column('boolean', { default: false })
completed: boolean;
#CreateDateColumn()
createdAt: Date;
#UpdateDateColumn()
updatedAt: Date;
}
Got the solution for this problem.
So my ormconfig.json needed a slight update,
{
"type": "postgres",
"host": "localhost",
"port": 5432,
"username": "",
"password": "",
"database": "backend-api",
"synchronize": false,
"logging": true,
"migrationsRun": false,
"entities": ["src/entity/**/*.ts"],
"migrations": ["src/migration/**/*.ts"],
"subscribers": ["src/subscriber/**/*.ts"],
"cli": {
"entitiesDir": "src/entity",
"migrationsDir": "src/migration",
"subscribersDir": "src/subscriber"
}
}
and i needed to install ts-node to compile the ts entity and migration files.
I created the below mentioned scripts:
"scripts": {
"start": "ts-node src/index.ts",
"entity:create": "./node_modules/.bin/ts-node ./node_modules/.bin/typeorm entity:create -n",
"migrate:generate": "./node_modules/.bin/ts-node ./node_modules/.bin/typeorm migration:generate -n",
"migrate:run": "./node_modules/.bin/ts-node ./node_modules/.bin/typeorm migration:run",
"migrate:revert": "./node_modules/.bin/ts-node ./node_modules/.bin/typeorm migration:revert",
"schema:drop": "./node_modules/.bin/ts-node ./node_modules/.bin/typeorm schema:drop"
}
and in the order of the script.
The one thing I learned is you cannot simply crate an entity file and run migration:generate on it. You first need to create an entity based on typeorm cli. I don't know why, but for me once I started creating the entity using the cli everything fallen into place
To run the migrations based on entities, you can generate the migrations files from your entities as said in the TypeOrm documentation about generating migrations.
TypeORM is able to automatically generate migration files with schema changes you made.
Run this command specifying the name of the migration to generate the file:
typeorm migration:generate -n <MigrationName>
After it, you just need to run your migrations by using the CLI:
typeorm migration:run
A good practice is to use the migrationsRun parameter to your database configuration to run your migrations on start:
migrationsRun: true,
Related
I am working with typeorm and Oracle with typescript, but I have the following problem when I want to connect.
Basically I want to use externalAuth but it tells me that the variable is read only, how can I solve it??
Cannot assign to 'externalAuth' because it is a read-only
import { DataSource } from "typeorm"
import { Empleado } from "./entity/Empleado"
import * as oracledb from "oracledb";
oracledb.externalAuth = true;
oracledb.initOracleClient({ libDir: 'C:\\instantclient_19_12' });
export const AppDataSource = new DataSource({
type: "oracle",
connectString: "xxxxx",
database: "xxxx",
synchronize: false,
logging: true,
entities: [Empleado],
migrations: [],
subscribers: [],
})```
From a quick test with the TypeORM sample app, setting externalAuth using the extra attribute in the project's ormconfig.json file like this seems to pass through the correct settings to node-oracledb:
{
"type": "oracle",
"connectString": "localhost/orclpdb1",
"synchronize": true,
"logging": false,
"extra" : {
"externalAuth": true
},
"entities": [
"src/entity/**/*.ts"
],
"migrations": [
"src/migration/**/*.ts"
],
"subscribers": [
"src/subscriber/**/*.ts"
],
"cli": {
"entitiesDir": "src/entity",
"migrationsDir": "src/migration",
"subscribersDir": "src/subscriber"
}
}
I use Node Js with Typeorm and Mysql.
When i restart the server the BLOB img disappear from database, because the the server always drop the column ¿How can avoid this?
The drop:
query: ALTER TABLE `products_images` DROP COLUMN `img`
query: ALTER TABLE `products_images` ADD `img` blob NULL
Example of my code:
#Entity('products_images')
export class ProductsImages extends Base {
#Column("blob", { nullable: true })
img: Buffer;
}
you can made change in ormconfig.json file "synchronize" : false
and serve again
might be your problem is solved
its work for me
{
"type": "mysql",
"host": "",
"port": 3306,
"username": "root",
"password": "",
"database": "money",
"synchronize": false,
"logging": true,
"entities": ["dist/entity/**/*.js"],
"migrations": ["dist/migration/**/*.js"],
"subscribers": ["dist/subscriber/**/*.js"],
"cli": {
"entitiesDir": "./src/entity",
"migrationsDir": "./src/migration",
"subscribersDir": "./src/subscriber"
}
}
Remove the dist folder in your project and rerun the app.
This helps me.
i have this ormconfig.json:
{
"type": "postgres",
"host": "db-pg",
"port": 5432,
"username": "spirit",
"password": "api",
"database": "emasa_ci",
"synchronize": true,
"logging": false,
"entities": ["dist/src/entity/**/*.js"],
"migrations": ["dist/src/migration/**/*.js"],
"subscribers": ["dist/src/subscriber/**/*.js"],
"cli": {
"entitiesDir": "dist/src/entity",
"migrationsDir": "dist/src/migration",
"subscribersDir": "dist/src/subscriber"
}
}
and have this env:
SERVER_PORT=4000
DB_HOST=db-pg
DB_PORT=5432
DB_USER=spirit
DB_PASS=api
DB_NAME=emasa_ci
but .env doesn't work in .json and so I don't know how I'm going to use my enviroment variables in my config orm
There is a good documentation.
If you want to dig into the source code - there is a class ConnectionOptionReader, which is looking for file ormconfig (with extensions env, js, cjs, ts, json, yml, yaml, xml) or for file .env. See the load function for more details.
1 So the easiest way is to add a line in your .env file, like this:
TYPEORM_URL=postgres://user:pass#host:port/dbname
Or use this sample. TypeORM will parse .env file using dotenv.
Here you can find all available env varibales.
2 If you read your .env file before TypeORM initialization, you can already use your env variables. For example in a Javascript file, instead ormconfig.json. Just export object like this from the file ormconfig.js:
module.exports = {
"type": "postgres",
"host": process.env.DB_HOST,
"port": process.env.DB_PORT,
"username": process.env.DB_USER,
"password": process.env.DB_PASS,
"database": process.env.DB_NAME,
"synchronize": true,
"logging": false,
"entities": ["dist/src/entity/**/*.js"],
"migrations": ["dist/src/migration/**/*.js"],
"subscribers": ["dist/src/subscriber/**/*.js"],
"cli": {
"entitiesDir": "dist/src/entity",
"migrationsDir": "dist/src/migration",
"subscribersDir": "dist/src/subscriber"
}
};
Another example
Since ormconfig is deprecated, I suggest another approach using TypeORM DataSource.
I'm using Heroku to deploy my server, so I created an environment file containing the same variable as created in Heroku Dynos, named .development.env:
DATABASE_URL="postgres://user:password#localhost:5432/main"
Note that you can place this file anywhere in your project tree.
Then I created a datasource file:
import dotenv from 'dotenv';
import { DataSource } from 'typeorm';
// Load env file
dotenv.config({ path: '../api/.development.env' });
DataSource definition
const AppDataSource = new DataSource({
type: 'postgres',
url: process.env.DATABASE_URL,
logging: true,
entities: ['../api/dist/**/*.entity.js'],
migrations: ['./migrations/*.js'],
subscribers: [],
});
export default AppDataSource;
This way, you can store in your environment your database connection settings.
You could hide ormconfig.json and put your secrets directly in there, or viceversa, load TypeORM's configuration from your .env file. Is there a precise reason why you need them to be separated? If yes, then we can work out a solution.
Background
I am creating a boilerplate express application. I have configured a database connection using pg and sequelize. When I add the cli and try to run sequlize db:migrate I get this error,
ERROR: The dialect [object Object] is not supported. Supported
dialects: mssql, mysql, postgres, and sqlite.
Replicate
Generate a new express application. Install pg, pg-hstore, sequelize and sequelize-cli.
Run sequelize init.
Add a config.js file to the /config path that was created from sequelize init.
Create the connection in the config.js file.
Update the config.json file created by sequelize-cli.
Run sequelize db:migrate
Example
/config/config.js
const Sequelize = require('sequelize');
const { username, host, database, password, port } = require('../secrets/db');
const sequelize = new Sequelize(database, username, password, {
host,
port,
dialect: 'postgres',
operatorsAliases: false,
pool: {
max: 5,
min: 0,
acquire: 30000,
idle: 10000
}
});
module.exports = sequelize;
/config/config.js
{
"development": {
"username": "user",
"password": "pass",
"database": "db",
"host": "host",
"dialect": "postgres"
},
"test": {
"username": "user",
"password": "pass",
"database": "db",
"host": "host",
"dialect": "postgres"
},
"production": {
"username": "user",
"password": "pass",
"database": "db",
"host": "host",
"dialect": "postgres"
}
}
Problem
I expect the initial migrations to run but instead get an error,
ERROR: The dialect [object Object] is not supported. Supported
dialects: mssql, mysql, postgres, and sqlite.
Versions
Dialect: postgres
Dialect version: "pg":7.4.3
Sequelize version: 4.38.0
Sequelize-Cli version: 4.0.0
Package Json
"pg": "^7.4.3",
"pg-hstore": "^2.3.2",
"sequelize": "^4.38.0"
Installed globally
npm install -g sequelize-cli
Question
Now that the major rewrite has been released for sequelize, what is the proper way to add the dialect so the migrations will run?
It is important to note that my connection is working fine. I can query the database without problems, only sequelize-cli will not work when running migrations.
i ran into same problem. there is a few thing that you need to change. first, i am not sure why you had 2 config/config.js file. i assumed the second file is config.json. the reason run into this problem is that
const sequelize = new Sequelize(database, username, password, {
host,
port,
dialect: 'postgres',
operatorsAliases: false,
pool: {
max: 5,
min: 0,
acquire: 30000,
idle: 10000
}
});
these lines of code is used for the node server to access db, not for sequlize-cli to migrate. you need to follow exact the sequlize-cli instruction. here is the link: instruction
my code:
config/db.js
const {sequlize_cli} = require('../config.json');
module.exports = sequlize_cli;
config.json
{
"sequlize_cli":{
"development":{
"username":"root",
"password":"passowrd",
"database":"monitor",
"host":"127.0.0.1",
"dialect": "postgres"
},
"test": {
"username":"root",
"password":"passowrd",
"database":"monitor",
"host":"127.0.0.1",
"dialect": "postgres"
},
"production": {
"username":"root",
"password":"passowrd",
"database":"monitor",
"host":"127.0.0.1",
"dialect": "postgres"
}
}
}
the main point i guess is to export the json object directly instead of exporting a sequelize object. In addition, this is only the problem with postges , i tested with mysql, your code works perfectly with mysql.
Just following the sequelize doc ( http://docs.sequelizejs.com/manual/tutorial/migrations.html ), we can generate a model and a migration file using the sequelize-cli command like:
sequelize model:generate --name Users --attributes firstName:string,lastName:string,bio:text
but then, in the migration file, one can find two additional timestamps values that will be added to the DB:
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
I know I can set timestamp: false and/or deleting these two entries manually, but it would be better to set an option while generating the model/migration files not to have these timestamps. Is there such a way?
You can set the options in config.json as well. It works for all models.
"dialect": "mysql",
"logging": false,
"define": {
"timestamps": true
}
Use --underscored param for sequelize-cli.
Example:
sequelize-cli model:generate --name User --attributes login:string,password:string,token:string,token_exp:date,firstName:string,lastName:string,email:string,phone:string --underscored
or use file 'config.json' with this contents:
{
"define": {
"underscored": true,
"freezeTableName": true,
"charset": "utf8",
"dialectOptions": {
"collate": "utf8_general_ci"
},
"timestamps": true,
"createdAt": "created_at",
"updatedAt": "updated_at",
"createdBy": "created_by",
"updatedBy": "updated_by"
}
}
..and pass it to command line as param:
sequelize-cli model:generate --name User --attributes login:string,password:string,token:string,token_exp:date,firstName:string,lastName:string,email:string,phone:string --config config.json