question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Impossible to group on attributes from (nested) includes

See original GitHub issue

if several tables are included, and have columns of the same name, then those must be referred by the alias. Yet the alias is not available (other than reverse engineering, which can break at the next update of sequelize)

var S = require('sequelize');

var sequelize = new S('seq_test', 'passwd', '', {
    host: 'localhost',
    dialect: 'postgres',
    pool: { max: 15, min: 0, idle: 10000, },
    define: {  },
});

var User = sequelize.define('User', {
    name: { type: S.STRING(50), allowNull: true},
    pass: { type: S.STRING(50), allowNull: true},
});
var Foo = sequelize.define('Foo', {
    login: { type: S.STRING(50), allowNull: true},
    pass: { type: S.STRING(50), allowNull: true},
});
var Bar = sequelize.define('Bar', {
    login: { type: S.STRING(50), allowNull: true},
    pass: { type: S.STRING(50), allowNull: true},
});

User.belongsTo(Foo, {});
Foo.belongsTo(Bar, {});

sequelize.sync()
.then(function (){
    User.findAll({
        raw: true,
        attributes: [ 
            [ S.fn('count', S.literal('*')), 'cnt' ],
            [ S.col('name'), 'username' ] 
        ],
        include: [
            {   model: Foo,
                attributes: [ [ S.col('login'), 'fooname' ] ],
                raw: true, // workaruond issue 4308
                //group: [S.col('barname')],
                include: [
                    {   model: Bar,
                        attributes: [ [ S.col('login'), 'barname' ] ],
                        //group: [S.col('barname')],
                    },
                ],
            },
        ],
        group: [S.col('username'), S.col('fooname'), S.col('barname')],
//        group: [S.col('username'), S.col('login'), S.col('login')],
//        group: [S.col('username')],
    });
});

results in this sql:

SELECT count(*) AS "cnt", 
  "name" AS "username", 
  "Foo"."login" AS "Foo.fooname", 
  "Foo.Bar"."login" AS "Foo.Bar.barname" 
FROM "Users" AS "User" 
LEFT OUTER JOIN "Foos" AS "Foo" ON "User"."FooId" = "Foo"."id" 
LEFT OUTER JOIN "Bars" AS "Foo.Bar" ON "Foo"."BarId" = "Foo.Bar"."id" 
GROUP BY "username", "fooname", "barname";

Unhandled rejection SequelizeDatabaseError: column "fooname" does not exist

Attempting to group by the real name of the column (not alias) is not possible either: Unhandled rejection SequelizeDatabaseError: column reference “login” is ambiguous

And group by inside the include is not accepted neither. Besides it would be no good, as it would loose the ability to specify the order in which the fields appear in the group by clause.


S.col('username')

would need a further argument, to identify the model to which the column belongs. Then it could find the correct prefix, and apply it. In the easiest case it could be

S.col('username', { model: Foo })

However this only works, if Foo is only included once.

The same model may be included more than once (and even with the same “as”, if deeply nested from different parents,

In this cases an alternative way of identifying it would be needed. Maybe (but not sure if acceptable)

 include: [  {   model: Foo, includeId: 'myPersonalId_ForThisInclude'  ] },

S.col('username', { includeId: 'myPersonalId_ForThisInclude'  })

Or alternatively (but IMHO a not such a good idea), instead of generating the table-alias (prefix) “Foo.Bar” (as seen in “Foo.Bar”.“login”), the v could be given by the user (and then would be known and can be used in col().

 include: [  {   model: Foo, tableAlias: 'my_foo_table_alias'  ] },

S.col('my_foo_table_alias.username')

#2134 is about grouping with include too, but does not have the same name issue

Issue Analytics

  • State:closed
  • Created 8 years ago
  • Reactions:5
  • Comments:8 (8 by maintainers)

github_iconTop GitHub Comments

1reaction
matthewheckcommented, Oct 27, 2015

@mickhansen It’s a little more complicated than that, mostly due to the inclusion of defaultScope.

My model includes this scope:

defaultScope: {
    where: {
        deleted: false
    },
    attributes: [ 'id', 'title', 'slug', 'meta' ],
    group: ['id']
}

Without group defined, the findAndCountAll function fails in Postgres with this error: Unhandled rejection SequelizeDatabaseError: column "blam.id" must appear in the GROUP BY clause or be used in an aggregate function

Consequently, I added group: ['id'] to defaultScope, which works fine for any query that does not utilize an include.

Once I add self-referential include, it breaks as I showed above with the ambiguous id. I did try to add blam.id on the group in the defaultScope, but that leads to a new problem with the defaultScope:

Unhandled rejection SequelizeDatabaseError: column "child_blams.id" must appear in the GROUP BY clause or be used in an aggregate function

Because I’m using defaultScope on a self-referential include (that inherently needs to change its reference in INNER JOIN "blams" AS "child_blams" to prevent ambiguity), specificity on the group of the defaultScope becomes an issue.

Apologies – this quickly expanded outside of the scope of the initial issue. Happy to open a new issue if that would be easier.

0reactions
mickhansencommented, Oct 28, 2015

@matthewheck Ah yeah, sounds like group might need to be scoped to the model then.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Sequelize : Only returning one of many result for a nested ...
I tried to do group clause inside include. const jobPosts = await JobPost.unscoped().findAll({ where, include: [ ...
Read more >
Syncing nested group hiearchies to AD - NetIQ Identity Manager
In eDirectory a nested groups attributes are: "Group Membership" for parent relation "groupMember" for child relations.
Read more >
Managing nested groups | Administering Jira applications ...
Some directory servers allow you to define a group as a member of another group. Groups in such a structure are called nested...
Read more >
How to manage groups - Azure Active Directory - Microsoft Entra
Azure AD roles that can manage groups include Groups ... When an attribute of a user or device changes, all dynamic group rules...
Read more >
Active Directory Nested Groups Explained - Imanami
It is also possible to nest users, computers, and domain local groups in global groups through a trusted domain of the same forest....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found