Repository: bookshelf/bookshelf

Issue #1944: Bookshelf not setting models correctly
Created: 2019-02-05T01:28:28Z
Introduction
After setting up a model and calling fetchAll, I recieve and error message telling me it is querying from an undefined table. If I query from knex directly or pg directly it works. if i call console.log(User.query().toString()); it outputs select * so it appears it is somehow skipping the where clause in the query
System Configuration

Node: v10.15.1
NPM: 6.7.0
Bookshelf: 0.14.2 (tried multiple previous releases)
Knex: 0.15.0 (tried 0.13.0, 0.14.x, 0.15.x, 0.16.x)
pg: 7.8.0 (tried multiple previous releases)
PostgreSQL 8.4.20 (I'm aware this is super old but my web hosting provider doesn't offer a better option)
MacOS 10.14.2 (Mojave)

Error
Unhandled rejection error: missing FROM-clause entry for table "undefined"
    at Connection.parseE (/Users/Wesley/Desktop/VendorSearch/node_modules/pg/lib/connection.js:555:11)
    at Connection.parseMessage (/Users/Wesley/Desktop/VendorSearch/node_modules/pg/lib/connection.js:380:19)
    at Socket.<anonymous> (/Users/Wesley/Desktop/VendorSearch/node_modules/pg/lib/connection.js:120:22)
    at Socket.emit (events.js:189:13)
    at addChunk (_stream_readable.js:284:12)
    at readableAddChunk (_stream_readable.js:265:11)
    at Socket.Readable.push (_stream_readable.js:220:10)
    at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)

Code
Database.js
const config = require(`../../utils/Config`);

const knex = require(`knex`)({
  client: config.database.dialect,
  version: config.database.version,
  connection: {
    host: config.database.host,
    user: config.database.username,
    password: config.database.password,
    database: config.database.name,
    port: config.database.port
  }
});

const bookshelf = require(`bookshelf`)(knex);

const Role = bookshelf.Model.extend({
  tablename: `roles`
});

const User = bookshelf.Model.extend({
  tablename: `users`,
  role: function () {
    return this.belongsTo(Role);
  }
});

exports.Role = Role;
exports.User = User;

exports.__bookshelf = bookshelf;
exports.knex = knex;

User.js
const User = require(`../../Database`).User;
const jsonify = require(`../../Database`).jsonify;

exports.getAll = () => {
  return User.fetchAll()
    .then(jsonify);
};

Works if you call
using pg
const { Client } = require(`pg`);

const client = new Client({
  host: config.database.host,
  port: config.database.port,
  user: config.database.username,
  password: config.database.password,
  database: config.database.name
});

client.connect().then(() => console.log(`connected`))
.catch(e => console.error(`connection error`, e.stack));

