sails.config.datastores
Datastore configurations (or simply datastores) are like "saved settings" for your adapters.
In Sails, database adapters are the middleman between your app and some kind of structured data storage (typically a database). But in order for an adapter to communicate between your Sails app and a particular database, it needs some additional information. That's where datastores come in. Datastores are dictionaries (plain JavaScript objects) that specify an adapter
, as well as other necessary configuration information, like url
, or host
, port
, user
, and password
.
While this can be overridden on a per-model basis, out of the box, every model in your app uses a datastore named "default".
As a convenience during development, Sails provides a built-in database adapter called sails-disk
. This adapter simulates a real database by reading and writing database records to a JSON file on your computer's hard drive. And while sails-disk
makes it easy to run your Sails/Node.js app in almost any environment with minimal setup, it is not designed for production use. Before deploying your app and exposing it to real users, you'll want to choose a proper database such as PostgreSQL, MySQL, MongoDB, etc. To do that, you'll need to customize your app's default datastore.
Unsurprisingly, the default datastore shared by all of your app's models is named "default". So to hook up a different database, that's the key you'll want to change. For example, imagine you want to develop against a MySQL server installed locally on your laptop:
First, install the MySQL adapter for Sails and Waterline:
npm install sails-mysql --save --save-exact
Then edit your default datastore configuration in config/datastores.js
so that it looks something like this:
// config/datastores.js
module.exports.datastores = {
default: {
adapter: require('sails-mysql'),
url: 'mysql://root:squ1ddy@localhost:3306/my_dev_db_name',
}
};
That's it! The next time you lift your app, all of your models will communicate with the specified MySQL database whenever your code executes built-in model methods like .create()
or .find()
.
Want to use a different database? Don't worry, MySQL is just an example. You can use any supported database adapter in your Sails app.
You might have noticed that we used url
here, instead of specifying individual settings like host
, port
, user
, password
, and database
. This is called a connection URL (or "connection string"), and it's just another, more concise way, to tell Sails and Waterline about your datastore configuration.
One major benefit to this style of configuration is that the format of a connection URL is the same across various types of databases. In other words, whether you're using MySQL, PostgreSQL, MongoDB, or almost any other common database technology, you can specify basic configuration using a URL that looks roughly the same:
protocol://user:password@host:port/database
The protocol://
chunk of the URL is always based on the adapter you're using (mysql://
, mongodb://
, etc.), and the rest of the URL is composed of the credentials and network information that your app needs to locate and connect to the database. Here's a deconstructed version of the url
from the MySQL example above that shows what each section is called:
mysql:// root : squ1ddy @ localhost : 3306 / my_dev_db_name
| | | | | |
| | | | | |
protocol user password host port database
In production, if you are using a cloud-hosted database, you'll probably be given a connection URL (e.g. mysql://lkjdsf4:kw8sd@us-west-2.64-8.amazonaws.com:3306/4e843g
). If not, it's usually a good idea to build one yourself from the individual pieces of information. For more information about how to configure your particular database, check out the database adapter reference.
If you have all of the pieces of information mentioned above, building a connection URL is easy: you just stick them together. But sometimes, you may not want to specify all of those details (if you want to use the default port, or if you're using a local database that does not require a username and password, for example).
Fortunately, since database connection URLs are more or less just normal URLs, you can omit various pieces of information in the same way you might already be familiar with. For example, here are a few common mashups, all of which are potentially valid connection URLs:
protocol://user:password@host:port/databaseName
protocol://user:password@host/databaseName
(no port)protocol://user@host:port/databaseName
(no password)protocol://host:port/databaseName
(neither a username nor a password)Connection URLs are the recommended approach for configuring your Sails app's database(s), so it's best to stick with them if possible. But technically, some adapters also support configuration of individual settings (
user
,password
,host
,port
, anddatabase
) as an alternative. In that scenario, if both theurl
notation and individual settings are used, the non-url configuration options should always take precedence. You should, however, always use one approach or the other: either theurl
or the individual properties. Mixing the two configuration strategies may confuse the adapter, or cause the underlying database driver to reject your configuration.
When configuring your app for a production deployment, you won't actually use the config/datastores.js
file. Instead, you can take advantage of config/env/production.js
, a special file of configuration overrides that only get applied in a production environment. This allows you to override the url
and adapter
(or just the url
) that you set in config/datastores.js
:
// config/env/production.js
module.exports = {
// ...
// Override the default datastore settings in production.
datastores: {
default: {
// No need to set `adapter` again, because we already configured it in `config/datastores.js`.
url: 'mysql://lkjdsf4a23d9xf4:kkwer4l8adsfasd@u23jrsdfsdf0sad.aasdfsdfsafd.us-west-2.ere.amazonaws.com:3306/ke9944a4x23423g',
}
},
// ...
};
Connection URLs really shine in production, because you can change them by swapping out a single config key. Not only does this make your production settings easier to understand, it also allows you to swap out your production database credentials simply by setting an environment variable (sails_datastores__default__url
). This is a handy way to avoid immortalizing sensitive database credentials as commits in your version control system.
Sails's ORM, Waterline, has a well-defined adapter system for supporting all kinds of datastores. The Sails core team maintains official adapters for MySQL, PostgreSQL, MongoDB, and local disk; and community adapters exist for databases like Oracle, DB2, MSSQL, OrientDB, and many more.
You can find an up-to-date list of supported database adapters here.
Still can't find the adapter for your database? You can also create a custom adapter. Or if you'd like to modify/update an existing adapter, get in touch with its maintainer. (Need help? Click here for additional resources.)
You can set up more than one datastore pointed at the same adapter, or at different adapters.
For example, you might be using MySQL as your primary database but also need to integrate with a second MySQL database that contains data from an existing Java or PHP app. Meanwhile, you might need to integrate with a third MongoDB database that was left over from a promotional campaign a few months ago.
You could set up config/datastores.js
as follows:
// config/datastores.js
module.exports.datastores = {
default: {
adapter: require('sails-mysql'),
url: 'mysql://root@localhost:3306/dev',
},
existingEcommerceDb: {
adapter: require('sails-mysql'),
url: 'mysql://djbluegrass:0ldy3ll3r@legacy.example.com:3306/store',
},
q3PromoDb: {
adapter: require('sails-mongo'),
url: 'mongodb://djbluegrass:0ldy3ll3r@seasonal-pet-sweaters-promo.example.com:27017/promotional',
}
};
Note: If a datastore is using a particular adapter, then all datastores that share that adapter will be loaded on
sails lift
, whether or not models are actually using them. In the example above, if a model was defined withdatastore: 'existingEcommerceDb'
, then at runtime Waterline would create two MySQL connection pools: one forexistingEcommerceDb
and one fordefault
. Because of this behavior, we recommend commenting out or removing any "aspirational" datastore configurations that you're not actually using fromconfig/datastores.js
.
Some general rules of thumb:
default
key in config/datastores.js
(or use config/local.js
if you'd rather not check in your credentials).config/env/production.js
(or set environment variables if you'd rather not check in your credentials).datastore
.config/datastores.js
and config/env/production.js
files, you can configure datastores in the same way you configure anything else in Sails, including environment variables, command-line options, and more.