-
-
Notifications
You must be signed in to change notification settings - Fork 98
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
What approach can you recommend for data grouping? #566
Comments
I have been exploring this feature in TypeSQL (a similar library but for mysql). The approach I have used is to annotate the queries with -- @nested
SELECT
*
FROM users u
INNER JOIN posts p on p.user_id = u.id
WHERE u.id = :id Then TypeSQL will generate the function const user = await selectUserPostsNested(conn, {id: 1}); The result type will have the structure: { id: 1, username: 'user1', email: '[email protected]', posts: [{ title: 'Post 1', content: 'Content of post 1', user_id: 1 }] } |
You can either use:
|
One solution is to query the posts as a First creating the custom import { z } from "zod";
const post = z.object({
id: z.number(),
title: z.string(),
content: z.string(),
user_id: z.number(),
});
export const jsonbParser = post.array();
export type JsonbParser = z.TypeOf<typeof jsonbParser>; Registering it as a custom type parser for pg client. import { Pool, types } from "pg";
import { jsonbParser } from "./jsonbParser";
types.setTypeParser(types.builtins.JSONB, (val: string) =>
jsonbParser.parse(JSON.parse(val))
);
export const pgPool = new Pool({
user: process.env.POSTGRES_USER,
password: process.env.POSTGRES_PASSWORD,
host: "localhost",
database: "app",
port: 5432,
}); Overriding types in pgtyped config. {
"transforms": [
{
"mode": "sql",
"include": "**/*.sql",
"emitTemplate": "{{dir}}/{{name}}.queries.ts"
}
],
"srcDir": "./queries/",
"failOnError": false,
"camelCaseColumnNames": false,
"db": {
"host": "localhost",
"port": 5432,
"user": "postgres",
"dbName": "app",
"password": "postgres"
},
"typesOverrides": {
"jsonb": "./src/jsonbParser.ts#JsonbParser"
}
} Writing the query. /* @name GetUser */
SELECT users.id,
users.username,
users.email,
jsonb_agg_strict(posts) AS posts
FROM users
LEFT JOIN posts ON users.id = posts.user_id
WHERE users.id = :userId
GROUP BY users.id; This will give you the following types as a result. interface IGetUserResult {
email: string;
id: number;
posts: JsonbParser | null;
username: string;
}
type JsonbParser = {
id: number;
title: string;
content: string;
user_id: number;
}[] If you have any other models that you are querying as |
For example, let's consider the following structure. If we perform a JOIN on these tables, we'll end up with two records for one user.
How can we process the data to obtain such a structure?:
User { id, username, email, posts: [{ title: 'Post 1', content: 'Content of post 1', user_id: 1 }] }
Of course, we can write parsers each time, use helper functions from lodash, but is there a more fundamental approach? Thank you!
The text was updated successfully, but these errors were encountered: