When I lift my sails project I get these warnings on terminal
debug: Deprecated: config.adapters.default debug: (see
http://links.sailsjs.org/docs/config/connections) debug: For now, I'll
pretend you set config.models.connection.
debug: Deprecated: config.adapters debug: (see
http://links.sailsjs.org/docs/config/connections) debug: For now, I'll
pretend you set config.connections.
debug: Deprecated: config.adapters.*.module debug: (see
http://links.sailsjs.org/docs/config/connections) debug: For now, I'll
pretend you set config.connections["disk"].adapter.
And my data is not stored in mysql DB.
This is my api model code
module.exports = {
schema:true,
tableName: 'BusStop',
adapters: 'mysql-adapter',
migrate: 'safe',
attributes: {
stopID:{
type: 'int'
},
stopName:{
type: 'string'
},
latitude:{
type: 'float'
},
longitude:{
type: 'float'
}
}
};
This is my local.js code
module.exports = {
port: process.env.PORT || 1337,
environment: process.env.NODE_ENV || 'development',
adapters:{
'default': 'disk',
disk:{
module:'sails-disk'
},
'mysql-adapter': {
module : 'mysql-sails',
host : '127.0.0.1',
user : 'root',
password : '',
database : 'PublicTransport',
schema : true
}
}
};
And this is my connections.js code
module.exports.connections = {
localDiskDb: {
adapter: 'sails-disk'
},
'mysql-adapter': {
module : 'sials-mysql',
host : '127.0.0.1',
port : 3306,
user : 'root',
password : '',
database : 'PublicTransport'
},
someMongodbServer: {
adapter: 'sails-mongo',
host: 'localhost',
port: 27017,
},
somePostgresqlServer: {
adapter: 'sails-postgresql',
host: 'YOUR_POSTGRES_SERVER_HOSTNAME_OR_IP_ADDRESS',
user: 'YOUR_POSTGRES_USER',
password: 'YOUR_POSTGRES_PASSWORD',
database: 'YOUR_POSTGRES_DB'
}
};
I want to know how can I remove these Deprecated warnings and why my data is not being stored in the Database.
Looks like the links in those deprecation warnings are incorrect. For information on how to configure Sails connections, see http://sailsjs.org/#/documentation/reference/sails.config/sails.config.connections.html.
You should be able to make those messages go away by following their instructions regarding what config keys to set.
In order to set a connection for a specific model, you now set the connection property:
module.exports = {
schema:true,
tableName: 'BusStop',
connection: 'mysql-adapter', // "adapter" is now "connection
migrate: 'safe',
attributes: {...}
}
In order to specify the adapter to use for a connection, use the adapter key, not module; you're already doing this in most of your connections, you just need to update mysql-adapter.
In your config/local.js you're using the deprecated adapters key to set up connections; use connections instead.
Lastly, in order to set a default connection for all of your models, you do as the deprecation message says and set sails.config.models.connection rather than sails.config.adapters.default; you can do so easily in the config/models.js file, or in your config/local.js like so:
module.exports = {
models: {
connection: 'mysql-adapter'
},
...more config...
}
This warning can also be generated if your project has an config/adapters.js file. If the file is empty it can be deleted and Zap the warning is gone.If it contains code then you will need to migrate it to the correct path config/models.js and config/connections.js
Related
I'm using Sequelize ORM for my nodejs project and it seems there is a mistake in configuration or I'm doing something really awry with the queries... The problem is that our client will make more than 60 connections sometimes when the user is requesting a lot of information at once (graphql request with deep structure and data loaders on top for a lot of records fetched from MySQL). The pool settings should not let do that since it is configured for 10 max connections at once. The main question is how those connections appear? The app is being hosted at AWS using ELB, for MySQL we are using RDS and we can have up to 2 app instances at once, so no more than 20 connections at all. Sequelize config:
production: {
username: process.env.DB_USER,
password: process.env.DB_PASS,
database: process.env.DB_NAME,
host: process.env.DB_HOST,
dialect: 'mysql',
define: {
charset: 'utf8mb4',
collate: 'utf8mb4_general_ci',
},
pool: {
max: parseInt(process.env.DB_POOL_SIZE, 10), // 10 from ENV variables
min: 0,
acquire: 60000,
idle: 60000,
},
operatorsAliases: 0,
logging: false,
},
once there are >50 connections on our RDS client we can see that our ELB can't perform health check since it can't make new connections and return positive status from MySQL. so our app becomes unreachable.
After bombing the backend with this particular query I've fetched processlist for MySQL. Some sleeping queries will go to more than 1000 "time".
Also I'm going to attach my Sequelize connection config. It is a singleton object which will be run only once the app is loaded. But on the other hand, I'm importing models from this file everywhere in the project. But is it a mistake?
/* eslint-disable import/no-cycle */
import { Sequelize } from 'sequelize-typescript';
import databaseConfig from '#config/database';
import models from './models';
const env = process.env.NODE_ENV || 'development';
const database = (databaseConfig as any)[env];
const sequelize = new Sequelize(database.database, database.username, database.password, {
host: database.host,
dialect: database.dialect,
define: database.define,
pool: database.pool,
operatorsAliases: database.operatorsAliases,
logging: database.logging,
retry: {
match: [
/SequelizeConnectionError/,
/SequelizeConnectionRefusedError/,
/SequelizeHostNotFoundError/,
/SequelizeHostNotReachableError/,
/SequelizeInvalidConnectionError/,
/SequelizeConnectionTimedOutError/,
],
max: Infinity,
},
});
sequelize.addModels(Object.values(models));
setTimeout(() => console.log('Waiting for mysql connection...'), 200);
sequelize.sync().then(() => console.log('Mysql connection established'));
export const {
... 16 MODELS...
} = models;
export { sequelize, Sequelize };
also I'm using sequelize suggested config in .sequelizerc file to make a connection when running migrations etc..
const path = require('path');
module.exports = {
'config': path.resolve('dist', './config/database.js'),
'models-path': path.resolve('dist', './models'),
'seeders-path': path.resolve('dist', './seeders'),
'migrations-path': path.resolve('dist', './migrations')
}
What I'm missing here?
I am trying to connect to MySQL. I have defined the db connection vars in a .env file in my root dir, and I am initializing the connection in the app.module.ts file.
the only issue I am facing now is when creating or running migrations using the CLI,
I followed the typeorm docs here to configure the connection, however when I run typeorm migrate:create -n myNewTable, it should create the migration file in the specified directory, what it does instead is it creates it in the app root directory,
similarily, I solved the issue by using the -d flag after the typeorm migrate:create to specify the directory, however when I try running my migration files, I get this
No connection options were found in any of configurations file.
here is my app.module.ts file.
TypeOrmModule.forRoot({
type: 'mysql',
host: process.env.TYPEORM_HOST,
port: parseInt(process.env.TYPEORM_PORT, 10),
username: process.env.TYPEORM_USERNAME,
password: process.env.TYPEORM_PASSWORD,
database: process.env.TYPEORM_DATABASE,
synchronize: false,
migrations: [process.env.TYPEORM_MIGRATIONS],
cli: {
migrationsDir: process.env.TYPEORM_MIGRATIONS_DIR,
},
logging: (process.env.TYPEORM_LOGGING === 'true') ? true : false,
entities: [__dirname + '/../**/*.entity{.ts,.js}'],
}),
and here is my .env file
# use .ts for development, .js for production
TYPEORM_CONNECTION = mysql
TYPEORM_HOST = 127.0.0.1
TYPEORM_PORT = 3306
TYPEORM_USERNAME = <username>
TYPEORM_PASSWORD = <password>
TYPEORM_DATABASE = <dbname>
TYPEORM_SYNCHRONIZE = true
TYPEORM_MIGRATIONSRUN = true
TYPEORM_LOGGING = true
TYPEORM_ENTITIES = src/**/**.entity.ts
#TYPEORM_ENTITIES = src/**/**.entity.js
TYPEORM_SUBSCRIBERS = src/subscriber/*.ts
#TYPEORM_SUBSCRIBERS = src/subscriber/*.js
TYPEORM_MIGRATIONS = src/database/migration/*.ts
TYPEORM_MIGRATIONS_DIR = src/database/migration
TYPEORM_SUBSCRIBERS_DIR = src/subscriber
any help/hint is highly appreciated, thanks in advance.
Try to change your entities dir in ormconfig.json or .env, it worked for me as:
"entities": ["dist/**/**.entity{.ts,.js}"]
There is an issue, how you are loading the **TypeOrmModule**. The way, you had loaded, it is synchronous so it simply means custom env will not be available instantly on application boot.
So what you can do, is to load TypeOrmModule` asynchronusly like below -
ConfigModule.forRoot({
isGlobal: true, // [REQUIRED if want to use env gloablly among all modules]
}),
TypeOrmModule.forRootAsync({
useFactory: () => ({
type: 'mysql',
host: process.env.TYPEORM_HOST,
port: parseInt(process.env.TYPEORM_PORT, 10),
username: process.env.TYPEORM_USERNAME,
password: process.env.TYPEORM_PASSWORD,
database: process.env.TYPEORM_DATABASE,
synchronize: false,
migrations: [process.env.TYPEORM_MIGRATIONS],
cli: {
migrationsDir: process.env.TYPEORM_MIGRATIONS_DIR,
},
logging: process.env.TYPEORM_LOGGING === 'true' ? true : false,
entities: [__dirname + '/../**/*.entity{.ts,.js}'],
}),
}),
You should specify the connection in ormconfig.json in the project root folder.
looking something like this
{
"type": "postgres",
"host": "localhost",
"port": <port>,
"username": "",
"password": "",
"database": "",
"entities": ["dist/**/*.entity{.ts,.js}"],
"synchronize": true,
"logging": "all",
"migrations": [
"migrations/**/*.js"
],
"subscribers": [
"subscriber/**/*.js"
],
"cli": {
"migrationsDir": "<migrations directory>",
"subscribersDir": "<subscriber directory>"
}
}
Read more in the documentation chapter
On a side note, you might have to remove your dist/ folder for changes to get through.
I'm trying to connect to my local MYSQL(ran by XAMPP) through Sequelize:
const sequelize = new Sequelize(process.env.MYSQL_DB, 'root', '', {
host: process.env.CLEARDB_DATABASE_URL,
dialect: 'mysql',
logging: false
});
The process.env.CLEARDB_DATABASE_URL variable is set to "localhost", just like the documentation says(i'm using this specific variable because i want to deploy to Heroku later)
I'm getting the following error:
getaddrinfo ENOTFOUND localhost'; localhost';:3306
The process.env.MYSQL_DB variable is just the name of my database.
It all worked when i was using the "short way" to connect:
var sequelize = new Sequelize(process.env.MYSQL_DB , "root", "", {
dialect:'mysql',
logging: false
});
Can someone tell me what might be wrong with my setup?
EDIT: if anybody is interested, the problem was that i put a semicolon after the variable deceleration in my .env file.......
I'm using Symfony 4 to interface with an existing Master/Slave MySQL setup and am executing queries against the server using raw sql. Raw SQL is the only option at the moment.
I'm using show full processlist; on the DB server to monitor which DB is used, and I am only seeing connections to the master server. It doesn't appear that any of the slaves are ever used.
For reference, I have two dbal connections setup, the default is NOT master/slave, and uses orm mapping. The second is the master/slave which I'm having issues with, and this is the server I'm executing raw sql queries against.
Below is my doctrine.yml:
doctrine:
dbal:
default_connection: default
connections:
default:
driver: pdo_mysql
host: "%env(DATABASE_HOST)%"
dbname: "db1"
user: "%env(DATABASE_USER)%"
password: "%env(DATABASE_PASS)%"
charset: UTF8
ds:
driver: pdo_mysql
host: "%env(DS_DATABASE_HOST)%"
dbname: "db2"
user: "%env(DS_DATABASE_USER)%"
password: "%env(DS_DATABASE_PASS)%"
slaves:
slave1:
host: "%env(DS_DATABASE_SLAVE1_HOST)%"
user: "%env(DS_DATABASE_USER)%"
password: "%env(DS_DATABASE_PASS)%"
dbname: "db2"
slave2:
host: "%env(DS_DATABASE_SLAVE2_HOST)%"
user: "%env(DS_DATABASE_USER)%"
password: "%env(DS_DATABASE_PASS)%"
dbname: "db2"
orm:
default_entity_manager: default
entity_managers:
default:
connection: default
mappings:
Main:
is_bundle: false
type: annotation
dir: '%kernel.project_dir%/src/Entity/Main'
prefix: 'App\Entity\Main'
alias: Main
ds:
connection: ds
I have configured my entity managers in my services.yml as follows:
# Entity managers
App\Service\Database\MainEntityManager:
arguments:
$wrapped: '#doctrine.orm.default_entity_manager'
App\Service\Database\DSEntityManager:
arguments:
$wrapped: '#doctrine.orm.ds_entity_manager'
The entity manager (in this case DSEntityManager) is injected into the constructor of a class, then the query is executed as such:
$result = $this->em->getConnection()->prepare($sql);
$result->execute($args);
Please let me know if I'm missing any helpful configuration.
Thanks a lot for the help.
Thanks #Cerad for the tip, that got me in the correct direction. Since I was no longer trying to use an entity manager for raw queries that were not mapped to entities, I could work with the connection directly.
I Created a wrapper class which extended MasterSlaveConnection. That worked as long as I was using executeQuery(). Per the docs, that must be used to query the slaves. However, my query required the use of prepare() and query() which both force the master connection.
So inside my new wrapper class I created two new methods, prepareSlave() and querySlave() which do the same as the original; however, they do $this->connect('slave'); instead of $this->connect('master');
Now all my read queries hit slave and everything else hits master.
So here are the following updates I've made to the configuration above to achieve this:
doctrine.yml
ds:
driver: pdo_mysql
host: "%env(DS_DATABASE_HOST)%"
dbname: "db2"
user: "%env(DS_DATABASE_USER)%"
password: "%env(DS_DATABASE_PASS)%"
wrapper_class: "%env(DS_DATABASE_PASS)%"
slaves: App\Service\Database\DSWrapper
slave1: ...
services.yml
# DBAL connections
App\Service\Database\DSWrapper: '#doctrine.dbal.ds_connection'
My new wrapper class
class DSWrapper extends MasterSlaveConnection
{
public function prepareSlave($statement)
{
$this->connect('slave');
try {
$stmt = new Statement($statement, $this);
} catch (\Exception $ex) {
throw DBALException::driverExceptionDuringQuery($this->_driver, $ex, $statement);
}
$stmt->setFetchMode($this->defaultFetchMode);
return $stmt;
}
public function querySlave()
{
$this->connect('slave');
$args = func_get_args();
$logger = $this->getConfiguration()->getSQLLogger();
if ($logger) {
$logger->startQuery($args[0]);
}
$statement = $this->_conn->query(...$args);
if ($logger) {
$logger->stopQuery();
}
return $statement;
}
}
So now if I need to execute a query which would normally require the use of prepare() and query(), I instead use prepareSlave() and querySlave().
How to use mysql with Sails ? Also, if I change the database to a mySQL one, do I lose all my current model data ?
I spent some time looking for tutorials and demos but haven't found any.
In order to use mySQL with sails, you will have to:
Define an adapter in config/adapters
Example adapters file:
module.exports.adapters = {
'default': 'disk',
disk: {
module: 'sails-disk'
},
'mysql-adapter': {
module: 'sails-mysql',
host: 'HOST',
user: 'USER',
password: 'PASSWORD',
database: 'DATABASE'
}
};
Make any model use the new mysql adapter (ex. api/models/Contact.js)
module.exports = {
tableName: 'contacts',
adapter: 'mysql-adapter',
migrate: 'safe',
attributes: { ... }
}
Then it should work.