pg node (postgres) UPDATE statement returns column does not exist when it does exist - node.js

In pgAdmin/the cli, the following query:
UPDATE wq SET l_id = NULL, v_id = NULL WHERE w_id = 'cf93bc71-88c1-4bba-9e5c-fdc58d0ed14e';
works fine. However, when calling the same with the pg package in node:
const w_id_val = 'cf93bc71-88c1-4bba-9e5c-fdc58d0ed14e';
/*
(here client is the result of calling const pool = pg.Pool({...}) ,
then let client = await pool.connect());
*/
const result = await client.query(
`UPDATE wq
SET l_id = null,
v_id = null
WHERE w_id = $1`,
[w_id_val]
);
I get the following error:
{
"message":"column \"w_id\" does not exist",
"stack":"error: column \"w_id\" does not exist\n at Connection.parseE (/Users/lukasjenks/Documents/Work/socrative-nodejs/node_modules/pg/lib/connection.js:569:11)\n at Connection.parseMessage (/Users/lukasjenks/Documents/Work/socrative-nodejs/node_modules/pg/lib/connection.js:396:17)\n at Socket.<anonymous> (/Users/lukasjenks/Documents/Work/socrative-nodejs/node_modules/pg/lib/connection.js:132:22)\n at Socket.emit (events.js:314:20)\n at Socket.EventEmitter.emit (domain.js:483:12)\n at addChunk (_stream_readable.js:297:12)\n at readableAddChunk (_stream_readable.js:272:9)\n at Socket.Readable.push (_stream_readable.js:213:10)\n at TCP.onStreamRead (internal/stream_base_commons.js:188:23)\n at TCP.callbackTrampoline (internal/async_hooks.js:126:14)",
"name":"error",
"length":112,
"severity":"ERROR",
"code":"42703",
"position":"68",
"file":"parse_relation.c",
"line":"3514",
"routine":"errMissingColumn"
}
I can confirm the column exists with this query:
SELECT table_schema, table_name, column_name, data_type
FROM information_schema.columns
WHERE table_name = 'wq';
public wq id uuid
public wq w_id uuid
public wq l_id uuid
public wq v_id uuid
I can also confirm that the column (w_id) should be recognized by pg as when using pg to query the table with a SELECT statement, I get this back in the fields property in the result object returned:
fields: [
Field {
name: 'id',
tableID: 26611,
columnID: 1,
dataTypeID: 2950,
dataTypeSize: 16,
dataTypeModifier: -1,
format: 'text'
},
Field {
name: 'w_id',
tableID: 26611,
columnID: 3,
dataTypeID: 2950,
dataTypeSize: 16,
dataTypeModifier: -1,
format: 'text'
},
...
I've also confirmed this isn't a case issue; i.e. the column name is all lowercase and using double quotes around the column name has no effect.

Related

typeorm update relations: INSERT before DELETE leads to a duplicate violation

I have a manytomany relation.
A Coordination can have several countries.
It ends up with 3 tables: coordination, country and coordination_country_join
#Entity('coordination')
...
#ManyToMany(() => CountryEntity)
#JoinTable({
joinColumn: {
name: 'event_id_w',
referencedColumnName: 'event_id_w',
},
inverseJoinColumn: {
name: 'CountryUnCode',
referencedColumnName: 'UN_Code',
},
})
countries: string[];
When I save my Coordination, with an array of countries, it works fine, but I found out weird sequence in the SQL statements.
To update the relations (the countries, content of coordination_country_join), it does
INSERT INTO coordination_country_join ... all the new countries of the given coordination
then DELETE from coordination_country_join all the old countries of the relation
Which does not work when I save the coordination while no country has changed because it tries to insert a pair (countryId, coordinationId) which already exists in the coordination_country_join table.
How can I fix this issue ?
Thanks
query: SELECT "CoordinationEntity"."gid" AS "CoordinationEntity_gid", "CoordinationEntity"."objectid" AS "CoordinationEntity_objectid", "CoordinationEntity"."gdacsid" AS "CoordinationEntity_gdacsid", "CoordinationEntity"."type" AS "CoordinationEntity_type", "CoordinationEntity"."name" AS "CoordinationEntity_name", "CoordinationEntity"."coordinato" AS "CoordinationEntity_coordinato", "CoordinationEntity"."requestor" AS "CoordinationEntity_requestor", "CoordinationEntity"."activation" AS "CoordinationEntity_activation", "CoordinationEntity"."spacechart" AS "CoordinationEntity_spacechart", "CoordinationEntity"."glidenumbe" AS "CoordinationEntity_glidenumbe", "CoordinationEntity"."url" AS "CoordinationEntity_url", "CoordinationEntity"."date_creat" AS "CoordinationEntity_date_creat", "CoordinationEntity"."date_close" AS "CoordinationEntity_date_close", "CoordinationEntity"."status" AS "CoordinationEntity_status", "CoordinationEntity"."comment" AS "CoordinationEntity_comment", "CoordinationEntity"."event_id_w" AS "CoordinationEntity_event_id_w", ST_AsGeoJSON("CoordinationEntity"."the_geom")::json AS "CoordinationEntity_the_geom" FROM "coordination" "CoordinationEntity" WHERE "CoordinationEntity"."gid" IN ($1) -- PARAMETERS: [36]
query: SELECT "CoordinationEntity_countries_rid"."event_id_w" AS "event_id_w", "CoordinationEntity_countries_rid"."CountryUnCode" AS "CountryUnCode" FROM "country" "country" INNER JOIN "coordination_countries_country" "CoordinationEntity_countries_rid" ON ("CoordinationEntity_countries_rid"."event_id_w" = $1 AND "CoordinationEntity_countries_rid"."CountryUnCode" = "country"."UN_Code") ORDER BY "CoordinationEntity_countries_rid"."CountryUnCode" ASC, "CoordinationEntity_countries_rid"."event_id_w" ASC -- PARAMETERS: [50]
query: START TRANSACTION
query: INSERT INTO "coordination_countries_country"("event_id_w", "CountryUnCode") VALUES ($1, $2) -- PARAMETERS: [50,4]
query failed: INSERT INTO "coordination_countries_country"("event_id_w", "CountryUnCode") VALUES ($1, $2) -- PARAMETERS: [50,4]
error: error: duplicate key value violates unique constraint "PK_622c3d328cd639f1f6deb8f3874"
at Parser.parseErrorMessage (/home/florent/dev/smcs/api/node_modules/pg-protocol/src/parser.ts:369:69)
at Parser.handlePacket (/home/florent/dev/smcs/api/node_modules/pg-protocol/src/parser.ts:188:21)
at Parser.parse (/home/florent/dev/smcs/api/node_modules/pg-protocol/src/parser.ts:103:30)
at Socket.<anonymous> (/home/florent/dev/smcs/api/node_modules/pg-protocol/src/index.ts:7:48)
at Socket.emit (events.js:375:28)
at addChunk (internal/streams/readable.js:290:12)
at readableAddChunk (internal/streams/readable.js:265:9)
at Socket.Readable.push (internal/streams/readable.js:204:10)
at TCP.onStreamRead (internal/stream_base_commons.js:188:23) {
length: 274,
severity: 'ERROR',
code: '23505',
detail: 'Key (event_id_w, "CountryUnCode")=(50, 4) already exists.',
hint: undefined,
position: undefined,
internalPosition: undefined,
internalQuery: undefined,
where: undefined,
schema: 'public',
table: 'coordination_countries_country',
column: undefined,
dataType: undefined,
constraint: 'PK_622c3d328cd639f1f6deb8f3874',
file: 'nbtinsert.c',
line: '434',
routine: '_bt_check_unique'
}
query: ROLLBACK

