-
Notifications
You must be signed in to change notification settings - Fork 674
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
🚀 Feature Request: Allow turning off foreign key check while migrating database. #5438
Comments
Hi, is there anyone reading this issue? |
Hi @aperture147, my apologies. I'm looking into this exact issue as part of #5683. Will make a record to update this issue once I have a resolution. |
Thanks. It would be nice to have |
Just want to add to this that this is indeed very annoying. Any changes to a table that requires recreating it will cascade to other referenced tables. I cannot make the required changes to my database atm.. (at least not trivially) |
I kept running into various errors trying something similar (foreign key constraint failed, LLVM syntax errors). I noticed @aperture147's second example is backwards. PRAGMA defer_foreign_keys = ON;
CREATE TABLE ...
PRAGMA defer_foreign_keys = OFF; Doing it exactly like this worked for me. Hope this helps. Not sure exactly where my issue was. Possible causes:
Docs are a bit messy as far as this goes; one page uses |
Does not work for me. Rows are still deleted or set to edit: this is my migration file btw PRAGMA defer_foreign_keys = ON;
--> statement-breakpoint
DROP INDEX `user_email_idx`;
--> statement-breakpoint
DROP INDEX `user_public_idx`;
--> statement-breakpoint
CREATE TABLE `new_user` (
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
`public_id` text NOT NULL,
`first_name` text NOT NULL,
`last_name` text NOT NULL,
`email` text NOT NULL,
`verified` integer NOT NULL,
`created_at` text NOT NULL,
`updated_at` text NOT NULL,
`deleted_at` text
);
--> statement-breakpoint
INSERT INTO `new_user` (`id`, `public_id`, `first_name`, `last_name`, `email`, `verified`, `created_at`, `updated_at`, `deleted_at`)
SELECT `id`, `public_id`, `first_name`, `last_name`, `email`, `verified`, `created_at`, `updated_at`, `deleted_at`
FROM `user`;
--> statement-breakpoint
DROP TABLE `user`;
--> statement-breakpoint
ALTER TABLE `new_user` RENAME TO `user`;
--> statement-breakpoint
UPDATE sqlite_sequence SET seq = (SELECT MAX(ID) FROM `user`) WHERE name = 'user';
--> statement-breakpoint
CREATE UNIQUE INDEX `user_public_idx` ON `user` (`public_id`);
--> statement-breakpoint
CREATE UNIQUE INDEX `user_email_idx` ON `user` (`email`);
--> statement-breakpoint
PRAGMA defer_foreign_keys = OFF;
--> statement-breakpoint edit 2: |
Hi, sorry for the wrong example. I've corrected the original example. Actually I've tried It seems like |
To be honest, I'd probably rather mark that as a bug - I almost lost data today due to a migration silently setting those values to NULL 😬 |
Hi, are there any updates on this? As far as I understand current workaround is to copy all related tables affected by |
Some table altering tasks in SQLite cannot be achieved without replacing it with a new table (by dropping - recreating the table) (like adding foreign keys, changing primary keys, updating column type). Dropping a table which has column referenced by other tables with
ON DELETE CASCADE
will delete all records of the child tables.Example:
Assume that we have Table A and B. Table B has column
a_id
referencing (ON DELETE CASCADE
) table A primary keyid
. For some reason I have to modify Table A by dropping and recreating table A (with original value), ALL records from table B are deleted by cascading.I'm trying to find a workaround for this situation as mentioned in this sqlx issue and some suggestion from Matt in Discord, but none of them work:
PRAGMA foreign_keys = OFF;
andPRAGMA foreign_keys = ON;
:PRAGMA defer_foreign_keys = OFF;
andPRAGMA defer_foreign_keys = ON;
:The workaround
1
and2
completed but all records in table B is still deleted. The workaround3
threw and error like this:Currently I have to copy data from table B to a temporally table then reinsert it to table B later.
This is a huge problem when I could have table B1, B2, B3 and more, all of them reference to table A, each table contains a few hundred thousands of records and more important, table B1, B2, B3 could be referenced from other tables too. This is really inefficient since it would definitely make a hit to billing metrics and might impact the traffic and make a migration takes longer to finish (which might affect the traffic to my D1).
Will there be a feature address this situation or is there any existing solution?
The text was updated successfully, but these errors were encountered: