#node.js #postgresql #nestjs #typeorm
#node.js #postgresql #nestjs #typeorm
Вопрос:
У меня возникла забавная проблема, когда я пытаюсь заставить TypeORM работать в моем проекте nestjs.
У меня есть приведенный ниже код для настройки моего проекта, да, все загружается, и да, я могу подключиться к своей базе данных.
import { CacheModule, Module } from '@nestjs/common';
import { JwtModule } from '@nestjs/jwt';
import { PassportModule } from '@nestjs/passport';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './entities/user.entity';
import { ConfigModule } from '@nestjs/config';
import { AuthenticationController } from './controllers/authentication.controller';
import { AuthenticationService } from './services/authentication.service';
import { Connection } from 'typeorm';
import { BaseEntity } from './entities/base.entity';
@Module({
imports: [
ConfigModule.forRoot(),
TypeOrmModule.forRoot({
type: 'postgres',
host: 'localhost',
port: 5432,
username: 'postgres',
password: process.env.POSTGRE_PASSWORD,
database: process.env.DATABASE,
migrationsTableName: 'migration_table',
entities: [User, BaseEntity],
migrations: [__dirname '/migrations/**/*.ts'],
subscribers: [__dirname '/subscribers/**/*.ts'],
cli: {
entitiesDir: '/entitys',
migrationsDir: '/migrations',
subscribersDir: '/subscribers',
},
synchronize: true,
autoLoadEntities: true,
}),
CacheModule.register(),
PassportModule,
JwtModule.register({
secret: 'myprivatekey',
signOptions: { expiresIn: '1d' },
}),
],
controllers: [AuthenticationController],
providers: [AuthenticationService],
})
export class AppModule {
constructor(private connection: Connection) {}
}
и вот сущности:
import {
Column,
BeforeUpdate,
BeforeInsert,
} from 'typeorm';
export class BaseEntity {
@Column()
created_at: Date;
@Column({
default: new Date(),
})
updated_at: Date;
@BeforeUpdate()
updateUpdatedAt() {
this.updated_at = new Date();
}
@BeforeInsert()
updateCreatedAt() {
this.created_at = new Date();
}
}
import {
Entity,
Column,
PrimaryGeneratedColumn,
Generated,
} from 'typeorm';
import { BaseEntity } from './base.entity';
@Entity('users')
export class User extends BaseEntity {
@PrimaryGeneratedColumn()
id: number;
@Column()
@Generated('uuid')
uuid: string;
@Column()
first_name: string;
@Column()
last_name: string;
@Column()
email: string;
@Column()
password: string;
@Column({
default: false,
})
confirmed: boolean;
@Column({
default: null,
})
seller_id: string;
@Column({
default: null,
})
auth_token: string;
@Column({
default: false,
})
is_admin: boolean;
}
Изначально я пытался выполнить сопоставление с шаблоном глобуса, но безрезультатно, поэтому теперь я напрямую импортирую свои объекты, пока не смогу что-то запустить. Также обратите внимание, что все мои модули загружаются до приведенной выше ошибки, и ошибка связана с использованием декоратора @InjectRepository() либо в AuthenticationController, либо в AdminController. Везде, где я смотрел, говорилось, что это потому, что мои объекты не загружаются, и я не уверен, как это возможно. Спасибо.
Ответ №1:
В моем случае у меня была ошибка в рабочем режиме, чтобы исправить ее, я добавил путь к скомпилированным JS-файлам в build
папке.
const conn: MongoConnectionOptions = {
type: 'mongodb',
url: DB_URL,
synchronize: true,
useNewUrlParser: true,
useUnifiedTopology: true,
logging: true,
entities: ['src/entity/*.ts', './build/src/entity/*.js'], // <- Here!
migrations: ['src/migration/**/*.ts'],
subscribers: ['src/subscriber/**/*.ts'],
cli: {
entitiesDir: 'src/entity',
migrationsDir: 'src/migration',
subscribersDir: 'src/subscriber',
},
extra: {
authSource: DB_AUTH_SOURCE,
},
};
Короткая версия может быть: entities: ['**/src/entity/*{.ts,.js}'],
Ответ №2:
Попробуйте присвоить имя вашему объекту с помощью декоратора @Entity:
import { Entity, PrimaryColumn, Column } from "typeorm";
@Entity("category") // <-- Right here
Комментарии:
1. Да .. это работает.
Ответ №3:
похоже, что это так, как вы сказали, потому что объекты не загружены.
я предполагаю: добавленный вами конфигурационный файл пытается найти файлы по адресу :
migrations: [__dirname '/migrations/**/*.ts'],
subscribers: [__dirname '/subscribers/**/*.ts'],
находятся ли эти файлы объектов в том же каталоге, что и модуль? может помочь распечатать выходные данные этих путей, чтобы убедиться, что они правильные.
также обратите внимание, что typescript компилируется в javascript, поэтому вы можете столкнуться с той же проблемой, если запустите код из / dist, потому что он сможет видеть только скомпилированные файлы «.js», поэтому я бы посоветовал использовать
migrations: [__dirname '/migrations/**/*{.ts,.js}'],
subscribers: [__dirname '/subscribers/**/*{.ts,.js}'],
если нет ничего из вышеперечисленных 2 вариантов, пожалуйста, укажите полные маршруты объектов и модулей в игре.
Ответ №4:
Я столкнулся с той же проблемой, глобальные пути не работают в случае monorepo
.
Однако обратите внимание, что глобальные пути не поддерживаются webpack, поэтому, если вы создаете свое приложение в monorepo, вы не сможете их использовать. Для решения этой проблемы предлагается альтернативное решение. Чтобы автоматически загружать объекты, установите свойство autoLoadEntities объекта конфигурации (передается в метод forRoot()).).
Обратите внимание, что объекты, которые не зарегистрированы с помощью метода Forforcature(), но на которые ссылаются только из объекта (через связь), не будут включены с помощью параметра autoLoadEntities.
Кроме того, я использовал ormconfig.ts
, что также представляет еще одну трудность —
Обратите внимание, что файл ormconfig.json загружается библиотекой typeorm. Таким образом, любое из дополнительных свойств, описанных выше (которые поддерживаются внутренне с помощью метода forRoot() — например, autoLoadEntities и retryDelay), применяться не будут. К счастью, TypeORM предоставляет функцию getConnectionOptions, которая считывает параметры подключения из файла ormconfig или переменных среды. При этом вы все равно можете использовать файл конфигурации и устанавливать параметры, зависящие от гнезда.
Окончательное решение
- корневой / основной модуль —
import { getConnectionOptions } from 'typeorm';
...
@Module({
imports: [
TypeOrmModule.forRootAsync({
useFactory: async () =>
Object.assign(await
getConnectionOptions(), {
autoLoadEntities: true,
}),
})
],
...
})
- приложение / дочерний модуль —
...
@Module({
imports: [TypeOrmModule.forFeature([<entities go here>])],
...
})
...
Комментарии:
1. Спасибо, это помогло мне. Я также использую monorepo.
Ответ №5:
В моем случае я решил это, объявив объект в файле подключения.
Документация TypeORM объясняет это изменение.
Создание подключения к базе данных
Теперь, когда наша сущность создана, давайте создадим файл index.ts (или app.ts, как вы его называете) и установим там наше соединение:
import "reflect-metadata";
import { createConnection } from "typeorm";
import { Photo } from "./entity/Photo";
createConnection({
type: "mysql",
host: "localhost",
port: 3306,
username: "root",
password: "admin",
database: "test",
entities: [
Photo
],
synchronize: true,
logging: false
}).then(connection => {
// here you can start to work with your entities
}).catch(error => console.log(error));
Ответ №6:
Убедитесь, что вы поставили знак @ перед вашим декоратором объекта (3 из моих объектов этого не сделали, и сообщение об ошибке было связано с отношениями, потому что оно не нашло мои объекты)
Ответ №7:
У меня была такая же проблема, и я добавил следующие свойства в свой ormconfig:
"cli":{
"migrationsDir":"./src/database/migrations",
"entitiesDir": ".src/modules/cars/entities"
},
"entities": [
"./src/modules/cars/entities/**/*{.ts,.js}"
]
Для меня все работает нормально.
Ответ №8:
При чтении исходного кода я понял, что строки все еще там (внутри пакета JS), поэтому он вызывает что-то, чего просто нет, поскольку все файлы находятся внутри него, я попытался импортировать модели непосредственно в app.module и не передавать строки или шаблоны в массив сущностей,но вместо этого импортированные классы сущностей сработали как шарм.
Учитывая, это может быть не самый чистый подход, потому что вам нужно записывать пути при импорте в разные модули и импортировать их один за другим. Было бы здорово посмотреть, что другие скажут о том, как решить и улучшить это, чтобы мы могли достичь более чистого решения.
Это работает сегодня по состоянию на ноябрь / 2021.
Ответ №9:
Также проверьте ваше соединение, если объекты есть entities: ['dist/**/*.entity.js']
, убедитесь, что ваше имя файла {name}.entity.ts
Ответ №10:
в базовом объекте вы не указали декоратор @Entity()
@Entity()
export class BaseEntity {
@Column()
created_at: Date;
}
Ответ №11:
В моем случае это было потому, что у меня был репозиторий внутри списка:
TypeOrmModule.forFeature([
TblX,
RepositoryX
]),
Удаление RepositoryX отсюда исправило это.
Ответ №12:
У меня все было правильно, кроме имени файла.
Это должно быть похоже entityname.entity.ts
Но это было похоже entityname.ts
Ответ №13:
Если все приведенные выше ответы не работают, вы можете просто очистить и перестроить dist
каталог, выполнив следующую команду
npm run build
Затем перезапустите приложение
npm run start:dev
Комментарии:
1. Это ничего не решит