TypeORM

[解決]TypeORMでPostgreSQLのboolean型の列からデータを取得するとWindowsとLinuxで型が違う

本件解決いたしました。
結論から書くと、LinuxのPostgreSQLのis_two_factor_authentication_enabledがtext型、WindowsのPostgreSQLのis_two_factor_authentication_enabledがboolean型にしてしまっていました。

どうしてこうなったのかというと人為ミスです。
WindowsのPostgreSQLの定義をダンプして、Docker環境のPostgreSQLに流し込む…ということをしているのですが、Docker環境のPostgreSQLに一世代前のWindowsのPostgreSQLの定義を流し込んでおり、不一致が発生していました。



TypeORMでPostgreSQLのboolean型の列からデータを取得する場合、WindowsのPostgreSQLから取得した場合とLinuxのPostgreSQLで型が違いました。

擬似コードは以下のとおりです。
[Usersテーブルの定義抜粋]
@Entity()
export class Users {
  @Column({ type: "boolean", default: false })
  @Exclude()
  is_two_factor_authentication_enabled: boolean;
[確認コード抜粋]
let usersRepository: Repository;
usersRepository = getRepository(Users);

    const userDataFromDB = await usersRepository.findOne({
      where: {
        id: testUserId,
      },
    });
    console.log(typeof userDataFromDB.is_two_factor_authentication_enabled);
[出力]
接続先がWindowsで動かしているのPostgreSQLの場合
  ● Console

    console.log
      boolean
接続先がLinuxで動かしているのPostgreSQLの場合
  ● Console

