少しハマりましたが、解決したので備忘録として解決方法を書いておきます。
開発環境+バージョン情報
Expo: SDK40
expo-cli: 4.0.17
TypeORM: 0.2.28
(expo-sqliteをドライバーに設定)
概要
原因
Development Mode時とProduction Mode時では、暗黙的に割り振られるエイリアスが異なるため、テーブルを正常に参照できなくなっていた。
解決方法
createQueryBuilderを利用する際は、エイリアス名を明確に設定しましょう。
問題の背景
日付(date)と日記の本文(report)のカラムを持つ日記(diary)エンティティーを定義し、
diary.ts
import { PrimaryColumn, Entity, Column, CreateDateColumn, UpdateDateColumn } from 'typeorm';
@Entity('diary')
export class Diary {
@PrimaryColumn('integer')
date: number;
@Column('text')
report: string;
constructor(date: number, report:string) {
this.date = date;
this.report = report;
}
}
BETWEEN句で指定した、日付間の日記を取得するクエリを定義していました。
getDiary.ts
import { getRepository } from 'typeorm';
import { Diary } from './entities/diary';
const dateFrom = 20201201;
const dateTo = 20210101;
const diaryRepository = getRepository(Diary);
.createQueryBuilder()
.where('diary.dateData BETWEEN :dateFrom AND :dateTo', {
dateFrom,
dateTo,
})
.getMany();
この定義で生成されるSQLはDevelopment Mode時は下記のような感じ
develop.sql
select
diary.date
,diary.report
from
diary diary
where
diary.diary between 20201201 and 20210101
しかしProduction Modeでは、ビルド時のサイズ縮小化によりDevelopment Mode時とは異なるエイリアス名が指定されており、案の定クエリは正常に動きません。
production.sql
select
diary.date
,diary.report
from
diary d <- ここのエイリアス名がdに省略されている!
where
diary.diary between 20201201 and 20210101
そこでcreateQueryBuilderにエイリアス名を明確に指定することで解決しました。
getDiary.ts
import { getRepository } from 'typeorm';
import { Diary } from './entities/diary';
const dateFrom = 20201201;
const dateTo = 20210101;
const diaryRepository = getRepository(Diary);
.createQueryBuilder('diary') // エイリアス名を明確に指定
.where('diary.dateData BETWEEN :dateFrom AND :dateTo', {
dateFrom,
dateTo,
})
.getMany();
後書き
パフォーマンスの検証を後回しにしていたため、Development Mode→apkファイルのビルドを行ってしまい、インストールしたアプリが動かず少し焦りました。
何事も抜け漏れのない動作確認が必要だと感じた課題でした。