MySql & Sqlalchemy - not all foreign keys visible - mysql

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.

Related

Sql: cannot drop foreign key due to auto-generated constraint

I have a foreign key that was generated with the following command in an old and already deployed migration:
ALTER TABLE `job_template`
ADD COLUMN `parent_id` BIGINT,
ADD FOREIGN KEY fk_job_template_parent_id(parent_id) REFERENCES job_template(id) ON DELETE CASCADE;
Now I am trying to drop this foreign key with following command:
ALTER TABLE job_template DROP FOREIGN KEY fk_job_template_parent_id;
The problem is that this works for mariaDB but not for mySQL and I need a migration that would work in both cases
If I list the SHOW CREATE TABLE command (before the deleting of the foreign key) from both environments I get the following:
mariaDB:
constraint fk_job_template_parent_id foreign key (parent_id) references job_template (id) on delete cascade,
mysql:
constraint job_template_ibfk_5 foreign key (parent_id) references job_template (id) on delete cascade,
The constraint names are different in the 2 environments, and thus I have no way to write a migration that would consistently drop this foreign key.
Is there any way to get around this situation?
Your problem is that you are not explicitly naming your constraints. This leaves each database to pick a name for you. The trick here is to name your foreign key constraints explicitly, when you create the actual tables on both MySQL and MariaDB:
CREATE TABLE job_template (
...,
parent_id int NOT NULL,
CONSTRAINT your_constraint FOREIGN KEY fk_name (parent_id)
REFERENCES job_template(id) ON DELETE CASCADE
);
But fixing your immediate situation would require more work. One option would be to query the information schema table, for the table involved, to find out the actual constraint names:
USE INFORMATION_SCHEMA;
SELECT
TABLE_NAME,
COLUMN_NAME,
CONSTRAINT_NAME,
REFERENCED_TABLE_NAME,
REFERENCED_COLUMN_NAME
FROM KEY_COLUMN_USAGE
WHERE
TABLE_SCHEMA = 'your_db' AND
TABLE_NAME = 'job_template' AND
REFERENCED_COLUMN_NAME IS NOT NULL;
This should return one record for every column and constraint. With this information, you should be able to run your current alter statements.
This is easy enough to do using a tool like Java, or something similar. If you want to do this directly from the database, then you would need dynamic SQL, which probably means writing a stored procedure.

foreign key constraint is incorrectly formed [same table]

here is my table structure
I would like that parent_forum would save an id of parent forum, which is the ID of the same table id column value. As you can see both columns have the same type. My table engine is InnoDB, I try the following query to add a constraint.
ALTER TABLE `forums` ADD CONSTRAINT `parent_forum constraint` FOREIGN KEY (`id`) REFERENCES `codeigniter`.`forums`(`id`) ON DELETE RESTRICT ON UPDATE RESTRICT;
and I get an error that is written on the title.
What is actually wrong here? Category_id successfully works with other table ID value.
I think this is the syntax you are looking for:
ALTER TABLE forums ADD CONSTRAINT parent_forum_constraint
FOREIGN KEY (parent_forum) REFERENCES codeigniter.forums(id)
ON DELETE RESTRICT ON UPDATE RESTRICT;
The column in parentheses is the one that refers to the column after the references. Also, don't put spaces in names, unless you have a really good reason. Code is much more readable without all the backticks.

Cannot add or update a child row: a foreign key constraint fails webERp

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.

MySQL strange FK error

Here are 2 tables.
Full size image
I'm trying to create relationship between them by creating foreign keys courses:parent<->child.parent_cid <=> courses.id and courses:parent<->child.child_cid <=> courses.id
SQL looks like that
ALTER TABLE `courses: parent<->child` ADD CONSTRAINT `cpc.parent_cid_courses.id` FOREIGN KEY (`parent_cid`) REFERENCES `courses` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE `courses: parent<->child` ADD CONSTRAINT `cpc.child_cid_courses.id` FOREIGN KEY (`child_cid`) REFERENCES `courses` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
Getting this error message
What am I doing wrong? Any suggestions?
My first suggestion: rename the child table and the foreign key constraints using only alphanumeric characters and underscores.
The error message implies that there are invalid foreign key values in the child table. You can tell the MySQL server to ignore those values like this before running the ALTER TABLE statements:
set foreign_key_checks = 0;
Or you can fix the data by either adding the missing parent rows or deleting the invalid child rows before adding the constraints.
You are trying to add foreign keys. The error means that child table has data which doesn't exist in parent table.
In your case cpc.parent_cid_courses.id.parent_cid has wrong values, there are no corresponding values in parent field courses.id.

What is this "_ifbk" constraint doing in my table?

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?