pg-promise ColumnSet with nested object prop? - pg-promise

What is the proper syntax for a object child as a column prop?
const cs = new pgp.helpers.ColumnSet([
{
name: 'uid',
prop: 'id'
}, {
name: 'created_at'
prop: 'member.created_at // <-- error
}
])
Cant seem to get this to work.

While the regular pg-promise query formatting (using Named Parameters) supports nested properties, specifically helpers do not, due to certain templates-related complexity.
However, it is not necessary, because ColumnSet syntax for columns is very flexible (see type Column), and supports dynamic property resolution.
Simply update the column to use init, to get the value dynamically:
{
name: 'created_at',
init: c => c.source.member.created_at
}
For the field, we go to the source object, as per documentation, and take what we need.
Alternative syntax:
{
name: 'created_at',
init(c) {
// with this syntax, this = c.source
return this.member.created_at;
}
}

Related

Prisma Typescript where clause inside include?

I am trying to query the database (Postgres) through Prisma. My query is
const products = await prisma.products.findMany({
where: { category: ProductsCategoryEnum[category] },
include: {
vehicles: {
include: {
manufacturers: { name: { in: { manufacturers.map(item => `"${item}"`) } } },
},
},
},
});
The error message is
Type '{ name: { in: { manufacturers: string; "": any; }; }; }' is not assignable to type 'boolean | manufacturersArgs'.
Object literal may only specify known properties, and 'name' does not exist in type 'manufacturersArgs'.ts(2322)
Manufacturers have the field name and it is unique; I am not sure why this is not working or how I can update this code to be able to query the database. It is like I should cast the values into Prisma arguments.
The TypeScript error is pretty self-explanatory: the name property does not exist in manufacturersArgs. The emitted Prisma Client does a great job of telling you what properties do and do not exist when filtering.
If you are trying to perform a nested filter, you need to use select instead of include.
Documentation: https://www.prisma.io/docs/concepts/components/prisma-client/relation-queries#filter-a-list-of-relations
Your query is going to look something like this:
const products = await prisma.products.findMany({
where: { category: ProductsCategoryEnum[category] },
select: {
// also need to select any other fields you need here
vehicles: {
// Updated this
select: { manufacturers: true },
// Updated this to add an explicit "where" clause
where: {
manufacturers: { name: { in: { manufacturers.map(item => `"${item}"`) } } },
},
},
},
});
The final code ultimately depends on your Prisma schema. If you are using an editor like VS Code, it should provide Intellisense into the Prisma Client's TypeScript definitions. You can use that to navigate the full Prisma Client and construct your query based on exactly what is and is not available. In VS Code, hold control [Windows] or command [macOS] and click on findMany in prisma.products.findMany. This lets you browse the full Prisma Client and construct your query!
The in keyword isn't working for me. I use hasSome to find items in an array. hasEvery is also available depending what the requirements are.
hasSome: manufacturers.map(item => `"${item}"`),
See https://www.prisma.io/docs/reference/api-reference/prisma-client-reference#scalar-list-filters

Ag-grid column definition and `__metadata__` property

I need to introduce object with my own properties in columnDefs object.
After, I did it, I see in dev console
So, here has been written, that I could mean __metadata__ property. Does this property suit to mine purpose?
I've not found any information in types and docs about this property
ColDef has no custom state property that you could use. Certainly do not touch __metadata__. The name sounds like some internal implementation detail.
You can store your metadata in a separate object, for example using colId as a key:
columnDefs: ColDef[] = [
{
colId: 'id',
field: 'id'
},
{
colId: 'name',
field: 'name'
}
];
columnMetadata: {
id: 'something custom',
name: 'custom data'
}
private getColumnMetadata(column: Column) {
return this.columnMetadata[column.getColId()];
}

PG-Promise - "Property doesn't exist" error with skip function

