使用数据库连接池为每个用户设置 search_path

问题描述 投票:0回答:1

我有一个听起来很愚蠢的问题,但我以前从未这样做过,并且有一些问题我似乎找不到答案。

我的项目位于 Next.js 14 中,使用 Kysely 和 node-postgres。我正在尝试设置一个多租户应用程序,其中每个租户都有自己的架构。问题出现在我建立连接并尝试将 search_path 设置为每个租户的特定架构但仅设置一次。这意味着如果我使用 2 个不同的帐户登录,则仅使用 1 个架构。

这是我的 Kysely 设置:

let pool: Pool | undefined;

if (!pool) {
  pool = new Pool({
    connectionString: process.env.DATABASE_URL,
  });
}

export const adapter = new NodePostgresAdapter(pool, {
  user: "auth_user",
  session: "user_session",
});

export const createPostgresDialect = (tenantId?: number) => {

  return new PostgresDialect({
    pool,
    onCreateConnection: async (connection) => {
      if (tenantId) {
        await connection.executeQuery({
          sql: `SET search_path TO tenant_${tenantId}, public`,
          query: { kind: 'RawNode', sqlFragments: [], parameters: [] },
          parameters: []
        });
      }
    }
  });
};

export const getDB = async(tenantId?: number) => {
  let db = new Kysely<Database & TenantSchema>({
    dialect: createPostgresDialect(tenantId),
    log: ['query', 'error'],
  });  

  return db
}

这就是我使用它的方式:

const auth = await getUser()

export const db = await getDB(auth?.session?.tenant_id)

然后我导入 db 并在我的组件和页面中使用它来进行我需要的查询。

另一件事我无法理解的是为什么当我这样做时:

const db = await getDB(auth?.session?.tenant_id)

并直接在我的页面或组件中使用它,例如它可以工作。使用 2 个不同的帐户登录会获得单独的架构。但我认为这种方式并不理想,因为我基本上必须在我想做查询的任何地方都获得会话。

这可能是愚蠢的问题,但我以前从未这样做过,我正在寻求帮助。不确定这是否可行,但我们将不胜感激。

database postgresql multi-tenant node-postgres kysely
1个回答
0
投票

Dialect (docs) 指的是数据库的底层类型(MySQL、PG 等)。我不确定您是否可以直接在其中实例化模式。

要使用模式,您可以参考以下文档,尤其是 withSchema。所以也许是这样的:

export const getDB = async(tenantId?: number) => {
  const dialect = new PostgresDialect({});

  const db = new Kysely<Database>({
    dialect,
    log: ['query', 'error'],
  });  

  return db.withSchema(tenantId)
}

希望这有帮助

© www.soinside.com 2019 - 2024. All rights reserved.