-
我有两个SQL查询,我正试图将它们转换为这些查询的sequelize表示
我要转换为sequelize版本的第一个SQL查询
SELECT
user_id,
a.account_id,
email,
email_verified,
user_id IN (
SELECT
user_id
FROM
user_roles
WHERE
role_id IN (
SELECT
role_id
FROM
roles
WHERE
role_name = 'admin'
)
) AS is_admin,
username,
picture_url,
social_account_id,
created_at,
updated_at
FROM
accounts a
LEFT JOIN user_accounts ua ON a.account_id = ua.account_id
WHERE
a.account_id = $1
第一个查询:续集版本
function getByPk(accountId) {
const subquery = `
SELECT
user_id
FROM
user_roles
WHERE
role_id IN (
SELECT
role_id
FROM
roles
WHERE
role_name = 'admin'
)
`;
return Account.findByPk(accountId, {
attributes: {
exclude: ['password'],
include: [
[sequelize.literal(`"Users".user_id IN (${subquery})`), 'isAdmin']
]
},
include: [{
model: User,
attributes: ['userId', 'enabled'],
through: {
attributes: []
}
}]
});
}
上面的sequelize版本在执行时运行良好,并生成以下SQL查询
第一个查询生成以下SQL
SELECT
"Account"."account_id" AS "accountId",
"Account"."email",
"Account"."email_verified" AS "emailVerified",
"Account"."is_primary" AS "isPrimary",
"Account"."username",
"Account"."picture_url" AS "pictureUrl",
"Account"."social_account_id" AS "socialAccountId",
"Account"."created_at" AS "createdAt",
"Account"."updated_at" AS "updatedAt",
"Account"."authentication_type_id" AS "authenticationTypeId",
"Users".user_id IN (
SELECT
user_id
FROM
user_roles
WHERE
role_id IN (
SELECT
role_id
FROM
roles
WHERE
role_name = 'admin'
)
) AS "isAdmin",
"Users"."user_id" AS "Users.userId",
"Users"."enabled" AS "Users.enabled"
FROM
"accounts" AS "Account"
LEFT OUTER JOIN (
"user_accounts" AS "Users->UserAccount"
INNER JOIN "users" AS "Users" ON "Users"."user_id" = "Users->UserAccount"."user_id"
) ON "Account"."account_id" = "Users->UserAccount"."account_id"
WHERE
"Account"."account_id" = 1
我的第二个原始SQL查询使用findOne而不是findByPk,如下所示
SELECT
user_id,
a.account_id,
email,
email_verified,
user_id IN (
SELECT
user_id
FROM
user_roles
WHERE
role_id IN (
SELECT
role_id
FROM
roles
WHERE
role_name = 'admin'
)
) AS is_admin,
nickname,
picture_url,
social_account_id,
created_at,
updated_at
FROM
accounts a
LEFT JOIN user_accounts ua ON a.account_id = ua.account_id
WHERE
authentication_type_id = (
SELECT
authentication_type_id
FROM
authentication_types
WHERE
authentication_type_name = $1
)
AND email = $2
现在,我的sequelize版本的查询抛出了一个错误,如下所示
第二个SQL查询:sequelize版本
(各方面与第一个相同)
function getByEmail(email) {
const subquery = `
SELECT
user_id
FROM
user_roles
WHERE
role_id IN (
SELECT
role_id
FROM
roles
WHERE
role_name = 'admin'
)
`;
return Account.findOne({
attributes: {
exclude: ['password'],
include: [
[sequelize.literal(`"Users".user_id IN (${subquery})`), 'isAdmin']
]
},
include: [{
model: User,
attributes: ['userId', 'enabled'],
through: {
attributes: []
}
}],
where: {
email
}
});
}
当我执行上述函数时,它抛出以下错误
Error
at Query.run (/Users/vivekramesh/Desktop/code/imagineapp4/node_modules/sequelize/dist/lib/dialects/postgres/query.js:50:25)
at /Users/vivekramesh/Desktop/code/imagineapp4/node_modules/sequelize/dist/lib/sequelize.js:313:28
at processTicksAndRejections (internal/process/task_queues.js:95:5)
at async PostgresQueryInterface.select (/Users/vivekramesh/Desktop/code/imagineapp4/node_modules/sequelize/dist/lib/dialects/abstract/query-interface.js:396:12)
at async Function.findAll (/Users/vivekramesh/Desktop/code/imagineapp4/node_modules/sequelize/dist/lib/model.js:1102:21)
at async Function.findOne (/Users/vivekramesh/Desktop/code/imagineapp4/node_modules/sequelize/dist/lib/model.js:1196:12) {
name: 'SequelizeDatabaseError',
parent: error: missing FROM-clause entry for table "Users"
at Parser.parseErrorMessage (/Users/vivekramesh/Desktop/code/imagineapp4/node_modules/pg-protocol/dist/parser.js:287:98)
at Parser.handlePacket (/Users/vivekramesh/Desktop/code/imagineapp4/node_modules/pg-protocol/dist/parser.js:126:29)
at Parser.parse (/Users/vivekramesh/Desktop/code/imagineapp4/node_modules/pg-protocol/dist/parser.js:39:38)
at Socket.<anonymous> (/Users/vivekramesh/Desktop/code/imagineapp4/node_modules/pg-protocol/dist/index.js:11:42)
at Socket.emit (events.js:400:28)
at Socket.emit (domain.js:537:15)
at addChunk (internal/streams/readable.js:293:12)
at readableAddChunk (internal/streams/readable.js:267:9)
at Socket.Readable.push (internal/streams/readable.js:206:10)
at TCP.onStreamRead (internal/stream_base_commons.js:188:23) {
length: 117,
severity: 'ERROR',
code: '42P01',
detail: undefined,
hint: undefined,
position: '507',
internalPosition: undefined,
internalQuery: undefined,
where: undefined,
schema: undefined,
table: undefined,
column: undefined,
dataType: undefined,
constraint: undefined,
file: 'parse_relation.c',
line: '3545',
routine: 'errorMissingRTE',
sql: `SELECT "Account".*, "Users"."user_id" AS "Users.userId", "Users"."enabled" AS "Users.enabled" FROM (SELECT "Account"."account_id" AS "accountId", "Account"."email", "Account"."email_verified" AS "emailVerified", "Account"."is_primary" AS "isPrimary", "Account"."username", "Account"."picture_url" AS "pictureUrl", "Account"."social_account_id" AS "socialAccountId", "Account"."created_at" AS "createdAt", "Account"."updated_at" AS "updatedAt", "Account"."authentication_type_id" AS "authenticationTypeId", "Users".user_id IN (SELECT user_id FROM user_roles WHERE role_id IN (SELECT role_id FROM roles WHERE role_name = 'admin')) AS "isAdmin" FROM "accounts" AS "Account" WHERE "Account"."email" = 'vivek.9891@gmail.com' LIMIT 1) AS "Account" LEFT OUTER JOIN ( "user_accounts" AS "Users->UserAccount" INNER JOIN "users" AS "Users" ON "Users"."user_id" = "Users->UserAccount"."user_id") ON "Account"."accountId" = "Users->UserAccount"."account_id";`,
parameters: undefined
},
original: error: missing FROM-clause entry for table "Users"
at Parser.parseErrorMessage (/Users/vivekramesh/Desktop/code/imagineapp4/node_modules/pg-protocol/dist/parser.js:287:98)
at Parser.handlePacket (/Users/vivekramesh/Desktop/code/imagineapp4/node_modules/pg-protocol/dist/parser.js:126:29)
at Parser.parse (/Users/vivekramesh/Desktop/code/imagineapp4/node_modules/pg-protocol/dist/parser.js:39:38)
at Socket.<anonymous> (/Users/vivekramesh/Desktop/code/imagineapp4/node_modules/pg-protocol/dist/index.js:11:42)
at Socket.emit (events.js:400:28)
at Socket.emit (domain.js:537:15)
at addChunk (internal/streams/readable.js:293:12)
at readableAddChunk (internal/streams/readable.js:267:9)
at Socket.Readable.push (internal/streams/readable.js:206:10)
at TCP.onStreamRead (internal/stream_base_commons.js:188:23) {
length: 117,
severity: 'ERROR',
code: '42P01',
detail: undefined,
hint: undefined,
position: '507',
internalPosition: undefined,
internalQuery: undefined,
where: undefined,
schema: undefined,
table: undefined,
column: undefined,
dataType: undefined,
constraint: undefined,
file: 'parse_relation.c',
line: '3545',
routine: 'errorMissingRTE',
sql: `SELECT "Account".*, "Users"."user_id" AS "Users.userId", "Users"."enabled" AS "Users.enabled" FROM (SELECT "Account"."account_id" AS "accountId", "Account"."email", "Account"."email_verified" AS "emailVerified", "Account"."is_primary" AS "isPrimary", "Account"."username", "Account"."picture_url" AS "pictureUrl", "Account"."social_account_id" AS "socialAccountId", "Account"."created_at" AS "createdAt", "Account"."updated_at" AS "updatedAt", "Account"."authentication_type_id" AS "authenticationTypeId", "Users".user_id IN (SELECT user_id FROM user_roles WHERE role_id IN (SELECT role_id FROM roles WHERE role_name = 'admin')) AS "isAdmin" FROM "accounts" AS "Account" WHERE "Account"."email" = 'vivek.9891@gmail.com' LIMIT 1) AS "Account" LEFT OUTER JOIN ( "user_accounts" AS "Users->UserAccount" INNER JOIN "users" AS "Users" ON "Users"."user_id" = "Users->UserAccount"."user_id") ON "Account"."accountId" = "Users->UserAccount"."account_id";`,
parameters: undefined
},
sql: `SELECT "Account".*, "Users"."user_id" AS "Users.userId", "Users"."enabled" AS "Users.enabled" FROM (SELECT "Account"."account_id" AS "accountId", "Account"."email", "Account"."email_verified" AS "emailVerified", "Account"."is_primary" AS "isPrimary", "Account"."username", "Account"."picture_url" AS "pictureUrl", "Account"."social_account_id" AS "socialAccountId", "Account"."created_at" AS "createdAt", "Account"."updated_at" AS "updatedAt", "Account"."authentication_type_id" AS "authenticationTypeId", "Users".user_id IN (SELECT user_id FROM user_roles WHERE role_id IN (SELECT role_id FROM roles WHERE role_name = 'admin')) AS "isAdmin" FROM "accounts" AS "Account" WHERE "Account"."email" = 'vivek.9891@gmail.com' LIMIT 1) AS "Account" LEFT OUTER JOIN ( "user_accounts" AS "Users->UserAccount" INNER JOIN "users" AS "Users" ON "Users"."user_id" = "Users->UserAccount"."user_id") ON "Account"."accountId" = "Users->UserAccount"."account_id";`,
parameters: {}
}
进一步检查,sequelize似乎没有正确生成此查询,下面是从第二个查询生成的原始SQL的样子
SELECT
"Account".*,
"Users"."user_id" AS "Users.userId",
"Users"."enabled" AS "Users.enabled"
FROM
(
SELECT
"Account"."account_id" AS "accountId",
"Account"."email",
"Account"."email_verified" AS "emailVerified",
"Account"."is_primary" AS "isPrimary",
"Account"."username",
"Account"."picture_url" AS "pictureUrl",
"Account"."social_account_id" AS "socialAccountId",
"Account"."created_at" AS "createdAt",
"Account"."updated_at" AS "updatedAt",
"Account"."authentication_type_id" AS "authenticationTypeId",
"Users".user_id IN (
SELECT
user_id
FROM
user_roles
WHERE
role_id IN (
SELECT
role_id
FROM
roles
WHERE
role_name = 'admin'
)
) AS "isAdmin"
FROM
"accounts" AS "Account"
WHERE
"Account"."email" = 'vivek.9891@gmail.com'
LIMIT
1
) AS "Account"
LEFT OUTER JOIN (
"user_accounts" AS "Users->UserAccount"
INNER JOIN "users" AS "Users" ON "Users"."user_id" = "Users->UserAccount"."user_id"
) ON "Account"."accountId" = "Users->UserAccount"."account_id
有人能告诉我为什么生成的版本在这两个方面有很大的不同,以及如何运行第二个版本?
User has a belongsToMany with Account through UserAccount
Account has a belongsToMany with User through UserAccount