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

Model.count() regression in 3.15.0. Attributes are missing in SQL query #5057

Closed
smolyakoff opened this Issue Dec 16, 2015 · 4 comments

Comments

3 participants
@smolyakoff

smolyakoff commented Dec 16, 2015

This code used to work in v3.14.2

var Sequelize = require('Sequelize');

var connection = new Sequelize("postgres://postgres:admin@localhost:5432/app_db");

var Download = connection.define('download', {
    id: {type: Sequelize.UUID, primaryKey: true},
    type: {type: Sequelize.INTEGER},
    user: {type: Sequelize.UUID},
    createdAt: {
        field: 'created_at',
        type: Sequelize.DATE
    },
    updatedAt: {
        field: 'updated_at',
        type: Sequelize.DATE
    }
}, {
    underscored: true,
    tableName: 'downloads'
});

Download.count({
    attributes: [
        [Sequelize.literal('date_part(\'month\', "created_at" at TIME ZONE INTERVAL \'+03:00\')'), 'd_month']
    ],
    group: ['d_month']
}).then(function(result) {
    console.log(result);
}).done();

The generated SQL output was:

SELECT date_part('month', "created_at" at TIME ZONE INTERVAL '+03:00') AS "d_month", count(*) AS "count" FROM "downloads" AS "download" GROUP BY "d_month";

In 3.15.0 the same code results in error, generated SQL output doesn't include custom attributes

SELECT count(*) AS "count" FROM "downloads" AS "download" GROUP BY "d_month";
@mickhansen

This comment has been minimized.

Contributor

mickhansen commented Dec 16, 2015

A fix for scopes was introduced that removes attributes for count since they mess with it quite a bit: #5020

Your case can be solved more generally by using a simple find:

Download.findOne({
  attributes: [
    [Sequelize.literal('date_part(\'month\', "created_at" at TIME ZONE INTERVAL \'+03:00\')'), 'd_month'],
    [db.fn('COUNT', db.col('id')), 'count']
  ],
  group: ['d_month'],
  raw: true
});
@smolyakoff

This comment has been minimized.

smolyakoff commented Dec 16, 2015

Thanks @mickhansen. I've corrected your example to achieve the same result

Download.findAll({
  attributes: [
    [Sequelize.literal('date_part(\'month\', "created_at" at TIME ZONE INTERVAL \'+03:00\')'), 'd_month'],
    [Sequelize.fn('COUNT', Sequelize.col('id')), 'count']
  ],
  group: ['d_month'],
  raw: true
}).then(function(result) {
    console.log(result);
});

You may still want to adjust API docs for Model.count()

@mickhansen

This comment has been minimized.

Contributor

mickhansen commented Dec 16, 2015

We still need to fix this regression, we'll need to add a check that it only ignores attributes if it comes from a scope.

@mickhansen mickhansen self-assigned this Dec 16, 2015

@ashokfernandez

This comment has been minimized.

Contributor

ashokfernandez commented Dec 20, 2015

I'm having the same issue here. On 3.14.2 this code

db.Follower.count({
    where: {
      userId: userId,
      createdAt: {
        $gte: startDate,
        $lte: endDate
      }
    },
    attributes: ['createdAt'],
    group: [db.sequelize.fn('day', db.sequelize.col('createdAt'))]
  })

Would return

[ { createdAt: Sat Dec 02 2000 00:00:00,
    count: 1 },
  { createdAt: Sun Dec 03 2000 00:00:00,
    count: 2 }]

But in 3.15 it returns this

[ { count: 1 },
  { count: 2 }]

Is there a new way to get the original results with 3.15 or will there be a fix for this coming?

mickhansen added a commit that referenced this issue Jun 13, 2016

Fix #5057, Count no longer include attributes (#6096)
* (test) count() should return attributes

* count use explicit attributes from options

* count with attributes return string
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment