Skip to content
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

kanel-kysely should provide config options for namespace or multi-tenant style for multi-schema usage. #587

Open
aq1018 opened this issue Jul 18, 2024 · 3 comments

Comments

@aq1018
Copy link

aq1018 commented Jul 18, 2024

First of all. I'd like to say that kanel and kanel-kysely is a great tool with lots of flexibility for type generation, and I'm grateful of the efforts and design put into this awesome project. I'm currently using it in multiple projects in my work. It is great!

I'd like to make a suggestion to include a schemaStyle option with either namespace or multi-tenant values based on the Working with schemas article from Kysely.

In it, it posits two ways of using schemas in postgres:

  1. To group a logical set of tables under the same "namespace". For example all tables directly related to users could live under a user schema.

  2. To have a separate namespaced copy of a set of tables for each tenant in a multitenant application.

For Option 1, Database interface prefixes table names with the schema name, except the public schema. Example:

interface Database {
  // these tables are in the `user` schema
  'user.user': UserTable
  'user.user_permission': UserPermissionTable
  'user.permission': PermissionTable

  // these tables are in the `public` schema, notice that it doesn't prefix with `public.`
  pet: PetTable
}

For Option 2, Database interface prefixes table names with the schema name only in the public schema. This is because in multi-tenant situation, the public schema holds shared tables for all tenants. Example:

interface Database {
  // these tables are in non-public schemas and they are not prefixed
  user: UserTable
  user_permission: UserPermissionTable

  // These tables are in public schemas and prefixed with `public.`
  'public.permission': PermissionTable
}
@aq1018
Copy link
Author

aq1018 commented Jul 18, 2024

For those who stumbled here. I was able to make namespace style work by doing the following:

function removePublicSchemaPrefix(output) {
  for (const path in output) {
    const { declarations } = output[path]
    declarations.forEach((declaration) => {
      const { declarationType, name, properties } = declaration
      if (declarationType === 'interface' && name === 'PublicSchema') {
        properties.forEach((property) => {
          property.name = property.name.replace(/^public\./, '')
        })
      }
    })
  }
  return output
}

module.exports = {
  preRenderHooks: [
    makeKyselyHook({ includeSchemaNameInTableName: true }),
    removePublicSchemaPrefix,
  ],
}

@kristiandupont
Copy link
Owner

Thank you for the kind words and the contribution!
This seems like an obvious improvement. As I am not using Kysely myself (I expect that I will in the future), I am not certain of what the most correct answers are and I have been relying on the community for this. I am happy to make this change in the library itself (or accept a PR that does).

@aq1018
Copy link
Author

aq1018 commented Aug 6, 2024

I agree with you. The two styles I mentioned are from Kysely documentation, but in reality, different use cases will lead to different design decisions. kanel with its preRenderHooks is flexible enough to solve most of my needs. Let's wait for more feedback from Kysely users. This issue is a nice to have, and not urgent ( at least to me ).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants