Node Sql Template Strings

ES6 tagged template strings for prepared SQL statements 📋
Alternatives To Node Sql Template Strings
Project NameStarsDownloadsRepos Using ThisPackages Using ThisMost Recent CommitTotal ReleasesLatest ReleaseOpen IssuesLicenseLanguage
Metabase34,132
4 hours ago1June 08, 20223,268otherClojure
The simplest, fastest way to get business intelligence and analytics to everyone in your company :yum:
Dbeaver33,826
4 hours ago1,784apache-2.0Java
Free universal database tool and SQL client
Redash23,863320 hours ago2May 05, 2020586bsd-2-clausePython
Make Your Company Data Driven. Connect to any data source, easily visualize, dashboard and share your data.
Directus23,2001854 hours ago86July 25, 2023274otherTypeScript
The Modern Data Stack 🐰 — Directus is an instant REST+GraphQL API and intuitive no-code data collaboration app for any SQL database.
Postgrest21,121
411 hours ago37July 12, 2022213mitHaskell
REST API for any Postgres database
Shardingsphere18,80374 hours ago7June 04, 20201,191apache-2.0Java
Distributed SQL transaction & query engine for data sharding, scaling, encryption, and more - on any database.
Knex18,00718,0963,3493 days ago255July 12, 2023870mitJavaScript
A query builder for PostgreSQL, MySQL, CockroachDB, SQL Server, SQLite3 and Oracle, designed to be flexible, portable, and fun to use.
Cube16,214784 hours ago31May 02, 2023879otherRust
📊 Cube — The Semantic Layer for Building Data Applications
Apijson15,892
2 days ago224otherJava
🏆 零代码、全功能、强安全 ORM 库 🚀 后端接口和文档零代码,前端(客户端) 定制返回 JSON 的数据和结构。 🏆 A JSON Transmission Protocol and an ORM Library 🚀 provides APIs and Docs without writing any code.
Timescaledb15,517
7 hours ago602otherC
An open-source time-series SQL database optimized for fast ingest and complex queries. Packaged as a PostgreSQL extension.
Alternatives To Node Sql Template Strings
Select To Compare


Alternative Project Comparisons
Readme

SQL Template Strings

npm downloads build codecov dependencies node license chat: on gitter code style: prettier semantic-release

API Documentation

A simple yet powerful module to allow you to use ES6 tagged template strings for prepared/escaped statements.
Works with mysql, mysql2, postgres and sequelize.

Example for escaping queries (callbacks omitted):

const SQL = require('sql-template-strings')

const book = 'harry potter'
const author = 'J. K. Rowling'

// mysql:
mysql.query('SELECT author FROM books WHERE name = ? AND author = ?', [book, author])
// is equivalent to
mysql.query(SQL`SELECT author FROM books WHERE name = ${book} AND author = ${author}`)

// postgres:
pg.query('SELECT author FROM books WHERE name = $1 AND author = $2', [book, author])
// is equivalent to
pg.query(SQL`SELECT author FROM books WHERE name = ${book} AND author = ${author}`)

// sequelize:
sequelize.query('SELECT author FROM books WHERE name = ? AND author = ?', {replacements: [book, author]})
// is equivalent to
sequelize.query(SQL`SELECT author FROM books WHERE name = ${book} AND author = ${author}`)

This might not seem like a big deal, but when you do an INSERT with a lot columns writing all the placeholders becomes a nightmare:

db.query(
  'INSERT INTO books (name, author, isbn, category, recommended_age, pages, price) VALUES (?, ?, ?, ?, ?, ?, ?)',
  [name, author, isbn, category, recommendedAge, pages, price]
)
// is better written as
db.query(SQL`
  INSERT
  INTO    books
          (name, author, isbn, category, recommended_age, pages, price)
  VALUES  (${name}, ${author}, ${isbn}, ${category}, ${recommendedAge}, ${pages}, ${price})
`)

Also template strings support line breaks, while normal strings do not.

How it works

The SQL template string tag transforms the template string and returns an object that is understood by both mysql and postgres:

const query = SQL`SELECT author FROM books WHERE name = ${book} AND author = ${author}`
typeof query // => 'object'
query.text   // => 'SELECT author FROM books WHERE name = $1 AND author = $2'
query.sql    // => 'SELECT author FROM books WHERE name = ? AND author = ?'
query.values // => ['harry potter', 'J. K. Rowling']

