Skip to content

Error: Cannot find module 'pg-native' #3781

Closed

Description

@tornillo

Exception occurs when trying to add two (or more) equal values in a unique field using findOrCreate.

Test code:

var arr = [0, 1];

var User = sequelize.define('User', {
    login: {
        type: Sequelize.STRING,
        unique: true
    }
});

User.sync({ force: true })
.then(function () {
    sequelize.transaction()
    .then(function (tx) {
        return Promise.map(arr, function () {
            return User.findOrCreate({
                where: {
                    login: 'test'
                },
                transaction: tx
            });
        })
        .then(function () {
            tx.commit();
        });
    });
});

SQL log:

Executing (default): DROP TABLE IF EXISTS "Users" CASCADE;
Executing (default): CREATE TABLE IF NOT EXISTS "Users" ("id"   SERIAL , "login" VARCHAR(255) UNIQUE, PRIMARY KEY ("id"));
Executing (default): SELECT i.relname AS name, ix.indisprimary AS primary, ix.indisunique AS unique, ix.indkey AS indkey, array_agg(a.attnum) as column_indexes, array_agg(a.attname) AS column_names, pg_get_indexdef(ix.indexrelid) AS definition FROM pg_class t, pg_class i, pg_index ix, pg_attribute a WHERE t.oid = ix.indrelid AND i.oid = ix.indexrelid AND a.attrelid = t.oid AND a.attnum = ANY(ix.indkey) AND t.relkind = 'r' and t.relname = 'Users' GROUP BY i.relname, ix.indexrelid, ix.indisprimary, ix.indisunique, ix.indkey ORDER BY i.relname;
Executing (6a28eaa0-9716-4db0-be66-967f8ec12058): START TRANSACTION;
Executing (6a28eaa0-9716-4db0-be66-967f8ec12058): SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
Executing (6a28eaa0-9716-4db0-be66-967f8ec12058): SET autocommit = 1;
Executing (6a28eaa0-9716-4db0-be66-967f8ec12058): SAVEPOINT "6a28eaa0-9716-4db0-be66-967f8ec12058-savepoint-1";
Executing (6a28eaa0-9716-4db0-be66-967f8ec12058): SAVEPOINT "6a28eaa0-9716-4db0-be66-967f8ec12058-savepoint-2";
Executing (6a28eaa0-9716-4db0-be66-967f8ec12058): SELECT "id", "login" FROM "Users" AS "User" WHERE "User"."login" = 'test' LIMIT 1;
Executing (6a28eaa0-9716-4db0-be66-967f8ec12058): SELECT "id", "login" FROM "Users" AS "User" WHERE "User"."login" = 'test' LIMIT 1;
Executing (6a28eaa0-9716-4db0-be66-967f8ec12058): CREATE OR REPLACE FUNCTION pg_temp.testfunc(OUT response "Users", OUT sequelize_caught_exception text) RETURNS RECORD AS $func_66f952b0ec354cdbb8923433f3248e4a$ BEGIN INSERT INTO "Users" ("id","login") VALUES (DEFAULT,'test') RETURNING * INTO response; EXCEPTION WHEN unique_violation THEN GET STACKED DIAGNOSTICS sequelize_caught_exception = PG_EXCEPTION_DETAIL; END $func_66f952b0ec354cdbb8923433f3248e4a$ LANGUAGE plpgsql; SELECT (testfunc.response).*, testfunc.sequelize_caught_exception FROM pg_temp.testfunc(); DROP FUNCTION IF EXISTS pg_temp.testfunc();
Executing (6a28eaa0-9716-4db0-be66-967f8ec12058): CREATE OR REPLACE FUNCTION pg_temp.testfunc(OUT response "Users", OUT sequelize_caught_exception text) RETURNS RECORD AS $func_2abdfe30c027469dac0b5fe594fb4dda$ BEGIN INSERT INTO "Users" ("id","login") VALUES (DEFAULT,'test') RETURNING * INTO response; EXCEPTION WHEN unique_violation THEN GET STACKED DIAGNOSTICS sequelize_caught_exception = PG_EXCEPTION_DETAIL; END $func_2abdfe30c027469dac0b5fe594fb4dda$ LANGUAGE plpgsql; SELECT (testfunc.response).*, testfunc.sequelize_caught_exception FROM pg_temp.testfunc(); DROP FUNCTION IF EXISTS pg_temp.testfunc();

