Sequelize原生查询中如何传递不带单引号的字段名?
Hey, I totally get the frustration here—Sequelize's default replacements are meant for values (like user input strings or numbers), not database identifiers such as column names. That's why it's wrapping your locale in single quotes, treating it as a literal string instead of a column reference. Let's go through a few reliable solutions, ordered from most secure to most straightforward:
1. Use Sequelize's Built-in Identifier Quoting (Recommended)
Sequelize has a method to safely quote column names according to your database's dialect (e.g., double quotes for PostgreSQL, backticks for MySQL). This avoids SQL injection risks and ensures compatibility across databases:
// First, safely quote the attribute name const quotedAttribute = sequelize.getQueryInterface().quoteIdentifier(attributes[0]); // Build your query with the quoted identifier const query = `SELECT DISTINCT ${quotedAttribute} FROM "users"`; // Execute the query sequelize.query(query);
Always validate that attributes[0] is a valid column name from your users table before using this—never pass untrusted user input directly here without checking against a whitelist of allowed columns.
2. Use sequelize.literal() for Raw SQL Snippets
If you need more control, literal() lets you insert raw SQL into your query without automatic escaping. Just make sure to wrap the column name in the appropriate quotes for your database:
const query = `SELECT DISTINCT ${sequelize.literal(`"${attributes[0]}"`)} FROM "users"`; sequelize.query(query);
Same note as above: validate the input! If attributes[0] comes from user input, this could expose you to SQL injection attacks. Only use this with trusted, pre-vetted values.
3. Avoid Raw Queries Altogether (ORM Approach)
If possible, use Sequelize's ORM methods instead of raw queries—this is cleaner and safer:
const User = sequelize.model('users'); User.findAll({ attributes: [ [sequelize.fn('DISTINCT', sequelize.col(attributes[0])), attributes[0]] ], raw: true // Returns plain objects instead of model instances }) .then(results => { // Handle your distinct results here });
This approach leverages Sequelize's built-in functions to generate the correct SQL automatically, no manual string building required.
Why Your Original Code Didn't Work
To clarify: replacements are designed for parameter binding, which protects against SQL injection by treating all inputs as literal values. That's why your column name got wrapped in single quotes—it was being treated as a string, not a database identifier.
内容的提问来源于stack exchange,提问作者Yaroslav Prt

