最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - With TypeORM, `SQLITE_CONSTRAINT: FOREIGN KEY constraint failed` when adding a column to an entity - Stack Overflow

programmeradmin3浏览0评论

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 badges
Add a ment  | 

2 Answers 2

Reset to default 10

I 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));

})

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论