Error stack:

Unhandled rejection Error: Cannot find module 'pg-native'
    at Function.Module._resolveFilename (module.js:336:15)
    at Function.Module._load (module.js:278:25)
    at Module.require (module.js:365:17)
    at require (module.js:384:17)
    at Object.<anonymous> (/home/user/test/node_modules/pg/lib/native/index.js:1:76)
    at Module._compile (module.js:460:26)
    at Object.Module._extensions..js (module.js:478:10)
    at Module.load (module.js:355:32)
    at Function.Module._load (module.js:310:12)
    at Module.require (module.js:365:17)
    at require (module.js:384:17)
    at null.<anonymous> (/home/user/test/node_modules/pg/lib/index.js:78:36)
    at /home/user/test/node_modules/lodash/index.js:3159:32
    at baseForOwn (/home/user/test/node_modules/lodash/index.js:2089:14)
    at baseClone (/home/user/test/node_modules/lodash/index.js:1799:39)
    at /home/user/test/node_modules/lodash/index.js:1800:23
From previous event:
    at Promise.catch (/home/user/test/node_modules/sequelize/lib/promise.js:21:17)
    at Object.<anonymous> (/home/user/test/node_modules/sequelize/lib/model.js:1199:15)
From previous event:
    at Promise.then (/home/user/test/node_modules/sequelize/lib/promise.js:21:17)
    at module.exports.Model.findOrCreate (/home/user/test/node_modules/sequelize/lib/model.js:1180:8)
    at /home/user/test/tests.js:30:16
From previous event:
    at /home/user/test/tests.js:29:18
    at processImmediate [as _immediateCallback] (timers.js:358:17)
From previous event:
    at Promise.then (/home/user/test/node_modules/sequelize/lib/promise.js:21:17)
    at Object.<anonymous> (/home/user/test/tests.js:26:2)
    at Module._compile (module.js:460:26)
    at Object.Module._extensions..js (module.js:478:10)
    at Module.load (module.js:355:32)
    at Function.Module._load (module.js:310:12)
    at Function.Module.runMain (module.js:501:10)
    at startup (node.js:129:16)
    at node.js:814:3

Note: without the transaction is the same error