    console.log
      string
なぜ違うのでしょうか…booleanで返ってきて欲しい…

NestJS + TypeORM + PostgreSQLにおけるTypeORMの設定のentitiesの設定について

NestJS + TypeORM + PostgreSQLにおけるTypeORMの設定のentitiesの設定について、サーバーを起動する場合と、npm run testでテストする場合とで、設定をかえないといけないです。
※ぐぐると、entitiesの設定についてはまっている方が多いけど、いまいちしゃきっとした回答が見つかりませんでした。自分もいろいろ試行錯誤した結果、下に書いた内容に行き着いたのですが、どうしてそうなるのかをちゃんと説明できない(調べられない)です。分かる方にご教示頂きたいです…

[困ったこと]
NestJS + TypeORM + PostgreSQLの構成でサーバーは問題なく起動し、リクエストに対してレスポンスを返すのですが、npm run test(Jestによるテスト)をすると以下のエラーが発生しテストが失敗する。
    RepositoryNotFoundError: No repository for "Users" was found. Looks like this entity is not registered in current "default" connection?

[TypeORMの設定]
app.module.tsで
@Module({
  imports: [
    TypeOrmModule.forRoot(),
    TypeOrmModule.forFeature([Users]),
  ],
とし、ルートディレクトリにormconfig.jsonを配置した。
ormconfig.jsonの内容は以下のとおり。
{
  "name": "default",
  "type": "postgres",
  "host": "localhost",
  "port": 5432,
  "username": "postgres",
  "password": "postgres",
  "database": "pong",
  "entities": ["dist/entities/**/*.entity.js"],
  "migrations": ["dist/migrations/**/*.js"],
  "logging": false,
  "synchronize": false
}

[解決方法]
npm run test(Jestによるテスト)の場合は、entitiesを以下のように設定する。
["./src/entities/**/*.entity.ts"]
具体的には、spec.tsファイルを以下のように書いた。
describe("AppController", () => {
  let appController: AppController;
  let app: TestingModule;

  beforeAll(async () => {
    app = await Test.createTestingModule({
      imports: [
        TypeOrmModule.forRoot(),
        TypeOrmModule.forRootAsync({
          useFactory: async () =>
            Object.assign(await getConnectionOptions(), {
              entities: getEntites(),
            }),
        }),
        TypeOrmModule.forFeature([Users]),
      ],
(中略)
    }).compile();

    appController = app.get(AppController);
  });

  afterAll(() => app.close());

getEntites()の内容は以下のとおり。
export function getEntites() {
  return ["./src/entities/**/*.entity.ts"];
}

[考えたこと]
  "entities": ["dist/entities/**/*.entity.js"],
と設定して、Jestでテストをしようとすると
RepositoryNotFoundError: No repository for "Users" was found. Looks like this entity is not registered in current "default" connection?
となる。
  "entities": ["./src/entities/**/*.entity.ts"],
と設定して、npm run start:devすると
[Nest] 17012  - 2021/12/08 16:53:42   ERROR [TypeOrmModule] Unable to connect to the database. Retrying (1)...
D:\42\ft_transcendence\github\pong\server\src\entities\accomplishes.entity.ts:1
import {
^^^^^^

SyntaxError: Cannot use import statement outside a module
となる。 以上から、NestJSはコンパイルされたJavaScriptで動作するので、TypeORMに読み込ませるEntityの情報はJavaScript(.js)でなければならない(importがSyntaxErrorになる)のに対して、Jestでテストをする場合、テストファイルはTypeScriptで書かれているものをJestがトランスコンパイルして生成されたJavascriptで動作するので、TypeORMに読み込ませるEntityの情報は(おそらく依存関係の解決のために)TypeScript(.ts)でなければならない(dist/entities/*/.entity.jsを読み込んでくれない?)のだと思います、たぶん… ちゃんとした理由をご存知でしたらご教示頂きたいです。

[試験環境]
https://github.com/hiroin/typeorm-setting-entities

TypeORMの@ManyToOneで設定する列にNOT NULL制約を追加する

TypeORMの@ManyToOneで設定する列にNOT NULL制約を追加する
  @ManyToOne(() => Users, (user) => user.directMessage_from, {
    nullable: false,
  })

Screenshot_1

の赤字の部分をTypeORMで表現すると、
  @ManyToOne(() => Users, (user) => user.directMessage_from, })
  @JoinColumn({ name: "user_from_id" })
  user_from_id: Users;

  @ManyToOne(() => Users, (user) => user.directMessage_to)
  @JoinColumn({ name: "user_to_id" })
  user_to_id: Users;
となる。
これを反映すると、
pong=# \d direct_messages
                                          テーブル "public.direct_messages"
      列      |             型              | 照合順序 | Null 値を許容 |
           デフォルト
--------------+-----------------------------+----------+---------------+---------------------------------------------
 id           | integer                     |          | not null      | nextval('direct_messages_id_seq'::regclass)
 message      | text                        |          | not null      |
 created_at   | timestamp without time zone |          | not null      | now()
 user_from_id | integer                     |          |               |
 user_to_id   | integer                     |          |               |
と、user_from_id列とuser_to_id列にNOT NULL制約が設定されない。
NOT NULL制約を追加するには以下のように記述する。
  @ManyToOne(() => Users, (user) => user.directMessage_from, {
    nullable: false,
  })
  @JoinColumn({ name: "user_from_id" })
  user_from_id: Users;

  @ManyToOne(() => Users, (user) => user.directMessage_to, { nullable: false })
  @JoinColumn({ name: "user_to_id" })
  user_to_id: Users;
pong=# \d direct_messages
                                          テーブル "public.direct_messages"
      列      |             型              | 照合順序 | Null 値を許容 |
           デフォルト
--------------+-----------------------------+----------+---------------+---------------------------------------------
 id           | integer                     |          | not null      | nextval('direct_messages_id_seq'::regclass)
 message      | text                        |          | not null      |
 created_at   | timestamp without time zone |          | not null      | now()
 user_from_id | integer                     |          | not null      |
 user_to_id   | integer                     |          | not null      |
※マニュアルに書いてないと思うのですが…、みなさんどのように見つけてくるのでしょうか…
自分は「@manytoone not null typeorm」でぐぐって、「How to save entity with ManyToOne with nullable: false set? · Issue #3229 · typeorm/typeorm」を見て、なるほど…、そのように設定方法があるのか…と分かったのですが…

記事検索