Building complex queries with append()

It is also possible to build queries by appending another query or a string with the append() method (returns this for chaining):

query.append(SQL`AND genre = ${genre}`).append(' ORDER BY rating')
query.text   // => 'SELECT author FROM books WHERE name = $1 AND author = $2 AND genre = $3 ORDER BY rating'
query.sql    // => 'SELECT author FROM books WHERE name = ? AND author = ? AND genre = ? ORDER BY rating'
query.values // => ['harry potter', 'J. K. Rowling', 'Fantasy'] ORDER BY rating

This allows you to build complex queries without having to care about the placeholder index or the values array:

const query = SQL`SELECT * FROM books`
if (params.name) {
  query.append(SQL` WHERE name = ${params.name}`)
}
query.append(SQL` LIMIT 10 OFFSET ${params.offset || 0}`)

Raw values

Some values cannot be replaced by placeholders in prepared statements, like table names. append() replaces the SQL.raw() syntax from version 1, just pass a string and it will get appended raw.

Please note that when inserting raw values, you are responsible for quoting and escaping these values with proper escaping functions first if they come from user input (E.g. mysql.escapeId() and pg.escapeIdentifier()). Also, executing many prepared statements with changing raw values in a loop will quickly overflow the prepared statement buffer (and destroy their performance benefit), so be careful.

const table = 'books'
const order = 'DESC'
const column = 'author'

db.query(SQL`SELECT * FROM "`.append(table).append(SQL`" WHERE author = ${author} ORDER BY ${column} `).append(order))

// escape user input manually
mysql.query(SQL`SELECT * FROM `.append(mysql.escapeId(someUserInput)).append(SQL` WHERE name = ${book} ORDER BY ${column} `).append(order))
pg.query(SQL`SELECT * FROM `.append(pg.escapeIdentifier(someUserInput)).append(SQL` WHERE name = ${book} ORDER BY ${column} `).append(order))

Binding Arrays

To bind the array dynamically as a parameter use ANY (PostgreSQL only):

const authors = ['J. K. Rowling', 'J. R. R. Tolkien']
const query = SQL`SELECT name FROM books WHERE author = ANY(${authors})`
query.text   // => 'SELECT name FROM books WHERE author = ANY($1)'
query.values // => ['J. K. Rowling', 'J. R. R. Tolkien']

Named Prepared Statements in Postgres

Postgres has the option of naming prepared statements, which allows parsing and other work to be reused (and requires the SQL associated with the name to stay the same, with only the parameters changing). You can set the name with the setName() method:

// old way
pg.query({name: 'my_query', text: 'SELECT author FROM books WHERE name = $1', values: [book]})

// with template strings
pg.query(SQL`SELECT author FROM books WHERE name = ${book}`.setName('my_query'))

You can also set the name property on the statement object directly or use Object.assign().

Bound Statements in sequelize

By default, Sequelize will escape replacements on the client. To switch to using a bound statement in Sequelize, call useBind(). The boolean parameter defaults to true. Like all methods, returns this for chaining. Please note that as long as the bound mode is active, the statement object only supports Sequelize, not the other drivers.

// old way
sequelize.query('SELECT author FROM books WHERE name = ? AND author = ?', {bind: [book, author]})

// with template strings
sequelize.query(SQL`SELECT author FROM books WHERE name = ${book}`.useBind(true))
sequelize.query(SQL`SELECT author FROM books WHERE name = ${book}`.useBind()) // the same

// works with append (you can call useBind at any time)
const query = SQL`SELECT * FROM books`.useBind(true)
if (params.name) {
  query.append(SQL` WHERE name = ${params.name}`)
}
query.append(SQL` LIMIT 10 OFFSET ${params.offset || 0}`)

Editor Integration

Contributing

  • Tests are written using mocha
  • You can use npm test to run the tests and check coding style
  • Since this module is only compatible with ES6 versions of node anyway, use all the ES6 goodies
  • Pull requests are welcome :)
Popular Sql Projects
Popular Postgresql Projects
Popular Data Processing Categories

Get A Weekly Email With Trending Projects For These Categories
No Spam. Unsubscribe easily at any time.
Javascript
Postgres
Sql
Sequelize