Sequelize, how to use Op.contains to find models that have certain values

I'm working on some project about renting houses and appartments and I've reached the point when i need to implement filtering houses based on features they have(wifi, security and other staff). In the beginning I decided to try Sequelize ORM for the first time. Stuff like adding, creating, editing is working fine, but the filtering part is where I have some problems.
I'm working with nodejs,express and postgresql.
I need to find all houses that have features listed in the array of features IDs. Here is what I've tried. In this example I'm trying to get houses which have features with ids 1, 2 and 4.
db.House.findAll({
include: [{
model: db.HouseFeature,
as: 'HouseFeatures',
where: {
featureId: {
[Op.contains]: [1, 2, 4] //<- array of featuresIds
}
}
}]
})
Fetching houses by single feature id works fine because i don't use Op.contains there.
Here are some relations related to this case:
House.hasMany(models.HouseFeature, { onDelete: 'CASCADE' });
HouseFeature.belongsTo(models.House);
HouseFeature contains featureId field.
Here is the error I get:
error: оператор не существует: integer #> unknown
at Connection.parseE (C:\***\server\node_modules\pg\lib\connection.js:601:11)
at Connection.parseMessage (C:\***\server\node_modules\pg\lib\connection.js:398:19)
at Socket.<anonymous> (C:\***\server\node_modules\pg\lib\connection.js:120:22)
at Socket.emit (events.js:182:13)
at addChunk (_stream_readable.js:283:12)
at readableAddChunk (_stream_readable.js:264:11)
at Socket.Readable.push (_stream_readable.js:219:10)
at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)
name: 'error',
length: 397,
severity: 'ОШИБКА',
code: '42883',
detail: undefined,
hint:
'Оператор с данными именем и типами аргументов не найден. Возможно, вам следует добавить явные приведения типов.',
position: '851',
internalPosition: undefined,
internalQuery: undefined,
where: undefined,
schema: undefined,
table: undefined,
column: undefined,
dataType: undefined,
constraint: undefined,
file:
'd:\\pginstaller.auto\\postgres.windows-x64\\src\\backend\\parser\\parse_oper.c',
line: '731',
routine: 'op_error',
sql:
'SELECT "House"."id", "House"."title", "House"."description", "House"."price", "House"."address", "House"."lat", "House"."lon", "House"."kitchen", "House"."bathrooms", "House"."floor", "House"."totalFloors", "House"."people", "House"."area", "House"."bedrooms", "House"."trusted", "House"."createdAt", "House"."updatedAt", "House"."CityId", "House"."ComplexId", "House"."OwnerProfileId", "House"."HouseTypeId", "House"."RentTypeId", "HouseFeatures"."id" AS "HouseFeatures.id", "HouseFeatures"."featureId" AS "HouseFeatures.featureId", "HouseFeatures"."createdAt" AS "HouseFeatures.createdAt", "HouseFeatures"."updatedAt" AS "HouseFeatures.updatedAt", "HouseFeatures"."HouseId" AS "HouseFeatures.HouseId" FROM "Houses" AS "House" INNER JOIN "HouseFeatures" AS "HouseFeatures" ON "House"."id" = "HouseFeatures"."HouseId" AND "HouseFeatures"."featureId" #> \'1,2\';'
Sorry for some russian there.
UPDATE:
I've managed to do what i needed by changing each House relating only to one HouseFeature, and by changing that HouseFeature model to store array of featureIds. Op.contains works fine.
db.House.findAll({
include: [{
model: db.HouseFeature,
as: 'HouseFeature',
where: {
features: {
[Op.contains]: req.body.features
}
},
}]
})
// Associations
HouseFeature.belongsTo(models.House);
House.hasOne(models.HouseFeature, { onDelete: 'CASCADE' });
const HouseFeature = sequelize.define('HouseFeature', {
features: {
type: DataTypes.ARRAY(DataTypes.INTEGER)
}
}, {});
Now i have one little issue. Can I somehow link HouseFeature model with Feature model to fetch feature icon images and name later on? With Feature ids being stored inside HouseFeature array.
Please check the difference between Op.in and Op.contains:
[Op.in]: [1, 2], // IN [1, 2]
[Op.contains]: [1, 2] // #> [1, 2] (PG array contains operator)
It looks like HouseFeatures.featureId is a PK with type integer, not a postgres array.
Please try:
db.House.findAll({
include: [{
model: db.HouseFeature,
as: 'HouseFeatures',
where: {
featureId: {
[Op.in]: [1, 2, 3]
}
}
}]
})
or even
db.House.findAll({
include: [{
model: db.HouseFeature,
as: 'HouseFeatures',
where: {
featureId: [1, 2, 3]
}
}]
})
instead

