I'm currently trying to connect a Node JS app to a single database that I created using the Azure SQL Database. In order to connect to the database, I use Sequelize. In order to do that, I set up the firewall to accept my IP address as explained here, and I configured a config.json file like so
"username": "SERVER_ADMIN_NAME#MY_IP_ADDRESS",
"password": "ADMIN_PASSWORD",
"database": "DATABASE_NAME",
"host": "SERVER_NAME",
"port": 1433,
"dialect": "mssql",
"dialectOptions": {
"options": {
"encrypt": true
}
}
However, after running the application it fails to connect to the database and returns the following message
"Cannot open server '211' requested by the login. Client with IP address 'MY_IP_ADDRESS' is not allowed to access the server. To enable access, use the Windows Azure Management Portal or run sp_set_firewall_rule on the master database to create a firewall rule for this IP address or address range. It may take up to five minutes for this change to take effect."
I've already waited for more than 5 minutes but the result is still the same. Now, the first thing that came into my mind was how I provided the values for the config.json file. However, after checking the sys.database_firewall_rules using the following query
SELECT * FROM sys.database_firewall_rules;
The table was EMPTY. From here on I'm not really sure what I'm supposed to do. I was wondering if anybody could point out what I was missing? Thanks in advance!
You should not connect to Azure SQL Database using the IP address because it can change any time.
Could you try a connection like below using tedious driver?
var Sql = require('sequelize');
var sql = new Sql('dbname', 'UserName#server', 'password', {
host: 'server.database.windows.net',
dialect: 'mssql',
driver: 'tedious',
options: {
encrypt: true,
database: 'dbname'
},
port: 1433,
pool: {
max: 5,
min: 0,
idle: 10000
}
});
Make sure you are adding your public IP address not your local IP address to the firewall rules. To verify the firewall rules you have added already, please run the following query:
SELECT * FROM sys.firewall_rules;
The above query shows rules at the server level. You have created your rules at that level.
Related
Using DigitalOcean's managed Postgres database cluster and App Platform, I want to connect my NodeJS app to my Postgres database.
At the moment, I'm getting the time out error below. As part of debugging the misconfiguration, I want to verify that I'm using the bindable app environment variables correctly.
Here are some basic details. Using this information, can you help me to understand how to construct the bindable variable?
Database Cluster Name: demo
Database Pool Name: Demo
Example database Name: defaultdb
App Platform > App Name: demo1
I've tried an assortment of combinations as shown below. When I run the echo $MY_VAR command, none of these values are interpolated. I see the bindable variable syntax.
# Test using database cluster name only.
apps#client:~$ echo $TEST1
${demo.HOSTNAME}
# Test using _self, or the current context. I believe this is the app context.
apps#client:~$ echo $TEST2
${_self.HOSTNAME}
# Test using syntax of <db_cluster_name>.<db_pool_name>.<env_var>
apps#client:~$ echo $TEST3
${demo.Demo.HOSTNAME}
# Test using syntax of <app_name>.<db_pool_name>.<env_var>
apps#client:~$ echo $TEST4
${demo1.Demo.HOSTNAME}
Most of these are a bit ridiculous, and at this point, I'm just experimenting with various combinations. Can you please help me to understand the syntax that would output the database hostname when I run echo $DB_HOSTNAME from the Digital Ocean app console? Thank you.
Why am I trying to confirm the bindable variable syntax?
I'd like to use the app environment variables for databases. Because of the connection refused, I believe the issue might be related to the CA certificate not being available as part of the Postgres connection details. Since my syntax isn't resolving, the CA cert isn't available when connecting to Postgres in my code.
The bindable variables should be populated in Node's environment variables and available through process.env.
# Sample postgres configuration
const postgresConfig = {
user: process.env.PG_USER,
password: process.env.PG_PASSWORD,
host: process.env.PG_HOST,
database: process.env.PG_DATABASE,
port: process.env.PG_PORT,
ssl: {
require: true,
rejectUnauthorized: true,
ca: process.env.PG_CA_CERT,
},
};
Error message
When attempting to run a Postgres query, I get this error:
Error: connect ETIMEDOUT 10.x.y.z:25061
at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1278:16) {
errno: -110,
code: 'ETIMEDOUT',
syscall: 'connect',
address: '10.x.y.x',
port: 25061
}
I see how it works now. When you are managing your App Platform application, under the Create menu button is the option to "Create/Attach Database".
I didn't look here because I didn't think I would need to use the "Create" button to attach an existing database. It would be more intuitive to find this feature under the "Actions" menu. I fell victim to some peculiar UI design decisions.
Once the database is attached, all is well in the world.
I'm attempting to connect to a new Aurora PostgreSQL instance with Babelfish enabled.
NOTE: I am able to connect to the instance using the pg library through the normal port 5432 (the Postgres TDAS endpoint).
However, for this test, I am attempting to connect through the Babelfish TDS endpoint (1433) using the standard mssql package.
If I specify a database name (it is correct), I receive the error 'database "postgres" does not exist':
var config = {
server: 'xxx.us-east-1.rds.amazonaws.com',
database: 'postgres',
user: 'xxx',
password: 'xxx'
};
and the connection closes since the connection fails.
if I omit the database property in the config, like:
var config = {
server: 'xxx.us-east-1.rds.amazonaws.com',
user: 'xxx',
password: 'xxx'
};
It will connect. Also, I can use that connection to query basic things like SELECT CURRENT_TIMESTAMP and it works!
However, I can't access any tables.
If I run:
SELECT COUNT(1) FROM PERSON
I receive an error 'relation "person" does not exist'.
If I dot-notate it:
SELECT COUNT(1) FROM postgres.dbo."PERSON"
I receive an error "Cross DB query is not supported".
So, I can't connect to the specific database directly and if I connect without specifying a database, I can't cross-query to the table.
Any one done this yet?
Or, if not, any ideas on helping me figure out what to try next? I'm out of ideas.
Babelfish databases (that you connect to on port 1433) have nothing to do with PostgreSQL databases (port 5432). Essentially, all of Babelfish lives within a single PostgreSQL database (parameter babelfishpg_tsql.database_name).
You seem to have a single-db setup, because Cross DB query is not supported. With such a setup, you can only have a single database via port 1433 (apart from master and tempdb). You have to use CREATE DATABASE to create that single database (if it isn't already created; ask sys.databases).
I can't tell if it is supported to create a table in PostgreSQL (port 5432) and use it on port 1433 (the other way around is fine), but if so, you have to create it in a schema that you created with CREATE SCHEMA while connected on port 1433.
The answer was that I should be connecting to database "master".
Even though there is no database titled master in the instance, you still do connect to it.
Once connected, running the following:
select current_database();
This will indicate you are connected to database "babelfish_db".
I don't know how that works or why a database would have an undocumented alias.
The bigger answer here is that cross-DB object references are not currently supported in Babelfish, outside your current SQL Server database.
This is currently being worked on. Stay tuned.
I've build a nest.js server and now I'm trying to connect mongoDB Atlas.
In the app.module imports i've tried to connect with
mongodb+srv://<user>:<pass>#cluster0.iijhz.mongodb.net/<dbName>?retryWrites=true&w=majority
url string, but failed, now i've tried these options too:
imports: [
MongooseModule.forRoot(
'mongodb+srv://cluster0.iijhz.mongodb.net',
{
user: '<user>',
pass: '<pass>',
dbName: '<dbName>',
w: 'majority',
retryWrites: true
}
),
but still got
MongoError: Authentication failed.
my ip, and 0.0.0.0/0 is also added to whitelist.
Ok, surely my bad, the dbName wasn't correct the whole time.
The problem that I faced was not whitelisting my IP address. The error was not visible when tried with NestJS but while using it with express I found out the error!
In case you're wondering how to change IP address in MongoDB atlas:
Goto MongoDB atlas dashboard
Select Network Access option under Security
In the IP address tab, clik edit on the first(according to your requirement) IP address.
Click Add Current IP address(for only your current IP, you can't access from other IP) / select "Global IP" or 0.0.0.0/0 for getting
access from anywhere.
It should work now!
Hope that helps!
I am trying to connect node.js app to MongoDB having replica set but it's throwing an error when any write operations are performed.
It throws MongoError: not master.
It tries to write on secondary mongo instances.
I have the options as { db: { readPreference: secondaryPreferred } } and passing it to the function MongoClient.connect in the node.js code using native Mongo Driver.
The URL used to connect looks like mongodb://admin:pass#host_one:27017,host_two:27017,host_three:27017/dbName
Any help would be really appreciated.
Did you add in your replicaSet name?
mongodb://admin:pass#host_one:27017,host_two:27017,host_three:27017/dbName?replicaSet=my-replica-set
replicaSet=name
The driver verifies that the name of the replica set it connects to
matches this name. Implies that the hosts given are a seed list, and
the driver will attempt to find all members of the set. No default
value.
If this is not set it will be treated as a standalone node.
Maybe your replica set configuration is not correct.
To check the configuration run the rs.conf() command in your mongo servers. You need to have a mongo host running as primary member.
MongoError: Not master
This error seems like your primary member of replica set is not configured properly.
You can confirm this by entering into mongo shell of the host_one. If mongo shell prompt doesn't show PRIMARY, then it's not configured properly.
Mongo shell prompt of host_two and host_three should show SECONDARY after proper configuration.
Important : Run rs.initiate() on just one and only one mongod instance for the replica set.
You can execute this command on the primary member to make the configuration work properly.
rs.initiate();
cfg = {
_id: 'rs0',
members: [{
_id: 0,
host: 'host_one:27017',
priority: 2
}, {
_id: 1,
host: 'host_two:27017',
priority: 1
}, {
_id: 2,
host: 'host_three:27017',
priority: 1
}]
};
cfg.protocolVersion = 1;
rs.reconfig(cfg, {
force: true
});
Please note that priority value indicates the relative eligibility of a member to become a primary.
Specify higher values to make a member more eligible to become primary, and lower values to make the member less eligible. A member with a priority of 0 is ineligible to become primary.
You can again check your replica set configuration using this command
rs.conf()
Read preference is not applicable to writes. Writes must always be performed on the primary.
You should be connecting to replica set instead of directly to an individual node. See node.js mongodb how to connect to replicaset of mongo servers
I need some clarification about what the pool is and what it does. The docs say Sequelize will setup a connection pool on initialization so you should ideally only ever create one instance per database.
var sequelize = new Sequelize('database', 'username', 'password', {
host: 'localhost',
dialect: 'mysql'|'mariadb'|'sqlite'|'postgres'|'mssql',
pool: {
max: 5,
min: 0,
idle: 10000
},
// SQLite only
storage: 'path/to/database.sqlite'
});
When your application needs to retrieve data from the database, it creates a database connection. Creating this connection involves some overhead of time and machine resources for both your application and the database. Many database libraries and ORM's will try to reuse connections when possible, so that they do not incur the overhead of establishing that DB connection over and over again. The pool is the collection of these saved, reusable connections that, in your case, Sequelize pulls from. Your configuration of
pool: {
max: 5,
min: 0,
idle: 10000
}
reflects that your pool should:
Never have more than five open connections (max: 5)
At a minimum, have zero open connections/maintain no minimum number of connections (min: 0)
Remove a connection from the pool after the connection has been idle (not been used) for 10 seconds (idle: 10000)
tl;dr: Pools are a good thing that help with database and overall application performance, but if you are too aggressive with your pool configuration you may impact that overall performance negatively.
pool is draining error
I found this thread in my search for a Sequalize error was giving my node.js app: pool is draining. I could not for the life of me figure it out. So for those who follow in my footsteps:
The issue was that I was closing the database earlier than I thought I was, with the command sequelize.closeConnections(). For some reason, instead of an error like 'the database has been closed`, it was instead giving the obscure error 'pool is draining'.
Seems that you can try to put pool to false to avoid having the pool bing created. Here is the API details table :http://sequelize.readthedocs.org/en/latest/api/sequelize/
[options.pool={}]
Object
Should sequelize use a connection pool.
Default is true