I'm using TypeORM as a TypeScript ORM library, with a SQLite database.
I've got a TypeORM entity, called Photo
with a @OneToOne
relationship with another entity, called PhotoMetadata
.
Photo.ts
:
import {
Entity,
Column,
PrimaryGeneratedColumn,
OneToOne,
BaseEntity,
} from 'typeorm';
import PhotoMetadata from './PhotoMetadata';
@Entity()
export default class Photo extends BaseEntity {
@PrimaryGeneratedColumn()
public id: number;
@Column({ length: 100 })
public name: string;
@OneToOne(
() => PhotoMetadata,
(photoMetadata) => photoMetadata.photo,
{ cascade: true },
)
metadata: PhotoMetadata;
}
And here is PhotoMetadata.ts
:
import {
Entity,
Column,
PrimaryGeneratedColumn,
OneToOne,
JoinColumn,
} from 'typeorm';
import Photo from './Photo';
@Entity()
export default class PhotoMetadata {
@PrimaryGeneratedColumn()
id: number;
@Column()
ment: string;
@OneToOne(
() => Photo,
(photo) => photo.metadata,
)
@JoinColumn()
photo: Photo;
}
When I add a column to Photo
, like:
@Column({ nullable: true })
test: string;
Then run the app, with logging enabled, I get:
query: BEGIN TRANSACTION
query: SELECT * FROM "sqlite_master" WHERE "type" = 'table' AND "name" IN ('photo_metadata', 'photo', 'user')
query: SELECT * FROM "sqlite_master" WHERE "type" = 'index' AND "tbl_name" IN ('photo_metadata', 'photo', 'user')
query: PRAGMA table_info("user")
query: PRAGMA index_list("user")
query: PRAGMA foreign_key_list("user")
query: PRAGMA table_info("photo")
query: PRAGMA index_list("photo")
query: PRAGMA foreign_key_list("photo")
query: PRAGMA table_info("photo_metadata")
query: PRAGMA index_list("photo_metadata")
query: PRAGMA foreign_key_list("photo_metadata")
query: PRAGMA index_info("sqlite_autoindex_photo_metadata_1")
query: SELECT * FROM "sqlite_master" WHERE "type" = 'table' AND "name" = 'typeorm_metadata'
query: CREATE TABLE "temporary_photo_metadata" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "ment" varchar NOT NULL, "photoId" integer, CONSTRAINT "UQ_99f01ed52303cc16139d69f7464" UNIQUE ("photoId"), CONSTRAINT "FK_99f01ed52303cc16139d69f7464" FOREIGN KEY ("photoId") REFERENCES "photo" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION)
query: INSERT INTO "temporary_photo_metadata"("id", "ment", "photoId") SELECT "id", "ment", "photoId" FROM "photo_metadata"
query: DROP TABLE "photo_metadata"
query: ALTER TABLE "temporary_photo_metadata" RENAME TO "photo_metadata"
query: CREATE TABLE "temporary_photo" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(100) NOT NULL)
query: INSERT INTO "temporary_photo"("id", "name") SELECT "id", "name" FROM "photo"
query: DROP TABLE "photo"
query failed: DROP TABLE "photo"
error: [Error: SQLITE_CONSTRAINT: FOREIGN KEY constraint failed] {
errno: 19,
code: 'SQLITE_CONSTRAINT'
}
query: ROLLBACK
How can I fix this issue? It seems to fail dropping the Photo table that I modified, because of the foreign key.
I'm using TypeORM as a TypeScript ORM library, with a SQLite database.
I've got a TypeORM entity, called Photo
with a @OneToOne
relationship with another entity, called PhotoMetadata
.
Photo.ts
:
import {
Entity,
Column,
PrimaryGeneratedColumn,
OneToOne,
BaseEntity,
} from 'typeorm';
import PhotoMetadata from './PhotoMetadata';
@Entity()
export default class Photo extends BaseEntity {
@PrimaryGeneratedColumn()
public id: number;
@Column({ length: 100 })
public name: string;
@OneToOne(
() => PhotoMetadata,
(photoMetadata) => photoMetadata.photo,
{ cascade: true },
)
metadata: PhotoMetadata;
}
And here is PhotoMetadata.ts
:
import {
Entity,
Column,
PrimaryGeneratedColumn,
OneToOne,
JoinColumn,
} from 'typeorm';
import Photo from './Photo';
@Entity()
export default class PhotoMetadata {
@PrimaryGeneratedColumn()
id: number;
@Column()
ment: string;
@OneToOne(
() => Photo,
(photo) => photo.metadata,
)
@JoinColumn()
photo: Photo;
}
When I add a column to Photo
, like:
@Column({ nullable: true })
test: string;
Then run the app, with logging enabled, I get:
query: BEGIN TRANSACTION
query: SELECT * FROM "sqlite_master" WHERE "type" = 'table' AND "name" IN ('photo_metadata', 'photo', 'user')
query: SELECT * FROM "sqlite_master" WHERE "type" = 'index' AND "tbl_name" IN ('photo_metadata', 'photo', 'user')
query: PRAGMA table_info("user")
query: PRAGMA index_list("user")
query: PRAGMA foreign_key_list("user")
query: PRAGMA table_info("photo")
query: PRAGMA index_list("photo")
query: PRAGMA foreign_key_list("photo")
query: PRAGMA table_info("photo_metadata")
query: PRAGMA index_list("photo_metadata")
query: PRAGMA foreign_key_list("photo_metadata")
query: PRAGMA index_info("sqlite_autoindex_photo_metadata_1")
query: SELECT * FROM "sqlite_master" WHERE "type" = 'table' AND "name" = 'typeorm_metadata'
query: CREATE TABLE "temporary_photo_metadata" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "ment" varchar NOT NULL, "photoId" integer, CONSTRAINT "UQ_99f01ed52303cc16139d69f7464" UNIQUE ("photoId"), CONSTRAINT "FK_99f01ed52303cc16139d69f7464" FOREIGN KEY ("photoId") REFERENCES "photo" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION)
query: INSERT INTO "temporary_photo_metadata"("id", "ment", "photoId") SELECT "id", "ment", "photoId" FROM "photo_metadata"
query: DROP TABLE "photo_metadata"
query: ALTER TABLE "temporary_photo_metadata" RENAME TO "photo_metadata"
query: CREATE TABLE "temporary_photo" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(100) NOT NULL)
query: INSERT INTO "temporary_photo"("id", "name") SELECT "id", "name" FROM "photo"
query: DROP TABLE "photo"
query failed: DROP TABLE "photo"
error: [Error: SQLITE_CONSTRAINT: FOREIGN KEY constraint failed] {
errno: 19,
code: 'SQLITE_CONSTRAINT'
}
query: ROLLBACK
How can I fix this issue? It seems to fail dropping the Photo table that I modified, because of the foreign key.
Share Improve this question asked Mar 8, 2020 at 20:18 GaryGary 4,2418 gold badges41 silver badges64 bronze badges2 Answers
Reset to default 10I tried using TypeORM migrations to do this, but I encountered the same problem.
I then learned the following from this ment:
const connection = await createConnection();
await connection.query('PRAGMA foreign_keys=OFF');
await connection.synchronize();
await connection.query('PRAGMA foreign_keys=ON');
Or if you want to use migrations instead, then from this ment:
await connection.query("PRAGMA foreign_keys=OFF;");
await connection.runMigrations();
await connection.query("PRAGMA foreign_keys=ON;");
In either case, you need to set synchronize: false
in your ormconfig.json
.
The problem may occurs when you already have some data in your database and you add new Entities. I've tried the two solution here but didn't work. But one thing worked for me: just drop the Table before open a new connection (Open an connection, drop table, close connection, open another and do what u and to do). Example:
createConnection({
type: "sqlite",
database: "datateste.sqlite",
entities: [
User,
Auditory,
Goal,
Supervised,
Supervisor
],
synchronize: true,
logging: false}).then(async (e) => {
await e.dropDatabase()
await e.close()}).then(() => {
createConnection({
type: "sqlite",
database: "datateste.sqlite",
entities: [
User,
Auditory,
Goal,
Supervised,
Supervisor
],
synchronize: true,
logging: false
}).then(async connection => {
// here you do what you want
}).catch(error => console.log(error));
})