Activity

  1. tornillo commented on May 21, 2015

    @tornillo
    ContributorAuthor

    The error occurs when calling optClone->lodash.cloneDeep from findOne and other similar methods.
    The PG-module has a property 'native', which is a getter:

    module.exports.__defineGetter__("native", function() {
      delete module.exports.native;
      module.exports.native = new PG(require('./native'));
      return module.exports.native;
    });

    During cloning this getter is called and throwing error.

    Workarounds:

    1: Before Sequelize initialization in application we can remove stupid getter:

    var pg = require('pg');
    delete pg.native;

    It should be documented.

    2: Delete getter when require PG in Sequelize connection-manager.js if config.native === false

    3: Or we need to patch Units.clone for totally skipping property 'lib' cloning:

       cloneDeep: function(obj, fn) {
    -    return lodash.cloneDeep(obj, function (elem) {
    +    return lodash.cloneDeep(obj, function (elem, key) {
    +      // Skip property 'lib' cloning (PG-native error workaround)
    +      if (key === 'lib' && elem.hasOwnProperty('native')) {
    +        return elem;
    +      }
    +
  2. janmeier commented on May 21, 2015

    @janmeier
    Member

    Hmm, we've seen this problem before - optClone should be handling this problem already by not cloning transaction instances. Which version are you on?

  3. tornillo commented on May 21, 2015

    @tornillo
    ContributorAuthor

    3.0.1 - latest
    optClone clone all properties, pg.native is a getter.
    Lodash cloneDeep iterates through all properties and gets a value of each -> getter called.

  4. tornillo commented on May 21, 2015

    @tornillo
    ContributorAuthor

    ...and only then transaction is skipped by checking:

    elem instanceof Transaction
  5. janmeier commented on May 21, 2015

    @janmeier
    Member

    Hmm, it seems we are trying to clone a sequelize instance - which has a reference to the pg instance... weird..

  6. tornillo commented on May 21, 2015

    @tornillo
    ContributorAuthor

    Oh, I missed the important thing:
    It occurs only when findOne called an the end of findOrCreate
    https://github.com/sequelize/sequelize/blob/master/lib/model.js#L1207

  7. zooofeex commented on May 27, 2015

    @zooofeex

    I am having the same issue

  8. added
    type: bugDEPRECATED: replace with the "bug" issue type
    on May 27, 2015
  9. self-assigned this
    on May 27, 2015
  10. tornillo commented on May 27, 2015

    @tornillo
    ContributorAuthor

    Commit 4f9b502 solved the problem.
    Bug is not reproduced in version 3.1.1
    Thank you!

  11. mickhansen commented on May 27, 2015

    @mickhansen
    Contributor

    Great :)

  12. stoiacs commented on Jul 17, 2015

    @stoiacs

    In 3.3.2 I had the same issue, workaround by tornillo solved (delete pg.native;).

  13. jbrawnjr commented on Apr 21, 2016

    @jbrawnjr

    Still encountering the optClone issue in 3.21.0.

  14. benjaminhon commented on Jun 1, 2016

    @benjaminhon

    i still have this error message occurring, but i have no idea why it came suddenly. At first it didn't have it then suddenly it came. Im using postgres, and its giving me and error that i have no mysql dialect in node modules as well as pg-native

  15. 63 remaining items

  16. 1valdis commented on Jul 3, 2020

    @1valdis

    @superrandres do you use [email protected] or above?

  17. superrandres commented on Jul 4, 2020

    @superrandres

    Hello @1valdis thanks for answering. I indicate the versions that I am using:
    "pg": "^7.14.0",
    "pg-hstore": "^2.3.3",
    "sequelize": "^5.22.3"
    The MongoDB error has nothing to do with this.

  18. 1valdis commented on Jul 4, 2020

    @1valdis

    @superrandres you have [email protected]. Try using pg@8 or above (npm i -s pg@8) and see if the error is still there. I indicated a few post ago that upgrading pg from 7 to 8 solved the issue for me.

  19. superrandres commented on Jul 4, 2020

    @superrandres

    @1valdis This solved the problem, thank you very much.

  20. jeromeSH26 commented on Sep 26, 2020

    @jeromeSH26

    Hi,
    still got this error by just testing the connection (using native=true) in the connection options. Have to turn it to false.

    The workaround to delete the pg.native property is failing as this is a readonly property (in typescript)

    
    "pg": "^8.3.3",
    "pg-hstore": "^2.3.3",
    "sequelize": "^6.3.5",
    
    const dbConnection: Sequelize = new Sequelize(
    		DB_PARAMS.DB_DATABASE,
    		DB_PARAMS.DB_USER,
    		DB_PARAMS.DB_PWD,
    		{
    			host: DB_PARAMS.DB_HOST,
    			dialect: DB_PARAMS.DB_DIALECT.toLowerCase() as Dialect,
    			logging: DB_PARAMS.DB_LOG,
    			minifyAliases: true,
    			native: true,
    			pool: {
    				min: DB_PARAMS.DB_MINPOOL,
    				max: DB_PARAMS.DB_MAXPOOL,
    			},
    			port: DB_PARAMS.DB_PORT,
    			quoteIdentifiers: true,
    			typeValidation: true,
    		}
    	);
    

    image

  21. sshaginyan commented on Oct 11, 2020

    @sshaginyan

    Same issue as @jeromeSH26

  22. soryy708 commented on Feb 15, 2021

    @soryy708
    Contributor

    If the failure happens at build time (e.g. when running webpack), and you don't want to use pg-native, you can add it to webpack's externals s.t. it doesn't complain if it can't find the package.

  23. ps2goat commented on Mar 10, 2021

    @ps2goat

    @jeromeSH26 @sshaginyan

    This should work in typescript, though I haven't tested.

    delete (<any>pg).native;
  24. ps2goat commented on Mar 10, 2021

    @ps2goat

    I have confirmed that the line above works in Typescript. I had similar issues with TypeORM, not Sequelize. It appears to be an issue with the pg npm package, which is odd. I've seen it work on other machines...

    UPDATE: This fix worked with an older version of Node (10.22.1), but not 14..14.0

  25. papb commented on Apr 4, 2021

    @papb
    Member

    Since version 8, the .native getter is no longer enumerable, therefore this problem can be avoided by upgrading to pg 8. For this reason I will close this issue now. If anyone still experiences this problem with pg 8 please let me know and I will reopen this.

    However, in principle, it is Sequelize's fault to deep clone these things to begin with. I've opened #13168 to track this.

  26. RahmatAliMalik5 commented on Jul 31, 2022

    @RahmatAliMalik5

    I am still experiencing this issue with pg ^8.7.3. I have tried to delete native property by using the delete (<any>pg).native and delete pg.native. Also I have set logging: false. I am using sequelize in nestjs with angular ssr. Also using native:false The details are as follows:

          const sequelize = new Sequelize({
            database: 'vdp',
            dialect: 'postgres',
            native: false,
            username: 'postgres',
            password: 'root',
            host: 'localhost',
            port: 5432,
            dialectModule: pg,
            define: {
              timestamps: false,
            },
            logging: false,
          });
    

    Package.json:

    
      "dependencies": {
        "@angular/animations": "^14.0.0",
        "@angular/cdk": "^14.1.0",
        "@angular/common": "^14.0.0",
        "@angular/compiler": "^14.0.0",
        "@angular/core": "^14.0.0",
        "@angular/forms": "^14.0.0",
        "@angular/material": "^14.0.3",
        "@angular/platform-browser": "^14.0.0",
        "@angular/platform-browser-dynamic": "^14.0.0",
        "@angular/platform-server": "^14.0.0",
        "@angular/router": "^14.0.0",
        "@nestjs/cli": "^8.2.8",
        "@nestjs/common": "^8.0.0",
        "@nestjs/core": "^8.0.0",
        "@nestjs/ng-universal": "^6.1.0",
        "@nestjs/platform-express": "^8.0.0",
        "@nestjs/sequelize": "^8.0.1",
        "@nguniversal/express-engine": "^14.0.0",
        "body-parser": "^1.20.0",
        "bootstrap": "^5.1.3",
        "chart.js": "^3.8.0",
        "chartjs-plugin-datalabels": "^2.0.0",
        "class-transformer": "^0.4.0",
        "class-validator": "^0.13.1",
        "compression": "^1.7.4",
        "express": "^4.15.2",
        "helmet": "^5.1.0",
        "mysql2": "^2.3.3",
        "ngx-papaparse": "^5.1.0",
        "ngx-scrollbar": "^10.0.0",
        "pg": "^8.7.3",
        "pg-hstore": "^2.3.4",
        "primeicons": "^5.0.0",
        "primeng": "^14.0.0",
        "reflect-metadata": "^0.1.13",
        "rxjs": "~7.5.0",
        "sequelize": "^6.21.1",
        "sequelize-typescript": "^2.1.3",
        "tslib": "^2.3.0",
        "xlsx": "https://cdn.sheetjs.com/xlsx-0.18.9/xlsx-0.18.9.tgz",
        "zone.js": "~0.11.4"
      },
      "devDependencies": {
        "@angular-devkit/build-angular": "^14.0.2",
        "@angular/cli": "~14.0.2",
        "@angular/compiler-cli": "^14.0.0",
        "@nguniversal/builders": "^14.0.0",
        "@types/express": "^4.17.0",
        "@types/jasmine": "~4.0.0",
        "@types/sequelize": "^4.28.13",
        "jasmine-core": "~4.1.0",
        "karma": "~6.3.0",
        "karma-chrome-launcher": "~3.1.0",
        "karma-coverage": "~2.2.0",
        "karma-jasmine": "~5.0.0",
        "karma-jasmine-html-reporter": "~1.7.0",
        "typescript": "~4.7.2"
      }
    

    I have read all the thread and tried everything commented by the community. Nothing worked for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

dependencyFor issues and PRs. Things that are related to one or more dependencies.type: otherDEPRECATED: replace with the "meta" issue type

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions