TypeOrm updating geography column error: unknown GeoJSON type - postgresql

I have NestJs+TypeOrm+PostgreSQL project with a table column that is defined like so:
"area" GEOGRAPHY(POLYGON,4326) DEFAULT NULL
My entity column is defined like this:
#Column({
type: 'geography',
spatialFeatureType: 'Polygon',
srid: 4326,
nullable: true,
default: null,
transformer: {
from: (dbValue) => {...},
to: (entityValue: Position[]) => {
const polyObj: Polygon = {
type: 'Polygon',
coordinates: [entityValue]
}
return JSON.stringify(polyObj)
}
}
}
area: Position[]
When I try to update an entry with a new value I get this error:
error: error: unknown GeoJSON type
The TypeOrm logs show this as the parametrized query:
query failed: UPDATE "<tablename>" SET "uuid" = $1, "area" = ST_SetSRID(ST_GeomFromGeoJSON($2), 4326)::geography WHERE "uuid" IN ($3)
-- PARAMETERS: ["<uuid>","\"{\\\"type\\\":\\\"Polygon\\\",\\\"coordinates\\\":[[[10.053713611343388,57.20829976160476],[10.052780202606208,57.20646356881912],[10.054282239654546,57.206306674693764],[10.055151275375371,57.20820098140615],[10.053713611343388,57.20829976160476]]]}\"","<uuid>"]
Does anyone know what I might be doing wrong?

Related

Unable to update data using prisma

I am using prisma to update some fields but i am getting error.
I am using unique id to update the data.
Before update i am able to get all the data from table so prisma is working on select
const cartUpdate = await prisma.custom_checkout__c.update({
where: {
id: uniqueId,
},
data: {
status__c: 'Checkout completed',
coupon_code__c: coupon,
checkout_id__c: result.subscription.id,
}
})
Error is below
PrismaClientUnknownRequestError:
Invalid `prisma.custom_checkout__c.update()` invocation:
Error occurred during query execution:
ConnectorError(ConnectorError { user_facing_error: None, kind: QueryError(Error { kind: Db, cause: Some(DbError { severity: "ERROR", parsed_severity: Some(Error), code: SqlState(E42883), message: "function get_xmlbinary() does not exist", detail: None, hint: Some("No function matches the given name and argument types. You might need to add explicit type casts."), position: Some(Internal { position: 2, query: "(get_xmlbinary() = 'base64')" }), where_: Some("PL/pgSQL function hc_custom_checkout__c_status() line 3 at IF"), schema: None, table: None, column: None, datatype: None, constraint: None, file: Some("parse_func.c"), line: Some(629), routine: Some("ParseFuncOrColumn") }) }) })
at RequestHandler.handleRequestError (/Users/bi

Mongo Bulkwrite with $addToSet

I have been trying a bulkwrite but get complained about typing (I think it's about the syntax):
Type '{ roles: string; }' is not assignable to type 'SetFields<any>'.
Type '{ roles: string; }' is not assignable to type 'NotAcceptedFields<any, readonly any[]>'.
Property 'roles' is incompatible with index signature.
Type 'string' is not assignable to type 'never'.ts(2345)
I can't find any examples or docs about using $addToSet in a builkwrite. Here it is (INTER_ADMINS is just an array of string):
const bulkUpdates = INTER_ADMINS.map((ethAddress) => {
return {
updateOne: {
filter: { ethAddress },
update: {
$addToSet: {
roles: 'INTERNAL_ADMIN',
},
},
upsert: true,
},
};
});
const res = await db.collection('users').bulkWrite(bulkUpdates);
users collection sample:
{
ethAddress: 'something',
roles: ['role1','role2']
}
Appreciate your help
The syntax is correct, this is just a typescript error. I recommend you just add a #ts-ignore and move on.
Here is the type definition:
export type UpdateQuery<TSchema> = {
....
$addToSet?: SetFields<TSchema> | undefined;
....
};
export type SetFields<TSchema> = ({
readonly [key in KeysOfAType<TSchema, ReadonlyArray<any> | undefined>]?:
| UpdateOptionalId<Unpacked<TSchema[key]>>
| AddToSetOperators<Array<UpdateOptionalId<Unpacked<TSchema[key]>>>>;
} &
NotAcceptedFields<TSchema, ReadonlyArray<any> | undefined>) & {
readonly [key: string]: AddToSetOperators<any> | any;
};
As you can see because the Schema is not provided typescript doesn't know which are the valid "keys" of the schema so the only valid type left in the SetFields is the NotAcceptedFields fields type (which are null and undefined, not string )
If you provide a Schema to the operations I believe it should sort the issue:
const bulkUpdates: BulkWriteOperation<UserSchema>[] = ...

Sequelize migration queryInterface.removeColum fails to work

I created a migration file to add a column as an up and then delete it under down.
Here's the migration file code:
module.exports = {
up: (queryInterface, Sequelize) =>
queryInterface.addColumn('Books', 'Rating', {
allowNull: false,
type: Sequelize.ENUM('like', 'dislike'),
}),
down: (queryInterface, Sequelize) => {
queryInterface.removeColumn('Books', 'Rating');
},
};
When I ran it for the first time using db:migrate, it successfully added the column but when I did a db:migrate:undo:all and then ran the migrations again, it threw me an error sqying
======= 20180211100937-AddedRatingIntoBooks: migrating
======= 2018-02-11 15:42:46.076 IST
[64531] ERROR: type "enum_Books_Rating" already exists 2018-02-11 15:42:46.076 IST
[64531] STATEMENT: CREATE TYPE "public"."enum_Books_Rating" AS ENUM('like', 'dislike');
ALTER TABLE "public"."Boo ks" ADD COLUMN "Rating" "public"."enum_Books_Rating";
ERROR: type "enum_Books_Rating" already exists
The issue is still live here.
Sequelize creates TYPES for each of the enum you define, which you can find here
The name of the ENUM type is the concatenation of "enum", the table name, and the column name in snake casing. (enum_Books_Rating here)
To create migrations for ENUM, you have to modify your down function like so:
module.exports = {
up: (queryInterface, Sequelize) =>
queryInterface.addColumn('Books', 'Rating', {
allowNull: false,
type: Sequelize.ENUM('like', 'dislike')
}),
down: (queryInterface, Sequelize) =>
queryInterface.removeColumn('Books', 'Rating')
.then(() => queryInterface.sequelize.query('DROP TYPE "enum_Books_Rating";'));
};
Hope this helps.

Sails.js one to many association with postgreSQL: column does not exist

I need some help with associations in sails 0.12.13 with postgresql.
I have an "App" model and a "Membership" model. Relation should be one to many (one app can be associated with many relationships).
This is the App model db table schema (table is called "apps"):
Table "public.apps"
Column | Type | Modifiers
------------+-----------------------------+---------------------------------------------------
id | integer | not null default nextval('apps_id_seq'::regclass)
name | character varying | not null
Indexes:
"apps_pkey" PRIMARY KEY, btree (id)
"apps_name_key" UNIQUE CONSTRAINT, btree (name)
Referenced by:
TABLE "memberships" CONSTRAINT "app_fk" FOREIGN KEY (app_id) REFERENCES apps(id) ON UPDATE RESTRICT ON DELETE CASCADE
And this is memberships:
Table "public.memberships"
Column | Type | Modifiers
------------+-----------------------------+----------------------------------------------------------
id | integer | not null default nextval('memberships_id_seq'::regclass)
app_id | integer | not null
Foreign-key constraints:
"app_fk" FOREIGN KEY (app_id) REFERENCES apps(id) ON UPDATE RESTRICT ON DELETE CASCADE
in my user model, i have this:
module.exports = {
tableName: 'apps',
autoCreatedAt: false,
autoUpdatedAt: false,
attributes: {
name: { type: 'string', unique: true, required: true, alphanumericdashed: true },
memberships: { collection: 'memberships', model: 'Membership' },
}
}
And this is the Membership model:
module.exports = {
tableName: 'memberships',
autoCreatedAt: false,
autoUpdatedAt: false,
attributes: {
app: { model: 'app', columnName: 'app_id' },
},
};
When I try to query an app and get its memberships:
App.find({ id: 1 }).populate('memberships').exec((err, app) => {
if (err) throw err;
console.log(app.memberships);
});
I get this error:
Error (E_UNKNOWN) :: Encountered an unexpected error
error: column apps.memberships does not exist
at Connection.parseE (/usr/src/app/node_modules/sails-postgresql/node_modules/pg/lib/connection.js:539:11)
at Connection.parseMessage (/usr/src/app/node_modules/sails-postgresql/node_modules/pg/lib/connection.js:366:17)
at Socket.<anonymous> (/usr/src/app/node_modules/sails-postgresql/node_modules/pg/lib/connection.js:105:22)
at emitOne (events.js:115:13)
at Socket.emit (events.js:210:7)
at addChunk (_stream_readable.js:252:12)
at readableAddChunk (_stream_readable.js:239:11)
at Socket.Readable.push (_stream_readable.js:197:10)
at TCP.onread (net.js:589:20)
Looks like the association is not "enabled" and waterline is searching for an actual column "membership" in my model. Can anybody explain me what I am doing wrong? thx
According to the documentation, I would guess that you have a bad association.
// App.js
module.exports = {
tableName: 'apps',
autoCreatedAt: false,
autoUpdatedAt: false,
attributes: {
name: {
type: 'string',
unique: true,
required: true,
alphanumericdashed: true
},
memberships: {
collection: 'membership', // <-- changed to singular (as your model should be)
via: 'app' // <-- use "via" instead of "model"
},
}
}
// Membership.js
module.exports = {
tableName: 'memberships',
autoCreatedAt: false,
autoUpdatedAt: false,
attributes: {
app: {
model: 'app'
// <-- removed the "columnName" here
},
},
};
Also, convention generally says name your model as a singular instance. For example, its "User.js" and not "Users.js". It's valid to refer to the collection as a plural. I made some changes in your naming, but you'll have to see how that affects your files (since you didn't give those names).

Sailsjs Model Object Not Returning Data For Postgresql

I have the following in my Sailsjs config/adapter.js:
module.exports.adapters = {
'default': 'postgres',
postgres : {
module : 'sails-postgresql',
host : 'xxx.compute-1.amazonaws.com',
port : 5432,
user : 'xxx',
password : 'xxx',
database : 'xxx',
ssl : true,
schema : true
}
};
And in models/Movie.js:
Movie = {
attributes: {
tableName: 'movies.movies',
title: 'string',
link: 'string'
}
};
module.exports = Movie;
In my controller:
Movie.query("SELECT * FROM movies.movies", function(err, movies) {
console.log('movies', movies.rows);
});
movies.rows DOES return the correct data
However:
Movie.find({ title: 'Frozen' }, function(err, movies) {
console.log('movies', movies)
});
movies returns an EMPTY ARRAY
So it seems all connections are good because the raw query works perfectly.
Could there be something I am doing wrong with setting up the Movie.find() or with models/Movie.js?
Does the tableName attribute not support postgresql schema_name.table_name?
First off, you need to move tableName out of attributes, since it's a class-level property. Second, sails-postgresql does have some (very undocumented) support for schemas, using the meta.schemaName option:
Movie = {
tableName: 'movies',
meta: {
schemaName: 'movie'
},
attributes: {
title: 'string',
link: 'string'
}
};
module.exports = Movie;
You can give that a try, and if it doesn't work, either move your table into the public schema, or nudge the author of the schemaName support for help.