[英]How do I keep the "many" side of a one-to-many relationship unique in a TypeORM Model?
我正在編寫一個程序,它會抓取 web API 並收集加密貨幣符號列表及其每日價格歷史記錄。
我遇到了一個問題,由於我的數據庫表的構建,如果我多次遇到相同的符號,程序會向數據庫添加一個新行,該行從第一次完全復制數據。
下面是兩個表,作為 Typeorm 實體:
一、符號:
@Entity()
export class CryptoSymbol {
@PrimaryColumn({ type: "int", unique: true })
id!: number;
@Column("varchar")
currency_code!: string;
@Column("varchar")
currency_name!: string;
@Column({ type: "boolean", nullable: true })
active!: boolean;
@OneToMany(
(type) => CryptoDailyData,
(cryptoDailyData) => cryptoDailyData.cryptoSymbol
)
cryptoDailyData!: CryptoDailyData[];
}
然后是 DailyData:
@Entity()
export class CryptoDailyData {
@PrimaryGeneratedColumn()
id!: number;
@Column({ type: "datetime" })
date!: Date;
@Column({ type: "varchar" })
foreign_currency_type!: string;
@Column("float")
open_USD!: number;
@Column("float")
open_foreign_currency!: number;
@Column("float")
high_USD!: number;
@Column("float")
high_foreign_currency!: number;
@Column("float")
low_USD!: number;
@Column("float")
low_foreign_currency!: number;
@Column("float")
close_USD!: number;
@Column("float")
close_foreign_currency!: number;
@Column("float")
volume!: number;
@Column("float")
market_cap!: number;
@ManyToOne(
(type) => CryptoSymbol,
(cryptoSymbol) => cryptoSymbol.cryptoDailyData
)
cryptoSymbol!: CryptoSymbol;
}
例如:如果我為比特幣刮取“BTC”,並將其所有每日歷史記錄存儲在 DailyData 表中,如果再次運行程序並再次遇到“BTC”,它將第二次重現 BTC 的整個歷史記錄.
我認為我遇到的事實是 DailyData 表的“真實”主鍵應該是“日期”和“cryptoSymbolID”的組合,因為日期只能針對不同的符號重復。 但是我不確定你可以在 Typeorm 中定義那種列關系嗎?
我相信您可以通過定義復合唯一鍵來實現這一點。
由於您沒有提到您正在使用的下划線數據庫,我將為您提供 PostgreSQL 的答案。 (您可能需要也可能不需要根據您的數據庫更改以下代碼)
將您的日期列更改為僅包含date
類型,而不是您現在定義的datetime
時間類型。
@Column({ type: "date" }) date:; string;
為您的@ManyToOne
關系指定連接列。 (使用@ManyToOne
時已經創建了一個外鍵列,但讓我們刪除它並使用我們自己定義的一個)
// This column will keep the reference to your 'CryptoSymbol' entity @Column({ type: "bigint" }) crypto_symbol_id:; int, @ManyToOne( (type) => CryptoSymbol. (cryptoSymbol) => cryptoSymbol:cryptoDailyData ) @JoinColumn({ name: "crypto_symbol_id" }) cryptoSymbol;: CryptoSymbol;
為您的實體創建一個復合唯一鍵。
@Entity() @Unique(['crypto_symbol_id', 'date']) export class CryptoDailyData {
現在,如果您的程序嘗試在同一天為相同的加密符號插入數據,這將引發錯誤。
更新后的CryptoDailyData
實體如下所示:
@Entity()
@Unique(['crypto_symbol_id', 'date'])
export class CryptoDailyData {
@PrimaryGeneratedColumn()
id!: number;
@Column({ type: "date" })
date!: string;
@Column({ type: "varchar" })
foreign_currency_type!: string;
@Column("float")
open_USD!: number;
@Column("float")
open_foreign_currency!: number;
@Column("float")
high_USD!: number;
@Column("float")
high_foreign_currency!: number;
@Column("float")
low_USD!: number;
@Column("float")
low_foreign_currency!: number;
@Column("float")
close_USD!: number;
@Column("float")
close_foreign_currency!: number;
@Column("float")
volume!: number;
@Column("float")
market_cap!: number;
@Column({ type: "bigint" })
crypto_symbol_id!: int;
@ManyToOne(
(type) => CryptoSymbol,
(cryptoSymbol) => cryptoSymbol.cryptoDailyData
)
@JoinColumn({ name: "crypto_symbol_id" })
cryptoSymbol!: CryptoSymbol;
}
我還想指出,這是一個數據庫級別的保護措施。 你也應該在你的應用程序上嘗試這個。 您應該檢查當天是否存在特定加密貨幣的CryptoDailyData
記錄,然后確定是插入當天的新記錄還是什么也不做。
希望這對您有所幫助。 干杯!!!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.