client.query(`SELECT * FROM users`, (err, res) => {
    if (err) {
      console.log(err.stack);
    } else {
      console.log(res.rows);
    }

using knex
const knex = require(`knex`)({
  client: config.database.dialect,
  version: config.database.version,
  connection: {
    host: config.database.host,
    user: config.database.username,
    password: config.database.password,
    database: config.database.name,
    port: config.database.port
  }
});
console.log(knex.select().from('users').then(function(users){
    console.log(users);
}));

Duplicate issue #1945: missing FROM-clause entry for table "undefined"
Created: 2019-02-05T21:11:40Z
Introduction
After setting up a model and calling fetchAll, I recieve and error message telling me it is querying from an undefined table. If I query from knex directly or pg directly it works. (duplicate of #1944 because issue was closed without being resolved) model.fetchAll() is what throws the error I provided. and, I'm not calling model.createTable() because I have already created my database on the server. In other projects where i've used bookshelf I just needed to supply the tablename to connect to an existing table.
System Configuration

Node: v10.15.1
NPM: 6.7.0
Bookshelf: 0.14.2 (tried multiple previous releases)
Knex: 0.15.0 (tried 0.13.0, 0.14.x, 0.15.x, 0.16.x)
pg: 7.8.0 (tried multiple previous releases)
PostgreSQL 8.4.20 (I'm aware this is super old but my web hosting provider doesn't offer a better option)
MacOS 10.14.2 (Mojave)

Error
Unhandled rejection error: missing FROM-clause entry for table "undefined"
    at Connection.parseE (/Users/Wesley/Desktop/VendorSearch/node_modules/pg/lib/connection.js:555:11)
    at Connection.parseMessage (/Users/Wesley/Desktop/VendorSearch/node_modules/pg/lib/connection.js:380:19)
    at Socket.<anonymous> (/Users/Wesley/Desktop/VendorSearch/node_modules/pg/lib/connection.js:120:22)
    at Socket.emit (events.js:189:13)
    at addChunk (_stream_readable.js:284:12)
    at readableAddChunk (_stream_readable.js:265:11)
    at Socket.Readable.push (_stream_readable.js:220:10)
    at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)

Code
Database.js
const config = require(`../../utils/Config`);

const knex = require(`knex`)({
  client: config.database.dialect,
  version: config.database.version,
  connection: {
    host: config.database.host,
    user: config.database.username,
    password: config.database.password,
    database: config.database.name,
    port: config.database.port
  }
});

const bookshelf = require(`bookshelf`)(knex);

const Role = bookshelf.Model.extend({
  tablename: `roles`
});

const User = bookshelf.Model.extend({
  tablename: `users`,
  role: function () {
    return this.belongsTo(Role);
  }
});

exports.Role = Role;
exports.User = User;

exports.__bookshelf = bookshelf;
exports.knex = knex;

User.js
const User = require(`../../Database`).User;
const jsonify = require(`../../Database`).jsonify;

exports.getAll = () => {
  return User.fetchAll()
    .then(jsonify);
};

PG Database Dump
...

CREATE TABLE roles (
    id serial NOT NULL,
    code text,
    name text
);

...

CREATE TABLE users (
    id serial NOT NULL,
    username text NOT NULL,
    password text NOT NULL,
    name text NOT NULL,
    email text NOT NULL,
    store_name text,
    role integer DEFAULT 2 NOT NULL,
    active text DEFAULT 'true'::text NOT NULL
);

...

ALTER TABLE ONLY roles
    ADD CONSTRAINT "Roles_pkey" PRIMARY KEY (id);

ALTER TABLE ONLY users
    ADD CONSTRAINT "Users_pkey" PRIMARY KEY (id);

ALTER TABLE ONLY users
    ADD CONSTRAINT "Users_username_key" UNIQUE (username);

ALTER TABLE ONLY users
    ADD CONSTRAINT "Users_role_fkey" FOREIGN KEY (role) REFERENCES roles(id);
...

Package.json
{
  "name": "(project name)",
  "version": "1.0.0",
  "description": "(project desc)",
  "main": "index.js",
  "scripts": {
    "dev": "./node_modules/.bin/nodemon --watch src/libs --watch src/routes --watch src/utils --watch src/index.js src/index.js",
    "lint": "./node_modules/.bin/eslint src/** && ./node_modules/.bin/ejslint views/**",
    "fix-lint": "./node_modules/.bin/eslint src/** --fix",
    "gulp": "./node_modules/.bin/gulp",
    "gulp-dev": "./node_modules/.bin/gulp && ./node_modules/.bin/gulp watch",
    "prod": "node src/index.js"
  },
  "repository": {
    "type": "git",
    "url": "(git repo address)"
  },
  "author": "Wesley Reed",
  "license": "ISC",
  "dependencies": {
    "bcrypt": "^3.0.3",
    "bookshelf": "^0.14.2",
    "bootstrap": "^4.2.1",
    "bootstrap-colorpicker": "^2.5.2",
    "bootstrap-datepicker": "^1.5.1",
    "bootstrap-select": "^1.7.4",
    "cookie-parser": "~1.4.3",
    "datatables": "^1.10.18",
    "datatables-buttons": "^1.0.3",
    "datatables.net-buttons": "^1.2.2",
    "ejs": "^2.6.1",
    "express": "^4.16.4",
    "express-session": "^1.15.6",
    "font-awesome": "^4.5.0",
    "jquery": "^3.3.1",
    "knex": "^0.15.0",
    "lodash": "^4.17.11",
    "moment": "^2.10.6",
    "pg": "^7.8.0",
    "popper.js": "^1.14.7",
    "restify": "^4.1.1",
    "serve-favicon": "^2.5.0"
  },
  "devDependencies": {
    "@babel/cli": "^7.0.0",
    "@babel/core": "^7.0.0",
    "@babel/node": "^7.0.0",
    "@babel/plugin-proposal-class-properties": "^7.0.0",
    "@babel/plugin-proposal-decorators": "^7.0.0",
    "@babel/plugin-proposal-do-expressions": "^7.0.0",
    "@babel/plugin-proposal-export-default-from": "^7.0.0",
    "@babel/plugin-proposal-export-namespace-from": "^7.0.0",
    "@babel/plugin-proposal-function-bind": "^7.0.0",
    "@babel/plugin-proposal-function-sent": "^7.0.0",
    "@babel/plugin-proposal-json-strings": "^7.0.0",
    "@babel/plugin-proposal-logical-assignment-operators": "^7.0.0",
    "@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0",
    "@babel/plugin-proposal-numeric-separator": "^7.0.0",
    "@babel/plugin-proposal-optional-chaining": "^7.0.0",
    "@babel/plugin-proposal-pipeline-operator": "^7.0.0",
    "@babel/plugin-proposal-throw-expressions": "^7.0.0",
    "@babel/plugin-syntax-dynamic-import": "^7.0.0",
    "@babel/plugin-syntax-import-meta": "^7.0.0",
    "@babel/plugin-transform-regenerator": "^7.0.0",
    "@babel/polyfill": "^7.0.0",
    "@babel/preset-env": "^7.3.1",
    "babel-core": "^6.26.3",
    "babel-eslint": "^9.0.0",
    "babel-loader": "^8.0.4",
    "babel-polyfill": "^6.26.0",
    "ejs-lint": "^0.3.0",
    "eslint": "^2.13.1",
    "gulp": "^4.0.0",
    "gulp-babel": "^8.0.0",
    "gulp-clean-css": "^2.3.2",
    "gulp-concat": "^2.6.0",
    "gulp-sass": "^2.3.2",
    "gulp-uglify": "^2.0.1",
    "gulp-util": "^3.0.6",
    "husky": "^1.3.1",
    "nodemon": "^1.18.9"
  }
}

Works if you call
using pg
const { Client } = require(`pg`);

const client = new Client({
  host: config.database.host,
  port: config.database.port,
  user: config.database.username,
  password: config.database.password,
  database: config.database.name
});

client.connect().then(() => console.log(`connected`))
.catch(e => console.error(`connection error`, e.stack));

client.query(`SELECT * FROM users`, (err, res) => {
    if (err) {
      console.log(err.stack);
    } else {
      console.log(res.rows);
    }

using knex
const knex = require(`knex`)({
  client: config.database.dialect,
  version: config.database.version,
  connection: {
    host: config.database.host,
    user: config.database.username,
    password: config.database.password,
    database: config.database.name,
    port: config.database.port
  }
});
console.log(knex.select().from('users').then(function(users){
    console.log(users);
}));

Closing comment (2019-02-06T09:30:52Z): Duplicate of #1944.