-
-
Notifications
You must be signed in to change notification settings - Fork 4.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Sequelize adds id(PK) of main table in findAll with 'group' and currupts a query with it in posgre. #7534
Comments
As for Mysql - it ignores primary key id in first query and returns expected result. But that not postgre.. |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If this is still an issue, just leave a comment 🙂 |
bump |
I have the same issue with mysql (ONLY_FULL_GROUP_BY enabled), the query is showing gratitude.id even I dont have it in the attributes array.
Error
Thanks |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If this is still an issue, just leave a comment 🙂 |
Using: Sequelize 4.5.0 and Mysql 5.7.19 Exactly this happened to me . As @rusekr mentioned, it can be ignored in MySQL through doing something like below (but not a good practice): Wonder why sequelize adds the PK. Following docs , it says about
Then for
Then for
That means that the only options for selecting the right columns on my query is to use Doesn't make sense to add the PK whenever you join models or doing that without having a way to exclude it. |
Adding |
@anilkonsal Thanks for the tip! But "raw" heavely changes parse result logic though. |
update: adding raw :true not solved problem in 3.30.2 |
update: adding raw :true not solved problem in 4.19.0 |
bug still present in 4.27.0.. |
Any updates on this issue? @rusekr I tried this query: await Coupon.all({
subQuery: false,
attributes: ['tag'],
include: [
{
association: 'coupon_histories',
},
],
group: 'tag',
}); I was expecting something like this: SELECT
`coupon`.`tag`,
COUNT(`coupon_histories`.`coupon_id`)
FROM
`coupons` AS `coupon`
LEFT OUTER JOIN
`coupon_histories` AS `coupon_histories` ON `coupon`.`id` = `coupon_histories`.`coupon_id`
GROUP BY `coupon`.`tag` Yet Sequelize is resulting this query: SELECT
`coupon`.`id`,
`coupon`.`tag`,
`coupon_histories`.`id` AS `coupon_histories.id`,
`coupon_histories`.`user_id` AS `coupon_histories.user_id`,
`coupon_histories`.`coupon_id` AS `coupon_histories.coupon_id`,
`coupon_histories`.`order_id` AS `coupon_histories.order_id`
FROM
`coupons` AS `coupon`
LEFT OUTER JOIN
`coupon_histories` AS `coupon_histories` ON `coupon`.`id` = `coupon_histories`.`coupon_id`
GROUP BY `tag`; |
It still adding ID. And no response from maintainers. |
This should get some attention, it is a persistent and deal-breaking problem. |
It breaks aggregation |
for now I resorted to raw queries. made me add another deps like sql-bricks, dotties to make the sql queries bit more customizable and manageable. it's working quite well, but i'd still rather have this issue fixed though to have uniform and simple data fetching method across my system. |
if you are using Products.findAll({
attributes: [
[sequelize.fn('MAX', sequelize.col('vendor.id'), 'id'],
[sequelize.fn('MAX', sequelize.col('vendor.name'), 'name'],
[sequelize.fn('MAX', sequelize.col('vendor.description'), 'description']
],
where: { type: 'service' },
include: [{
model: Vendors,
as: 'vendor',
attributes: [],
required: true,
where: { approved: true }
}],
group: ['vendor.id']
}) I know that it looks horrible, but it works |
Still stuck on this issue, anyone looking? |
Generally, there are two solutions:
or, editing
I recommend the first solution(revising the queries), but solution 2 may be fine if you feel confident about the queries. |
Hi, any updates on this issue? |
If #3142 is fixed, would this issue be fixed too? |
Can`t test now but saw #3142 and it not fixes fact when model has PK and PK automatically added to any query with 'group' property which errores in postgres. I will rename issue to reflect this. This by seeing the code might fix current issue: #11283 |
Waiting for response from #11283 |
If you add an attribute named '
Here, concat is used to generate an id for each Product/Vendor association. |
This is still an issue with MSSQL. await Incident.findAll({
attributes: ['incidentHandler.name', [models.sequelize.fn('count', '*'), 'count']],
include: [
{
model: User,
attributes: [],
as: 'incidentHandler',
required: true
}
],
limit: 7,
order: models.sequelize.literal('count desc'),
group: ['incidentHandler.name'],
raw: true
}) generates SELECT [incidentHandler].[name], count(N'*') AS [count] FROM [dbo].[Incident] AS [Incident] INNER JOIN [dbo].[Users] AS [incidentHandler] ON [Incident].[IncidentHandler] = [incidentHandler].[Id] GROUP BY [incidentHandler].[name] ORDER BY count desc ORDER BY [Incident].[Id] OFFSET 0 ROWS FETCH NEXT 7 ROWS ONLY; we need to get rid of the automatically added Unfortunately, I ended up using raw query: const topHandlers = await models.sequelize.query(
'SELECT IncidentHandler.name AS name, count(*) AS count ' +
'FROM Incident AS Incident ' +
'INNER JOIN Users AS IncidentHandler ON Incident.IncidentHandler = IncidentHandler.Id ' +
'GROUP BY name ' +
'ORDER BY count desc ' +
'OFFSET 0 ROWS FETCH NEXT 7 ROWS ONLY;',
{ type: Sequelize.QueryTypes.SELECT }
) |
This issue still exists for me, but for nested includes.
This works perfectly fine until the first include but breaks at the second nested include. It includes the ID of Model3 in the select query Here's the generated query -
As you can see, the model3's id is also being added into the select query even though I haven't specified it in I will be resorting to raw queries for now. I am willing to help you resolve this issue by making a PR if any of you can guide me on where to get started. |
I have the same issue in mysql, with sequelize@5.22.3 |
I have the same issue in mysql |
Got the same issue in PostgreSQL using sequelize version 6.6.2 |
This is still an issue for me in Sequelize v6.3.5 with MSSQL. I wonder if this will ever get fixed... |
Workaround is to declare reverse relation from Vendors to Products of type HasMany (it will be using existing foreign key from direct relation) and write something like (vendors centric):
Thinking now it's best way to group by/distinct entity by entity-centric query. Just don't hesitate to declare reverse relation. |
still an issue sequelize 6.12.5 |
It seems like pk is used internally for critical parts of making objects from tables data after select. Workaround: #7534 (comment) |
still an issue on sequelize 6.21.4 please some one help us |
Amazing that this issue has not been fixed for 6 years, doesn't it affect anyone who wants to use group and include in findAll? const { QueryInterface } = require('sequelize/lib/dialects/abstract/query-interface.js');
const QueryTypes = require('sequelize/lib//query-types');
QueryInterface.prototype.select = async function(model, tableName, optionsArg) {
const options = { ...optionsArg, type: QueryTypes.SELECT, model };
let query = this.queryGenerator.selectQuery(tableName, options, model);
if(tableName=='Products' && options.group?.length && options.include?.length)
query = query.replace(', "Products"."id"','');
return await this.sequelize.query( query, options );
} |
It's still an issue for today and affects literally any query that uses |
I'm facing the same issue. Any updates? |
Here's another example of this issue, for which the workaround mentioned in this thread does not help: Post.findAll({
attributes: [
[sequelize.literal(`COALESCE(SUM("Post"."characterCount"), 0)`), 'totalCharacters'],
[sequelize.literal(`COUNT(DISTINCT "Post"."userId")`), 'userCount'],
],
include: [
{association: 'user', attributes: []},
],
where: {
'$user.role$': {[Op.or]: [{[Op.not]: 'admin'}, null]},
},
}); Generated SQL: SELECT
"Post"."id",
COALESCE(SUM("Post"."characterCount"), 0) AS "totalCharacters",
COUNT(DISTINCT "Post"."userId") AS "userCount"
FROM
"Posts" AS "Post"
LEFT OUTER JOIN "Users" AS "user" ON "Post"."userId" = "user"."id"
WHERE
"user"."role" != 'admin' OR "user"."role" IS NULL; As you can see, that Previously, I simply needed: Post.findAll({
attributes: [
[sequelize.literal(`COALESCE(SUM("Post"."characterCount"), 0)`), 'totalCharacters'],
[sequelize.literal(`COUNT(DISTINCT "Post"."userId")`), 'userCount'],
],
}); which worked fine...but then of course additional conditions were eventually needed. I've posted this to StackOverflow as well. |
Looks like these issues may be related:
Perhaps there are more... I only scanned through the issues a little. |
bump. Still an issue. Sequelize v6.32.1 w/ MySQL 8.0.33. |
Any news on this? (6.37.3) PostgreSQL still have the same problem. |
Same issue on: "sequelize": "^6.37.3" In fact, if you try the same aggregation functions on the including model itself, it is no problem. It all comes down the fact, that sequelize adds the primaryKey to the selected cols when include another model. I'm not sure why it does it this way. The only way around i found was to create your models such that you can group them over your primaryKey after including the other model. The real solution to this problem would be to figure out, why sequelize adds the pk col to the selected columns before the group by operation is done AND deleting it after before returning it. Since it only appear when you are including another model, this should have something to do with sequelize needing the pk to "join" the models (ofcourse it needs it) but not removing it after... |
Hello! I have Products model, and Vendors model. With assocation that Vendor has many products and product has one vendorId. I need filter vendors by product properties and/or vendor properties. Using postgre 9.6 and camelcase columns. Sequelize 3.30.2
Therefore object for querying:
Generates incorrect query (with "Products"."id"):
SELECT "Products"."id", "vendor"."id" AS "vendor.id", "vendor"."name" AS "vendor.name", "vendor"."description" AS "vendor.description" FROM "Products" AS "Products" INNER JOIN "Vendors" AS "vendor" ON "Products"."vendorId" = "vendor"."id" AND "vendor"."approved" = true WHERE "Products"."type" = 'service' GROUP BY "vendor"."id";
Query without "Products"."id" works fine and returns vendorId`s filtered by vendor parameters (or/and product parameters):
SELECT "vendor"."id" AS "vendor.id", "vendor"."name" AS "vendor.name", "vendor"."description" AS "vendor.description" FROM "Products" AS "Products" INNER JOIN "Vendors" AS "vendor" ON "Products"."vendorId" = "vendor"."id" AND "vendor"."approved" = true WHERE "Products"."type" = 'service' GROUP BY "vendor"."id";
Is any way to tell Sequelize to not include primary key if I don`t want it in attributes?
Thanks!
upd. workaround #7534 (comment)
The text was updated successfully, but these errors were encountered: