Domande Frequenti
Questa pagina è stata tradotta da PageTurner AI (beta). Non ufficialmente approvata dal progetto. Hai trovato un errore? Segnala problema →
Come aggiorno lo schema del database?
Una delle principali responsabilità di TypeORM è mantenere le tabelle del database sincronizzate con le entità. Esistono due approcci per raggiungere questo obiettivo:
-
Utilizza
synchronize: truenelle opzioni del data source:import { DataSource } from "typeorm"
const myDataSource = new DataSource({
// ...
synchronize: true,
})Questa opzione sincronizza automaticamente le tabelle del database con le entità specificate ogni volta che viene eseguito il codice. È ideale durante lo sviluppo, ma in produzione si consiglia di disabilitarla.
-
Utilizza gli strumenti da riga di comando ed esegui manualmente la sincronizzazione dello schema:
typeorm schema:syncQuesto comando eseguirà la sincronizzazione dello schema.
La sincronizzazione dello schema è estremamente veloce. Se stai valutando di disattivare l'opzione synchronize durante lo sviluppo per problemi di prestazioni, verifica prima quanto è rapida.
Come modifico il nome di una colonna nel database?
Per impostazione predefinita, i nomi delle colonne derivano dai nomi delle proprietà.
Puoi modificarli specificando l'opzione name nella colonna:
@Column({ name: "is_active" })
isActive: boolean;
Come posso impostare un valore predefinito con una funzione, ad esempio NOW()?
L'opzione default della colonna supporta funzioni.
Se passi una funzione che restituisce una stringa,
verrà utilizzata come valore predefinito senza escape. Esempio:
@Column({ default: () => "NOW()" })
date: Date;
Come effettuare la validazione?
La validazione non fa parte di TypeORM perché è un processo separato, non direttamente correlato alle sue funzionalità. Per la validazione utilizza class-validator - funziona perfettamente con TypeORM.
Cosa significa "lato proprietario" nelle relazioni o perché usare @JoinColumn e @JoinTable?
Partiamo da una relazione one-to-one.
Supponiamo due entità: User e Photo:
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number
@Column()
name: string
@OneToOne()
photo: Photo
}
@Entity()
export class Photo {
@PrimaryGeneratedColumn()
id: number
@Column()
url: string
@OneToOne()
user: User
}
Questo esempio manca di @JoinColumn, il che è errato.
Perché? Per stabilire una relazione reale, dobbiamo creare una colonna nel database.
Dobbiamo creare userId in photo o photoId in user.
Ma quale colonna creare - userId o photoId? TypeORM non può decidere per te.
Per risolvere, usa @JoinColumn su uno dei due lati:
- Se aggiungi
@JoinColumninPhoto, verrà creatauserIdnella tabellaphoto. - Se aggiungi
@JoinColumninUser, verrà creataphotoIdnella tabellauser. Il lato con@JoinColumnè chiamato "lato proprietario della relazione". L'altro lato, senza@JoinColumn, è il "lato inverso (non proprietario) della relazione".
Vale lo stesso per le relazioni @ManyToMany: usa @JoinTable per indicare il lato proprietario.
Nelle relazioni @ManyToOne o @OneToMany, @JoinColumn non è necessario perché
i decoratori sono diversi e la tabella con @ManyToOne conterrà già la colonna relazionale.
I decoratori @JoinColumn e @JoinTable possono anche specificare impostazioni aggiuntive
come nomi di colonne join o nomi di tabelle di giunzione.
Come aggiungere colonne extra in una tabella many-to-many (di giunzione)?
Non è possibile aggiungere colonne extra in tabelle create da relazioni many-to-many. Dovrai creare un'entità separata e collegarla tramite due relazioni many-to-one con le entità target (l'effetto sarà equivalente a una tabella many-to-many), aggiungendo le colonne extra lì. Maggiori dettagli in Relazioni Many-to-Many.
Come gestire l'opzione del compilatore TypeScript outDir?
Quando utilizzi l'opzione del compilatore outDir, non dimenticare di copiare nella directory di output asset e risorse utilizzate dalla tua applicazione.
In alternativa, assicurati di configurare i percorsi corretti per questi asset.
Un aspetto importante da sapere è che quando rimuovi o sposti entità, le vecchie entità rimangono intatte nella directory di output.
Ad esempio, crei un'entità Post e la rinomini in Blog,
non avrai più Post.ts nel tuo progetto. Tuttavia, Post.js rimane nella directory di output.
Ora, quando TypeORM legge le entità dalla tua directory di output, vede due entità: Post e Blog.
Questo può causare bug.
Ecco perché quando rimuovi o sposti entità con outDir attivata, è fortemente consigliato eliminare la directory di output e ricompilare nuovamente il progetto.
Come usare TypeORM con ts-node?
Puoi evitare di compilare i file ogni volta usando ts-node.
Se usi ts-node, puoi specificare entità ts nelle opzioni del data source:
{
entities: [__dirname + "/entities/**/*{.js,.ts}"],
subscribers: [__dirname + "/subscribers/**/*{.js,.ts}"]
}
Inoltre, se stai compilando file js nella stessa cartella dei tuoi file TypeScript,
assicurati di usare l'opzione del compilatore outDir per prevenire
questo problema.
Se preferisci usare la CLI di ts-node, puoi eseguire TypeORM così:
npx typeorm-ts-node-commonjs schema:sync
Per progetti ESM usa invece:
npx typeorm-ts-node-esm schema:sync
Come usare Webpack per il backend?
Webpack genera avvisi a causa di quelli che considera require mancanti - i require per tutti i driver supportati da TypeORM. Per sopprimere questi avvisi per driver inutilizzati, modifica il tuo file di configurazione Webpack.
const FilterWarningsPlugin = require('webpack-filter-warnings-plugin');
module.exports = {
...
plugins: [
// ignore the drivers you don't want. This is the complete list of all drivers -- remove the suppressions for drivers you want to use.
new FilterWarningsPlugin({
exclude: [/mongodb/, /mssql/, /mysql2/, /oracledb/, /pg/, /pg-native/, /pg-query-stream/, /react-native-sqlite-storage/, /redis/, /sqlite3/, /sql.js/, /typeorm-aurora-data-api-driver/]
})
]
};
Bundling dei File di Migrazione
Per default Webpack prova a creare un singolo file bundle. Questo può essere problematico quando il progetto contiene file di migrazione destinati a essere eseguiti dopo il deploy in produzione del codice bundled. Per assicurarti che tutte le tue migrazioni siano riconosciute ed eseguite da TypeORM, potresti dover usare la "Object Syntax" per la configurazione entry solo per i file di migrazione.
const { globSync } = require("node:fs")
const path = require("node:path")
module.exports = {
// ... your webpack configurations here...
// Dynamically generate a `{ [name]: sourceFileName }` map for the `entry` option
// change `src/db/migrations` to the relative path to your migrations folder
entry: globSync(path.resolve("src/db/migrations/*.ts")).reduce(
(entries, filename) => {
const migrationName = path.basename(filename, ".ts")
return Object.assign({}, entries, {
[migrationName]: filename,
})
},
{},
),
resolve: {
// assuming all your migration files are written in TypeScript
extensions: [".ts"],
},
output: {
// change `path` to where you want to put transpiled migration files.
path: __dirname + "/dist/db/migrations",
// this is important - we want UMD (Universal Module Definition) for migration files.
libraryTarget: "umd",
filename: "[name].js",
},
}
Inoltre, da Webpack 4, quando usi mode: 'production', i file vengono ottimizzati di default con tecniche che includono l'offuscamento del codice per ridurre le dimensioni. Questo rompe le migrazioni perché TypeORM si basa sui nomi per determinare quali sono già state eseguite. Puoi disabilitare completamente la minimizzazione aggiungendo:
module.exports = {
// ... other Webpack configurations here
optimization: {
minimize: false,
},
}
In alternativa, se usi UglifyJsPlugin, puoi dirgli di non modificare nomi di classi o funzioni così:
const UglifyJsPlugin = require("uglifyjs-webpack-plugin")
module.exports = {
// ... other Webpack configurations here
optimization: {
minimizer: [
new UglifyJsPlugin({
uglifyOptions: {
keep_classnames: true,
keep_fnames: true,
},
}),
],
},
}
Infine, assicurati che nelle opzioni del data source siano inclusi i file di migrazione transpilati:
// TypeORM Configurations
module.exports = {
// ...
migrations: [__dirname + "/migrations/**/*{.js,.ts}"],
}
Come usare TypeORM in progetti ESM?
Assicurati di aggiungere "type": "module" nel package.json del tuo progetto così TypeORM saprà di usare import( ... ) per i file.
Per evitare problemi di dipendenze circolari nelle importazioni, usa il tipo wrapper Relation per le definizioni dei tipi di relazione nelle entità:
@Entity()
export class User {
@OneToOne(() => Profile, (profile) => profile.user)
profile: Relation<Profile>
}
Questo impedisce che il tipo della proprietà venga salvato nei metadati nel codice transpilato, prevenendo problemi di dipendenze circolari.
Poiché il tipo della colonna è già definito usando il decoratore @OneToOne, non è utile il metadato aggiuntivo salvato da TypeScript.
Importante: Non usare
Relationsu tipi di colonna non relazionali