Kaltsoon / sequelize-cursor-pagination

➡️ Cursor-based pagination queries for Sequelize models
86 stars 27 forks source link

UUID PK and order generates unwanted results #24

Closed bartdelange closed 2 years ago

bartdelange commented 5 years ago

Hi,

If my pk is a UUID and I add an order field the returned data is not what is should be (see examples).

I am aware that I could simply override the pk field on model initialisation, but I am using the auto import that comes with sequelize-cli (rewriten in es8 syntax) which makes that almost impossible.

If I can help in any way let me know!

~/database/models/index.js
import path from 'path';
import Sequelize from 'sequelize';
import conf from '~/config/database.json';
import logger from '~/utils/logger';
import withPagination from 'sequelize-cursor-pagination';

const env = process.env.NODE_ENV || 'development';
const config = {
  logging: msg => logger.log('silly', msg),
  retry: {
    max: 10,
  },
  ...conf[env],
};

let sequelize;
if (config.use_env_variable) {
  sequelize = new Sequelize(process.env[config.use_env_variable], config);
} else {
  sequelize = new Sequelize(config.database, config.username, config.password, config);
}

const paginationOptions = {
  methodName: 'paginate',
  primaryKeyField: 'id',
};

const requireModels = require.context('.', true, /\.js$/);
const models = {};
requireModels.keys().forEach((key) => {
  if (key.includes(__filename)) return;

  const extension = path.extname(key);
  const modelName = path.basename(key, extension);
  const model = sequelize.import(modelName, requireModels(key));

  withPagination(paginationOptions)(model);

  models[model.name] = model;
});

Object.keys(models).forEach((modelName) => {
  if (models[modelName].associate) {
    models[modelName].associate(models);
  }
});

export default {
  sequelize,
  Sequelize,
  ...models,
};

Examples

in the example below the 'sonarrId' field is added to the order table. I am using graphql as the data fetcher so thats why the data is restructured (it should however still be clear what is happening)

Results without cursor:

{
  "data": {
    "shows": {
      "pageInfo": {
        "hasPreviousPage": false,
        "hasNextPage": true,
        "startCursor": "WyJiMzM5ZmI1Zi04N2VhLTRlYzgtYWYxYS0xYzk4MmVhNzE4NjEiXQ==",
        "endCursor": "WyIyMjQ2Y2M3ZS1lODFkLTQxNjAtOTEwNi1jZTMwMGRjNWE1OWMiXQ=="
      },
      "edges": [
        {
          "cursor": "WyJiMzM5ZmI1Zi04N2VhLTRlYzgtYWYxYS0xYzk4MmVhNzE4NjEiXQ==",
          "node": {
            "id": "b339fb5f-87ea-4ec8-af1a-1c982ea71861",
            "sonarrId": 1
          }
        },
        {
          "cursor": "WyI0OTdhYjk0OC1kZjUyLTQ3MWUtYTRlZS0xNDQ1NTM2NDVhMTMiXQ==",
          "node": {
            "id": "497ab948-df52-471e-a4ee-144553645a13",
            "sonarrId": 2
          }
        },
        {
          "cursor": "WyI2Njk1ZjE0MC0zODMxLTRiMzYtOTRkNi1kY2QwNWJkMjQ2YTAiXQ==",
          "node": {
            "id": "6695f140-3831-4b36-94d6-dcd05bd246a0",
            "sonarrId": 3
          }
        },
        {
          "cursor": "WyIyMjQ2Y2M3ZS1lODFkLTQxNjAtOTEwNi1jZTMwMGRjNWE1OWMiXQ==",
          "node": {
            "id": "2246cc7e-e81d-4160-9106-ce300dc5a59c",
            "sonarrId": 4
          }
        }
      ]
    }
  }
}

Result with cursor (cursor of element 'sonarrId = 2')

{
  "data": {
    "shows": {
      "pageInfo": {
        "hasPreviousPage": true,
        "hasNextPage": true,
        "startCursor": "WyJiMzM5ZmI1Zi04N2VhLTRlYzgtYWYxYS0xYzk4MmVhNzE4NjEiXQ==",
        "endCursor": "WyJjMDA5NGI1My1kZGE1LTQzYWQtOWRhMS1kN2QzZWY3NTYzMzYiXQ=="
      },
      "edges": [
        {
          "cursor": "WyJiMzM5ZmI1Zi04N2VhLTRlYzgtYWYxYS0xYzk4MmVhNzE4NjEiXQ==",
          "node": {
            "id": "b339fb5f-87ea-4ec8-af1a-1c982ea71861",
            "sonarrId": 1
          }
        },
        {
          "cursor": "WyI2Njk1ZjE0MC0zODMxLTRiMzYtOTRkNi1kY2QwNWJkMjQ2YTAiXQ==",
          "node": {
            "id": "6695f140-3831-4b36-94d6-dcd05bd246a0",
            "sonarrId": 3
          }
        },
        {
          "cursor": "WyI4YzczMzNmNi0yMDdjLTQxYmQtYjczZC0xYmM1ZDM3MmZmMWIiXQ==",
          "node": {
            "id": "8c7333f6-207c-41bd-b73d-1bc5d372ff1b",
            "sonarrId": 5
          }
        },
        {
          "cursor": "WyJjMDA5NGI1My1kZGE1LTQzYWQtOWRhMS1kN2QzZWY3NTYzMzYiXQ==",
          "node": {
            "id": "c0094b53-dda5-43ad-9da1-d7d3ef756336",
            "sonarrId": 6
          }
        }
      ]
    }
  }
}

Expected result

{
  "data": {
    "shows": {
      "pageInfo": {
        "hasPreviousPage": false,
        "hasNextPage": true,
        "startCursor": "WyJiMzM5ZmI1Zi04N2VhLTRlYzgtYWYxYS0xYzk4MmVhNzE4NjEiXQ==",
        "endCursor": "WyJmNmJjYjY5MC1iZjUyLTRiOWItYWRjZi03ZDhiOTdkZmUyZDEiXQ=="
      },
      "edges": [
        {
          "cursor": "WyI2Njk1ZjE0MC0zODMxLTRiMzYtOTRkNi1kY2QwNWJkMjQ2YTAiXQ==",
          "node": {
            "id": "6695f140-3831-4b36-94d6-dcd05bd246a0",
            "sonarrId": 3
          }
        },
        {
          "cursor": "WyIyMjQ2Y2M3ZS1lODFkLTQxNjAtOTEwNi1jZTMwMGRjNWE1OWMiXQ==",
          "node": {
            "id": "2246cc7e-e81d-4160-9106-ce300dc5a59c",
            "sonarrId": 4
          }
        },
        {
          "cursor": "WyI4YzczMzNmNi0yMDdjLTQxYmQtYjczZC0xYmM1ZDM3MmZmMWIiXQ==",
          "node": {
            "id": "8c7333f6-207c-41bd-b73d-1bc5d372ff1b",
            "sonarrId": 5
          }
        },
        {
          "cursor": "WyJjMDA5NGI1My1kZGE1LTQzYWQtOWRhMS1kN2QzZWY3NTYzMzYiXQ==",
          "node": {
            "id": "c0094b53-dda5-43ad-9da1-d7d3ef756336",
            "sonarrId": 6
          }
        }
      ]
    }
  }
}
Kaltsoon commented 2 years ago

Starting from version 2.4.0 you can use omitPrimaryKeyFromOrder option to omit the primary key from the order. Feel free to create a new issue if it doesn't solve your issue.