GithubHelp home page GithubHelp logo

nestjs-knex's Introduction

NestJS Knex

NPM Version Package License

Table of Contents

Description

Integrates Knex with Nest

Installation

npm install nestjs-knex knex

You can also use the interactive CLI

npx nestjs-modules

Examples

npm install nestjs-knex knex sqlite3

KnexModule.forRoot(options, connection?)

import { Module } from '@nestjs/common';
import { KnexModule } from 'nestjs-knex';
import { AppController } from './app.controller';

@Module({
  imports: [
    KnexModule.forRoot({
      config: {
        client: "sqlite3",
        useNullAsDefault: true,
        connection: ':memory:',
      },
    }),
  ],
  controllers: [AppController],
})
export class AppModule {}

KnexModule.forRootAsync(options, connection?)

import { Module } from '@nestjs/common';
import { KnexModule } from 'nestjs-knex';
import { AppController } from './app.controller';

@Module({
  imports: [
    KnexModule.forRootAsync({
      useFactory: () => ({
        config: {
          client: "sqlite3",
          useNullAsDefault: true,
          connection: ':memory:',
        },
      }),
    }),
  ],
  controllers: [AppController],
})
export class AppModule {}

InjectKnex(connection?)

import { Controller, Get, } from '@nestjs/common';
import { InjectKnex, Knex } from 'nestjs-knex';

@Controller()
export class AppController {
  constructor(
    @InjectKnex() private readonly knex: Knex,
  ) {}

  @Get()
  async getHello() {
    if (!await this.knex.schema.hasTable('users')) {
      await this.knex.schema.createTable('users', table => {
        table.increments('id').primary();
        table.string('name');
      });
    }
    await this.knex.table('users').insert({ name: 'Name' });
    const users = await this.knex.table('users');
    return { users };
  }
}

License

MIT

nestjs-knex's People

Contributors

dependabot[bot] avatar svtslv avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

nestjs-knex's Issues

Cannot read property 'client' of undefined

I met this problem and the issue happens when I config my Knex with

import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { KnexModuleOptionsFactory } from 'nestjs-knex';

// https://github.com/svtslv/nestjs-knex#readme
@Injectable()
export class PostgresConfig implements KnexModuleOptionsFactory {
  constructor(private readonly configService: ConfigService) {}
  createKnexModuleOptions() {
    const config = this.configService.get('postgres');
    return { config };
  }
}
import { Module } from '@nestjs/common';
import { KnexModule } from 'nestjs-knex';
import { ConfigModule } from '@nestjs/config';
import { PostgresConfig } from './postgres.config';

// https://docs.nestjs.com/techniques/configuration
@Module({
  imports: [
    KnexModule.forRootAsync({
      imports: [ConfigModule],
      useClass: PostgresConfig,
    }),
  ],
})
export class PostgresModule {}
export const config = () => ({
  postgres: {
    connection: {
      host: process.env['db_host'],
      port: process.env['db_port'],
      username: process.env['db_username'],
      password: process.env['db_password'],
      database: process.env['db_name'],
    },
    searchPath: ['public'],
    client: 'pg',
    pool: { min: 0, max: 7 },
  },
  app: {
    port: +process.env['app.port'],
  },
});

How to fix errors?

I have a lot of errors (Found 84 errors.)

typescript - last version

> tsc -p tsconfig.build.json

node_modules/knex/types/index.d.ts:1132:16 - error TS1110: Type expected.

1132       column1: `${TTable1}.${TKey1}`,
                    ~~~

node_modules/knex/types/index.d.ts:1133:14 - error TS1005: ';' expected.

1133       column2: `${TTable2}.${TKey2}`
                  ~

node_modules/knex/types/index.d.ts:1134:5 - error TS1128: Declaration or statement expected.

1134     ): QueryBuilder<TRecord2, TResult2>;
         ~

node_modules/knex/types/index.d.ts:1134:6 - error TS1128: Declaration or statement expected.

1134     ): QueryBuilder<TRecord2, TResult2>;
          ~

node_modules/knex/types/index.d.ts:1134:40 - error TS1005: '(' expected.

1134     ): QueryBuilder<TRecord2, TResult2>;
                                            ~

node_modules/knex/types/index.d.ts:1136:33 - error TS1005: '?' expected.

1136       TTable1 extends TableNames,
                                     ~

node_modules/knex/types/index.d.ts:1137:15 - error TS1005: ';' expected.

1137       TTable2 extends TableNames,
                   ~~~~~~~

node_modules/knex/types/index.d.ts:1138:13 - error TS1005: ';' expected.

1138       TKey1 extends StrKey<ResolveTableType<TableType<TTable1>>> & StrKey<TRecord1>,
                 ~~~~~~~

node_modules/knex/types/index.d.ts:1138:66 - error TS1005: '(' expected.

1138       TKey1 extends StrKey<ResolveTableType<TableType<TTable1>>> & StrKey<TRecord1>,
                                                                      ~

node_modules/knex/types/index.d.ts:1138:84 - error TS1109: Expression expected.

1138       TKey1 extends StrKey<ResolveTableType<TableType<TTable1>>> & StrKey<TRecord1>,
                                                                                        ~

node_modules/knex/types/index.d.ts:1139:13 - error TS1005: ',' expected.

1139       TKey2 extends StrKey<ResolveTableType<TableType<TTable2>>>,
                 ~~~~~~~

node_modules/knex/types/index.d.ts:1139:65 - error TS1109: Expression expected.

1139       TKey2 extends StrKey<ResolveTableType<TableType<TTable2>>>,
                                                                     ~

node_modules/knex/types/index.d.ts:1140:43 - error TS1109: Expression expected.

1140       TRecord1 = ResolveTableType<TRecord>,
                                               ~

node_modules/knex/types/index.d.ts:1141:65 - error TS1109: Expression expected.

1141       TRecord2 = TRecord1 & ResolveTableType<TableType<TTable2>>,

...

tsconfig

{
  "compilerOptions": {
    "module": "commonjs",
    "declaration": true,
    "removeComments": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "allowSyntheticDefaultImports": true,
    "target": "es2017",
    "sourceMap": true,
    "outDir": "./dist/server",
    "baseUrl": "./",
    "incremental": true
  }
}

Pooling?

Pooling support? Will you add it?

Multi tenant connections

Hi,

I use this module and it works great, but I am stuck on how to do multi tenant dynamic connections based on Scope.REQUEST.

I managed to make two connections using two KnexModule.forRootAsync but I am unsure how I can dynamically create the connection upon API request to connect to another DB.

I store all my tenant connection details in a master DB and connect to:

imports: [
    KnexModule.forRootAsync({
      useFactory: async (configService: ConfigService) => ({
        config: {
          client: configService.get('db_master.type'),
          useNullAsDefault: true,
          connection: {
            host: configService.get('db_master.host'),
            database: configService.get('db_master.database'),
            user: configService.get('db_master.username'),
            password: configService.get('db_master.password'),
            port: configService.get('db_master.port'),
            ssl: { rejectUnauthorized: false },
          },
          pool: {
            min: 0,
            max: 5,
            acquireTimeoutMillis: 60000,
            idleTimeoutMillis: 600000,
            afterCreate: (conn: any, done: any) => {
              conn.query('SELECT version();', (err: any, result: any) => {
                console.log('Connected to master database:', configService.get('db_master.database'))
                done()
              })
            },
          },
        },
      }),
      inject: [ConfigService],
    },
    'MASTER_CONNECTION'),
  ]

And in my TenantService I use:

export class TenantService {
  constructor(
    @InjectKnex('MASTER_CONNECTION') private readonly db: Knex,
  ) {}
...

With this connection I can go into the tenant table in the master DB and get the connection details to all tenants. Eventually I will load it into a Redis instance.

Now the problem when calling a Scope.REQUEST service I need to get the tenant ID either from header or resolve the user and create another dynamic connection.

So I need to create a TENANT_CONNECTION which can somehow be dynamic and use it in my "ProductService":

export class ProductService {
  constructor(
    @InjectKnex('TENANT_CONNECTION') private readonly db: Knex,
  ) {}
...

Any tips?

Thanks.

handle connection state

Hello, I can't find how I can handle success or error connection to the database. AfterCreate method seems not working. Any ideas on how to do it?
Basically, I want to have an opportunity to point callbacks on DB connected;

KnexModule.forRootAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: (configService: ConfigService) => ({
        config: {
          log: new DbLogger(),
          debug: true,
          client: 'postgres',
          useNullAsDefault: true,
          connection: {
            host: configService.get('DB_HOST'),
            port: configService.get<number>('DB_PORT'),
            username: configService.get('DB_USERNAME'),
            password: configService.get('DB_PASSWORD'),
            database: configService.get('DB_NAME'),
          },
          afterCreate: (conn, error) => {
              // created with success or error
          },
        },
      }),
    }),

Typescript 5 support

Hi, with typescript 5 there is an error

import { Injectable } from '@nestjs/common';
import { InjectKnex, Knex } from 'nestjs-knex';
@Injectable()
export class UsersService {
  constructor(@InjectKnex() private readonly knex: Knex) {}
}
Unable to resolve signature of parameter decorator when called as an expression.
  Argument of type 'undefined' is not assignable to parameter of type 'string | symbol'.ts(1239)
(alias) InjectKnex(connection?: string | undefined): (target: object, key: string | symbol, index?: number | undefined) => void
import InjectKnex

image

How to create table from QueryBuilder?

I have union query

queryKnex = queryKnex.union(queryKnex2);

I want to create table from it query and add alias?

      let queryUnion = this.knex({ 'random_name': queryKnex })
        .select('*')

How to do it right?

How to connect to multiple DB?

Hi, thanks for this package. I have a question about its usage with more than a single database?
Should I have to manually assign a token to the nest module to have injected the correct knex instance?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.