Postgresql Syntax Error when attempting to create a type

I am trying to create the following type in postgresql using pg nodejs package. I have written a function that queries the pool and attempts to create this type as follows:
return pool.query(
`
CREATE TYPE grade_sheet AS (
subjectName VARCHAR(100),
teacherName VARCHAR(100),
uti VARCHAR(32),
markAllocated REAL CHECK (markAllocated >= 0.0 AND markAllocated <= 100.00),
markObtained REAL CHECK (markObtained >= 0.0 AND markObtained <= 100.00),
gradeObtained CHAR(2),
dateTaken TIMESTAMP
);
`
);
When I am trying to run the script, I get the following syntax error:
{ error: syntax error at or near "CHECK"
at Connection.parseE (/home/zerocool/myschool/node_modules/pg/lib/connection.js:554:11)
at Connection.parseMessage (/home/zerocool/myschool/node_modules/pg/lib/connection.js:379:19)
at Socket.<anonymous> (/home/zerocool/myschool/node_modules/pg/lib/connection.js:119:22)
at Socket.emit (events.js:127:13)
at addChunk (_stream_readable.js:269:12)
at readableAddChunk (_stream_readable.js:256:11)
at Socket.Readable.push (_stream_readable.js:213:10)
at TCP.onread (net.js:590:20)
name: 'error',
length: 95,
severity: 'ERROR',
code: '42601',
detail: undefined,
hint: undefined,
position: '195',
internalPosition: undefined,
internalQuery: undefined,
where: undefined,
schema: undefined,
table: undefined,
column: undefined,
dataType: undefined,
constraint: undefined,
file: 'scan.l',
line: '1087',
routine: 'scanner_yyerror' }
Constraints cannot be used in types. But in domains the can. Domains however cannot have multiple attributes. But you can solve your problem by using both:
create a domain including your check constraint
create a type an use the domain
It could look like:
CREATE DOMAIN grade_sheet_real
real
CHECK (value >= 0.0
AND value <= 100.00);
CREATE TYPE grade_sheet AS
(subjectname varchar(100),
teachername varchar(100),
uti varchar(32),
markallocated grade_sheet_real,
markobtained grade_sheet_real,
gradeobtained char(2),
datetaken timestamp);

Type error in Nodejs and Postgres

I'm generating a dynamic update query based on a list of provided objects for postgres. This is what my query looks like:
update loan_item_assignment as t set id = c.id, dateselectionid = c.dateselectionid, loanitemid = c.loanitemid, active = c.active, type = c.type from (values ( $1, $2, $3, $4, $5 ), ( $6, $7, $8, $9, $10 ), ( $11, $12, $13, $14, $15 ), ( $16, $17, $18, $19, $20 ), ( $21, $22, $23, $24, $25 ), ( $26, $27, $28, $29, $30 ), ( $31, $32, $33, $34, $35 ), ( $36, $37, $38, $39, $40 ) ) as c( id, dateselectionid, loanitemid, active, type ) where c.id = t.id returning *
And here's the values list I'm giving it:
[ 7,
35,
3,
true,
'normal',
8,
35,
4,
true,
'normal',
1,
35,
6,
true,
'normal',
2,
35,
7,
true,
'normal',
3,
35,
8,
true,
'normal',
5,
35,
10,
true,
'normal',
4,
35,
11,
true,
'normal',
6,
35,
12,
true,
'normal' ]
As far as I can tell, the values match up correctly. This is the error I'm seeing:
{ [error: operator does not exist: text = integer]
name: 'error',
length: 195,
severity: 'ERROR',
code: '42883',
detail: undefined,
hint: 'No operator matches the given name and argument type(s). You might need to add explicit type casts.',
position: '448',
internalPosition: undefined,
internalQuery: undefined,
where: undefined,
schema: undefined,
table: undefined,
column: undefined,
dataType: undefined,
constraint: undefined,
file: 'parse_oper.c',
line: '726',
routine: 'op_error' }
And this is the code that's ultimately running the query:
var performQuery = function(text, values, cb) {
pg.connect(connectionString, function(err, client, done) {
client.query(text, values, function(err, result) {
done();
if (!result) {
console.log(err);
cb([], err);
} else {
cb(result.rows, err);
}
})
});
}
And here is the table definition:
Table "public.loan_item_assignment"
Column | Type | Modifiers | Storage | Stats target | Description
-----------------+---------+-------------------------------------------------------------------+----------+--------------+-------------
id | integer | not null default nextval('loan_item_assignment_id_seq'::regclass) | plain | |
dateselectionid | integer | | plain | |
loanitemid | integer | | plain | |
active | boolean | | plain | |
type | text | | extended | |
Indexes:
"loan_item_assignment_pkey" PRIMARY KEY, btree (id)
Foreign-key constraints:
"loan_item_assignment_dateselectionid_fkey" FOREIGN KEY (dateselectionid) REFERENCES date_selection(id)
"loan_item_assignment_loanitemid_fkey" FOREIGN KEY (loanitemid) REFERENCES loan_item(id)
Vitaly-t's comment on my answer is the solution - to use the pg-promise library to generate the query, and specifically method helpers.update for generating multi-row update queries, as shown in PostgreSQL multi-row updates in Node.js.