I am having trouble figuring out how to utilize skip to skip undefined/null values. I keep getting Error: Property 'vehicle_id' doesn't exist. Is skip within column set and skip of upsertReplaceQuery() somehow conflicting with each other? How can I get it to work?
const vehicleColumnSet = new pgp.helpers.ColumnSet(
[
{ name: 'user_id' },
{
name: 'vehicle_id',
skip: (c) => !c.exists,
},
{ name: 'model_id', def: null },
],
{ table: 'vehicle' }
);
const upsertReplaceQuery = (data, columnSet, conflictField) => {
return `${pgp.helpers.insert(
data,
columnSet
)} ON CONFLICT(${conflictField}) DO UPDATE SET ${columnSet.assignColumns({
from: 'EXCLUDED',
skip: conflictField,
})}`;
};
const vehicleUpsertQuery = upsertReplaceQuery(
{
user_id,
model_id: vehicle_model,
},
vehicleColumnSet,
'user_id'
);
await task.none(vehicleUpsertQuery);
PostgreSQL has no support for any skip logic within its multi-row insert syntax.
And pg-promise documentation also tells you within skip description:
An override for skipping columns dynamically.
Used by methods update (for a single object) and sets, ignored by methods insert and values.
It is also ignored when conditional flag cnd is set.
At most, you can add such logic against a single-row insert, as shown here.

must have a selection of subfields. Did you mean \"createEvent { ... }\"?", [graphql] [duplicate]

Hi I am trying to learn GraphQL language. I have below snippet of code.
// Welcome to Launchpad!
// Log in to edit and save pads, run queries in GraphiQL on the right.
// Click "Download" above to get a zip with a standalone Node.js server.
// See docs and examples at https://github.com/apollographql/awesome-launchpad
// graphql-tools combines a schema string with resolvers.
import { makeExecutableSchema } from 'graphql-tools';
// Construct a schema, using GraphQL schema language
const typeDefs = `
type User {
name: String!
age: Int!
}
type Query {
me: User
}
`;
const user = { name: 'Williams', age: 26};
// Provide resolver functions for your schema fields
const resolvers = {
Query: {
me: (root, args, context) => {
return user;
},
},
};
// Required: Export the GraphQL.js schema object as "schema"
export const schema = makeExecutableSchema({
typeDefs,
resolvers,
});
// Optional: Export a function to get context from the request. It accepts two
// parameters - headers (lowercased http headers) and secrets (secrets defined
// in secrets section). It must return an object (or a promise resolving to it).
export function context(headers, secrets) {
return {
headers,
secrets,
};
};
// Optional: Export a root value to be passed during execution
// export const rootValue = {};
// Optional: Export a root function, that returns root to be passed
// during execution, accepting headers and secrets. It can return a
// promise. rootFunction takes precedence over rootValue.
// export function rootFunction(headers, secrets) {
// return {
// headers,
// secrets,
// };
// };
Request:
{
me
}
Response:
{
"errors": [
{
"message": "Field \"me\" of type \"User\" must have a selection of subfields. Did you mean \"me { ... }\"?",
"locations": [
{
"line": 4,
"column": 3
}
]
}
]
}
Does anyone know what I am doing wrong ? How to fix it ?
From the docs:
A GraphQL object type has a name and fields, but at some point those
fields have to resolve to some concrete data. That's where the scalar
types come in: they represent the leaves of the query.
GraphQL requires that you construct your queries in a way that only returns concrete data. Each field has to ultimately resolve to one or more scalars (or enums). That means you cannot just request a field that resolves to a type without also indicating which fields of that type you want to get back.
That's what the error message you received is telling you -- you requested a User type, but you didn't tell GraphQL at least one field to get back from that type.
To fix it, just change your request to include name like this:
{
me {
name
}
}
... or age. Or both. You cannot, however, request a specific type and expect GraphQL to provide all the fields for it -- you will always have to provide a selection (one or more) of fields for that type.

Updating SOME fields in nested object without overwriting others with spread operator

How to update some field in nested object without overwriting other fields in that nested object with spread operator? My function is as follows
exports.handler = ((data, context) => {
const profile = data.profile
const uid = context.auth.uid
const newRef = db.collection("user").doc(uid)
return newRef.update({
profile: {...profile}
}).then(() => {
return "Data updated seccusfully"
})
})
which is suppose to update nested profile object. However the function removes also all not specified fields in that object. Is there any way to achieve update object with spread operator without removing other fields or do we have to specify each fields as the documentation says?
db.collection("users").doc("frank").update({
"age": 13,
"favorites.color": "Red"
})
My profile object contains different fields for each type of user and I'm updating the profile fileds in multiple places therefore I was hoping to simplify it like this
It looks like we can update some object properties without overwriting others with set method like this. Strange it doesn't work with update
return newRef.set({
profile: { ...profile }
}, { merge: true }).then(() => {
return "Data updated seccusfully"
})
Really appreciate all your help