Raw クエリ
生の/すでに準備された SQL クエリを実行する方が簡単なユースケースがよくあるため、sequelize.query
メソッドを使用できます。
デフォルトでは、この関数は 2 つの引数 (結果の配列と、メタデータ (影響を受けた行数など) を含むオブジェクト) を返します。これは raw クエリであるため、メタデータはダイアレクト固有であることに注意してください。一部のダイアレクトは、メタデータを結果オブジェクト内 (配列のプロパティとして) に返します。ただし、常に 2 つの引数が返されますが、MSSQL および MySQL の場合は、同じオブジェクトへの 2 つの参照になります。
const [results, metadata] = await sequelize.query('UPDATE users SET y = 42 WHERE x = 12');
// Results will be an empty array and metadata will contain the number of affected rows.
メタデータにアクセスする必要がない場合は、クエリのタイプを渡して、sequelize に結果の形式を設定する方法を指示できます。たとえば、単純な SELECT クエリの場合、次のように記述できます。
const { QueryTypes } = require('sequelize');
const users = await sequelize.query('SELECT * FROM `users`', {
type: QueryTypes.SELECT,
});
// We didn't need to destructure the result here - the results were returned directly
他にもいくつかのクエリタイプが利用可能です。詳細については、ソースを調べてください。
2 番目のオプションはモデルです。モデルを渡すと、返されるデータはそのモデルのインスタンスになります。
// Callee is the model definition. This allows you to easily map a query to a predefined model
const projects = await sequelize.query('SELECT * FROM projects', {
model: Projects,
mapToModel: true, // pass true here if you have any mapped fields
});
// Each element of `projects` is now an instance of Project
クエリ API リファレンスで詳細オプションを参照してください。いくつかの例を以下に示します。
const { QueryTypes } = require('sequelize');
await sequelize.query('SELECT 1', {
// A function (or false) for logging your queries
// Will get called for every SQL query that gets sent
// to the server.
logging: console.log,
// If plain is true, then sequelize will only return the first
// record of the result set. In case of false it will return all records.
plain: false,
// Set this to true if you don't have a model definition for your query.
raw: false,
// The type of query you are executing. The query type affects how results are formatted before they are passed back.
type: QueryTypes.SELECT,
});
// Note the second argument being null!
// Even if we declared a callee here, the raw: true would
// supersede and return a raw object.
console.log(await sequelize.query('SELECT * FROM projects', { raw: true }));
"ドット付き"属性とnest
オプション
テーブルの属性名にドットが含まれている場合、nest: true
オプションを設定すると、結果のオブジェクトがネストされたオブジェクトになる可能性があります。これは、内部でdottie.jsを使用して実現されます。以下を参照してください
-
nest: true
なしconst { QueryTypes } = require('sequelize');
const records = await sequelize.query('select 1 as `foo.bar.baz`', {
type: QueryTypes.SELECT,
});
console.log(JSON.stringify(records[0], null, 2));{
"foo.bar.baz": 1
} -
nest: true
ありconst { QueryTypes } = require('sequelize');
const records = await sequelize.query('select 1 as `foo.bar.baz`', {
nest: true,
type: QueryTypes.SELECT,
});
console.log(JSON.stringify(records[0], null, 2));{
"foo": {
"bar": {
"baz": 1
}
}
}
置換
クエリの置換は、名前付きパラメーター (:
で始まる) を使用するか、名前のない (?
で表される) のいずれかの 2 つの異なる方法で実行できます。置換は、オプションオブジェクトで渡されます。
- 配列が渡された場合、
?
は配列に現れる順序で置換されます - オブジェクトが渡された場合、
:key
はそのオブジェクトのキーで置換されます。オブジェクトにクエリで見つからないキーが含まれている場合、またはその逆の場合、例外がスローされます。
const { QueryTypes } = require('sequelize');
await sequelize.query('SELECT * FROM projects WHERE status = ?', {
replacements: ['active'],
type: QueryTypes.SELECT,
});
await sequelize.query('SELECT * FROM projects WHERE status = :status', {
replacements: { status: 'active' },
type: QueryTypes.SELECT,
});
配列置換は自動的に処理されます。次のクエリは、ステータスが値の配列と一致するプロジェクトを検索します。
const { QueryTypes } = require('sequelize');
await sequelize.query('SELECT * FROM projects WHERE status IN(:status)', {
replacements: { status: ['active', 'inactive'] },
type: QueryTypes.SELECT,
});
ワイルドカード演算子 %
を使用するには、それを置換に追加します。次のクエリは、名前が 'ben' で始まるユーザーと一致します。
const { QueryTypes } = require('sequelize');
await sequelize.query('SELECT * FROM users WHERE name LIKE :search_name', {
replacements: { search_name: 'ben%' },
type: QueryTypes.SELECT,
});
バインドパラメーター
バインドパラメーターは置換のようなものです。ただし、置換は、クエリがデータベースに送信される前に、sequelize によってエスケープされてクエリに挿入されますが、バインドパラメーターは SQL クエリテキストの外側でデータベースに送信されます。クエリには、バインドパラメーターまたは置換のいずれかを含めることができます。バインドパラメーターは、$1、$2、... (数値) または $key (英数字) のいずれかで参照されます。これはダイアレクトに依存しません。
- 配列が渡された場合、
$1
は配列の最初の要素 (bind[0]
) にバインドされます - オブジェクトが渡された場合、
$key
はobject['key']
にバインドされます。各キーは、数値以外の文字で始める必要があります。object['1']
が存在する場合でも、$1
は有効なキーではありません。 - どちらの場合も、リテラルの
$
記号をエスケープするために$$
を使用できます。
配列またはオブジェクトには、バインドされたすべての値が含まれている必要があります。そうでない場合、Sequelize は例外をスローします。これは、データベースがバインドされたパラメーターを無視する可能性のある場合にも適用されます。
データベースは、これにさらに制限を追加する場合があります。バインドパラメーターは、SQL キーワード、テーブル名、または列名にすることはできません。また、引用符で囲まれたテキストまたはデータでは無視されます。PostgreSQL では、コンテキストから型を推論できない場合、それらを型キャストする必要がある場合もあります $1::varchar
。
const { QueryTypes } = require('sequelize');
await sequelize.query(
'SELECT *, "text with literal $$1 and literal $$status" as t FROM projects WHERE status = $1',
{
bind: ['active'],
type: QueryTypes.SELECT,
},
);
await sequelize.query(
'SELECT *, "text with literal $$1 and literal $$status" as t FROM projects WHERE status = $status',
{
bind: { status: 'active' },
type: QueryTypes.SELECT,
},
);