SequelizeDatabaseError: ER_BAD_FIELD_ERROR: Unknown column

I'm getting the following error:
{ [SequelizeDatabaseError: ER_BAD_FIELD_ERROR: Unknown column 'activityId' in 'field list']
name: 'SequelizeDatabaseError',
message: 'ER_BAD_FIELD_ERROR: Unknown column \'activityId\' in \'field list\'',
parent:
{ [Error: ER_BAD_FIELD_ERROR: Unknown column 'activityId' in 'field list']
code: 'ER_BAD_FIELD_ERROR',
errno: 1054,
sqlState: '42S22',
index: 0,
sql: 'SELECT `id`, `activityType`, `customData`, `createdAt`, `updatedAt`, `activityId` FROM `activitiesTemplates` AS `ActivitiesTemplate` WHERE `ActivitiesTemplate`.`id` = NULL LIMIT 1;' },
original:
{ [Error: ER_BAD_FIELD_ERROR: Unknown column 'activityId' in 'field list']
code: 'ER_BAD_FIELD_ERROR',
errno: 1054,
sqlState: '42S22',
index: 0,
sql: 'SELECT `id`, `activityType`, `customData`, `createdAt`, `updatedAt`, `activityId` FROM `activitiesTemplates` AS `ActivitiesTemplate` WHERE `ActivitiesTemplate`.`id` = NULL LIMIT 1;' },
sql: 'SELECT `id`, `activityType`, `customData`, `createdAt`, `updatedAt`, `activityId` FROM `activitiesTemplates` AS `ActivitiesTemplate` WHERE `ActivitiesTemplate`.`id` = NULL LIMIT 1;' },
Is this an error mySQL database/relationships? or somewhere in my Node.js code?
In the database table, I do not have a field name "activityId". I also changed every instance in Code from activityId to id (a column that does exist in the table).
After making the changes I stopped my server. I did npm update, and restarted the server ; however, the console logs the error above.

Resources