I'm working on a Rails web application with a MySQL database. I'm using migrations to modify the schema. I've just run into a problem wherein I'm getting an invalid record error on inserting a new record. The relevant tables:
users
id | name | email | ...
academic_records
id | scholar_id | gpa | ...
academic_records.scholar_id is a foreign key reference to users.id, but I haven't placed any other constraints on that table. The error looks like this:
Mysql::Error: Cannot add or update a child row: a foreign key constraint fails
(`my_db`.`academic_records`, CONSTRAINT `academic_records_ibfk_1`
FOREIGN KEY (`id`) REFERENCES `academic_records` (`id`) ON DELETE CASCADE): ...
I opened up the MySQL database using Sequel Pro and found this constraint:
CREATE TABLE `academic_records` (
`gpa` varchar(10) DEFAULT NULL,
...
PRIMARY KEY (`id`),
KEY `index_academic_records_on_scholar_id` (`scholar_id`),
CONSTRAINT `academic_records_ibfk_1` FOREIGN KEY (`id`)
REFERENCES `academic_records` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=177 DEFAULT CHARSET=utf8;
I have no idea how it got there or what it does. Why would the table have a foreign key from its own ID to itself? Can I remove the constraint? If so, how? I could see why I would want to cascade deletes from users.id to academic_records.scholar_id, but as-is, it makes no sense to me.
Check your migration files to see if the constraint was created there, or perhaps your project is using some plugin or RubyGem that does something with database constraints. If both of those areas turn up blanks then it must have been created by hand or by an external SQL script.
Rails doesn't generate or use database constraints to enforce model relationships. Database referential integrity is something you have to add yourself if you want it.
I don't see any reason why you can't drop this constraint using:
mysql> ALTER TABLE academic_records DROP FOREIGN KEY `academic_records_ibfk_1`;
This kind of thing is not possible through Rails migrations using the DSL ... however, that doesn't stop people from creating a foreign key manually, or using an execute("SQL HERE") in your migration.
As I am unfamiliar with MySQL's syntax your best reference is the MySQL documentation - particularly DROP CONSTRAINT.
Why it references itself ... I have no idea, time to ask your colleagues?
Related
The list of foreign keys is empty for one of my tables in MySql Workbench. When I try to add the missing FK's I get an error of this structure:
Executing:
ALTER TABLE <schema>.<table>
ADD INDEX <index_name> (<column_name> ASC);
ALTER TABLE <schema>.<table_name>
ADD CONSTRAINT <constraint_name>
FOREIGN KEY (<column_name>)
REFERENCES <schema>.<ref_table_name> (<ref_column_name>)
ON DELETE CASCADE
ON UPDATE CASCADE;
Operation failed: There was an error while applying the SQL script to the database.
ERROR 1452: Cannot add or update a child row: a foreign key constraint fails (<schema>.`#sql-49f_6`, CONSTRAINT <constraint_name> FOREIGN KEY (<column_name>) REFERENCES <ref_table_name> (<ref_column_name>) ON DELETE CASCADE ON UPDATE CASCADE)
SQL Statement:
ALTER TABLE <schema>.<table_name>
ADD CONSTRAINT <constraint_name>
FOREIGN KEY (<column_name>)
REFERENCES <schema>.<ref_table_name> (<ref_column_name>)
ON DELETE CASCADE
ON UPDATE CASCADE
Obviously, the foreign key I am trying to create seems to be in the database already. Some research on the web lead me to believe that in some cases MySql Workbench does not list all foreign keys (for various reasons), which might be true for my setup as well. Thus, I tried listing all foreign keys on the table I am trying modify using this query:
SELECT *
FROM
information_schema.KEY_COLUMN_USAGE
WHERE
constraint_schema = <schema> AND table_name = <table_name> AND
referenced_table_name IS NOT NULL;
The result set is as empty as the Workbench foreign key list...
Looking at the error message I seem to have a weird table sitting around my database named #sql-49f_6.
This table was not explicitely created by me.
That said, I am using sqlalchemy to create and manage my database, so all might be due to the sqlalchemy model definition, which looks like this:
TableName = Table(<table_name>,
table_base.metadata,
Column(
<column_name_1>,
Integer(),
ForeignKey('<ref_table_name>.<ref_column_name>', onupdate='CASCADE', ondelete='CASCADE'),
nullable=False
),
Column(
<column_name_2>,
Integer(),
ForeignKey('<ref_table_name_2>.<ref_column_name_2>', onupdate='CASCADE', ondelete='CASCADE'),
nullable=False
)
)
With all of the above, can anyone suggest a solution?
Preferably without having to recreate the database; because, I need to maintain the data contained by the table.
I wasn't able to find the origin of the issue described above.
In need of a solution, I temporarily stored the data contained by the problematic table offline and recreated it from scratch. In this step I also added in the foreign key missing. The issue did not persist. Sorry I cannot shed light on what went wrong initially.
I want to assign foreign key(email) references user(email), but It shows error. I cant figure out what is wrong.
ERROR 1005: Can't create table 'schema.#sql-1bf8_f' (errno: 121)
SQL Statement:
ALTER TABLE `schema`.`vendor_ambassador`
ADD CONSTRAINT `email`
FOREIGN KEY (`email`)
REFERENCES `schema`.`user` (`email`)
ON DELETE NO ACTION
ON UPDATE NO ACTION
I've have the same problem. These were my steps to resolve this problem:
Check if master table are created first.
Check the primary key on the master table are implemented and indexes are created.
Check data type within related column on master and detail table are same.
Ensure that column on foreign key in detail table are not set into primary key.
Check the foreign key or constraint name on other tables within database. The foreign key or constraint name should be unique.
If this doesn't help, check using MySQL Command: Show innodb engine status; to read the problems.
I hope this solves your problem.
I use MySQL with InnoDB engine. I double-checked type of columns. But always have:
Error Code: 1215. Cannot add foreign key constraint
I tried:
ALTER TABLE `mail`.`boxes`
ADD CONSTRAINT FK_id
FOREIGN KEY (id)
REFERENCES `mail`.`users` (id)
ON UPDATE NO ACTION
ON DELETE NO ACTION;
and
ALTER TABLE `mail`.`boxes`
ADD FOREIGN KEY (id)
REFERENCES `mail`.`users` (id)
Nothing works(((
Please, help, what I am doing wrong (except choosing MySQL :-) )?
If table contains data then you are not able to add foreign key you drop table object and recreate
use below reference for the same
Basics of Foreign Keys in MySQL?
To check what exactly the problem is, use:
SHOW ENGINE INNODB STATUS\G
There is section "last foreign key error". Look at: http://dev.mysql.com/doc/refman/5.0/en/innodb-monitors.html
My guess is that data type od mail.boxes (id) and mail.users (id) is not the same. (E.g. smallint in one table and integer in second one).
Data in table on which you're trying to create FK could possibly also be problem (are your mailbox ids the same as id of existing users?)
MySQL Workbench came up with the following SQL to create a table:
CREATE TABLE IF NOT EXISTS `mydb`.`errors_reports` (
`error_id` INT NOT NULL ,
`report_short` VARCHAR(15) NOT NULL ,
PRIMARY KEY (`error_id`, `report_short`) ,
INDEX `error_id_idx` (`error_id` ASC) ,
INDEX `report_short_idx` (`report_short` ASC) ,
CONSTRAINT `error_id`
FOREIGN KEY (`error_id` )
REFERENCES `mydb`.`errors` (`error_id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `report_short`
FOREIGN KEY (`report_short` )
REFERENCES `mydb`.`reports` (`report_short` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB
which looks fine to me, and there are a bunch of other very similar tables in my database which MySQL was perfectly happy to create.
But this one...
ERROR 1022 (23000): Can't write; duplicate key in table 'errors_reports'
I can't for the life of me see any duplicate keys here. There's only one key defined!
I'm running MySQL 5.6 with a fresh default install. There's nothing in the error log.
Ideas?
Edit: through a process of elimination (going back to the simplest possible definition of the table, then gradually adding bits back in) the problem appears to be this bit:
CONSTRAINT `error_id`
FOREIGN KEY (`error_id` )
REFERENCES `mydb`.`errors` (`error_id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION,
which is particularly odd as there is identical code in several other table definitions and those are perfectly okay!
The problem is that the name of a foreign key can not be the same as another foreign key in the entire model.
Imagine this situation
Catalog --> Supplier
Product --> Supplier
if the name of the foreign key in table Catalog for supplier is "supplier" and you assigned the same name in product table then the foreign keys names will "collide".
You need to name them differently..
For example:
catalog_supplier
product_supplier
It seems you're creating an index on the foreign key columns. When creating a foreign key in InnoDb, one will be created automatically.
See this thread.
Try using INSERT IGNORE instead of INSERT where INSERT IGNORE will not insert a new row if a duplicate primary key is found. This should help resolve the problem temporary but I would recommend truncating the table.
I use WebERP in my 1and1 account, when I migrate my database to another 1and1 database I get this error:
SQL query:
--
-- Constraints for table `chartdetails`
--
ALTER TABLE `chartdetails` ADD CONSTRAINT `chartdetails_ibfk_1` FOREIGN KEY ( `accountcode` )
REFERENCES `chartmaster` ( `accountcode` ) ,
ADD CONSTRAINT `chartdetails_ibfk_2` FOREIGN KEY ( `period` ) REFERENCES `periods` ( `periodno` )
MySQL said:
#1452 - Cannot add or update a child row: a foreign key constraint fails (`dbxxxxxxxxx/#sql- 376_3fa4f12`, CONSTRAINT `chartdetails_ibfk_2` FOREIGN KEY (`period`) REFERENCES `periods` (`periodno`))
But the original file just work fine.
I got the same Error when i migrate. I resolved this error in 3 ways. You can resolve your error on any one of them or an all. This happens because of no data insret query happens before you alter.
• Put Alter table queries on last of all other queries.
• Twice check for the presence of data where the primary key is present
• Install fresh DB later insert in hierarchical order like chart master first and later chart detail insert queries.
Note: DB wont allow you to delete or insert when you try to change db queries. Keep backups of DB before making any changes.