SQLAlchemy configration for MySQL's "SET foreign_key_checks = 0" - mysql

I am using SQLAlchemy with Flask to create database tables - every table has at least one foreign key - it works with sqlite but not MySQL - I get foreign key integrity error when creating the tables in MySQL (the parent table is not created when creating the child table). I use "SET foreign_key_checks = 0" to solve the problem but that does not work with sqlite. Is there a way to configure SQLAlchemy to ignore foreign key checks?

if you are user mysql, you can connect to mysql and use SET GLOBAL FOREIGN_KEY_CHECKS = 0; delete the db table you want, and again SET GLOBAL FOREIGN_KEY_CHECKS = 1;. This value verifies foreign relationships in the db tables.

First of all, why would you want to ignore foreign key constraints? When you define your foreign key you can pass a string with the foreign table and column names, and those will be resolved correctly even if the foreign table hasn't been created yet.
But in any case, if you want to have foreign keys that are not enforced, just don't define your foreign key columns as foreign keys, define them as simple columns and manage the foreign key dependency yourself. Not a good idea, in my opinion, but it can be done.

Related

MySQL "Duplicate Foreign Key", but key doesn't exist

I need to create a foreign key, but executing the following results in the error: "Error Code: 1826. Duplicate foreign key constraint name 'FK_ProjectBase_Program'"
alter table ipos5.ProjectBase
add constraint FK_ProjectBase_Program foreign key (Program) references Program(OID);
If I execute:
select *
from information_schema.TABLE_CONSTRAINTS
where CONSTRAINT_TYPE = 'FOREIGN KEY'
result = def ipos5 FK_ProjectBase_Program ipos5 projectbase FOREIGN KEY
I can see the existing key definition, but if I show the structure for the target TABLE_NAME, it is not there.
This is on an active database with a large amount of data, using InnoDB, so dump/restore is a very last resort.
I am using a 3rd party framework, which does not allow me to manually specify a foreign key name (so I HAVE to use the one specified), but my application errors during startup because it cannot create the key.
Is there a way to rebuild the information_schema database? I am really hoping to avoid doing a dump and rebuild of the application database, as it is quite large.
I ended up duplicating the table structure, copying the data into it, dropping the original table, then re-creating it and copying the data back. Orphaned foreign key reference is now gone.

MySQL Updating/adding foreign key constraints

I have to update foreign constraints in a lot of tables in a lot of databases. The databases should(!) have the same structure, but I realized that there are sometimes little differences (e.g. constraints are different).
So my idea is, to "normalize" all tables by dropping foreign key constraints first.
Is there a way to drop all foreign key constraints referenced to a specified table/column from all tables?
For example:
DROP FOREIGN KEY FROM ... WHERE referenceTable = 'myTable'
AND referenceCol' = 'myId'
I think you need to look here:
http://dev.mysql.com/doc/refman/5.6/en/innodb-information-schema-system-tables.html
It is feasible. Youc could certainly do a single query to drop the keys you need to remove.

Automatic connection of a new table in a existing Mysql database

I have a schema on my db where there are some tables. I have to create a table into this schema and i have to connect it with the others already present on the schema.I make an example:
Tables already present:
SCHOOL(IdSchool,NumStud,IdCountry);
SHOP(IdShop,IdCountry);
New table:
Country(IdCountry,....);
I want to know if there is an automatic mode to connect them (it means not to set the foreign key manually).
I want to know if there is an automatic mode to connect them (it means not to set the foreign key manually).
No.
How is the DBMS to know that Country.IdCountry and SCHOOL.IdCountry are given the same name with the intention to be connected, instead of just accidentally?
You'll have to use ALTER TABLE ... ADD FOREIGN KEY (...) REFERENCES ...1 to explicitly create the foreign key in the existing table.
1 Or ALTER TABLE ... ADD CONSTRAINT ... FOREIGN KEY (...) REFERENCES ....

Cascading delete removes unintended records

I typically develop in MS Access and occasionally connect to a MySQL back end. I have a MySQL back end that isn't cascading deletes as I'd expect when I delete records. I'm wondering if it's because of how I've set up the table relationships (foreign keys). I don't know enough about MySQL to know if I've done this right. In designer view I set up the relationships using the designer view in MySQL. For a composite primary key field (InterviewID, Coder ID) in tblInterviews I created two separate relations to tblSB for each of these two primary key fields (tblSB includes a 3rd field, SBid, as its composite PK). The designer view is a little different from Access in that you can't highlight more than one field at a time to set up relationships. I did find forums that discuss the syntax for setting up the relationship with the foreign key but I don't know if it's equivalent to what I did in designer. I suspect not because currently when I try to delete a specific record (unique InterviewID, CoderID combination) ALL interview records for the CoderID in the InterviewID, CoderID combination get deleted (and this cascades through to other child tables as well). I also am wondering if I need to set up my primary key in a way that I am not currently doing (e.g., setting it up as an index, also). Any help would be appreciated. Thanks in advance.
To see what you've created, look at the DDL. (SHOW CREATE TABLE)
To enforce foreign key constraints--including cascading deletes--you probably want to use the innodb engine. The myisam engine will accept DDL that declares foreign keys, but it won't enforce them.
MySQL will let a foreign key target a non-unique column. The MySQL docs say
Deviation from SQL standards: A FOREIGN KEY constraint that references
a non-UNIQUE key is not standard SQL. It is an InnoDB extension to
standard SQL.
They call it an extension to SQL. I call it a mistake.
It means you can declare tblSB.interviewID as a foreign key referencing tblInterviews.interviewID. A standard SQL dbms wouldn't allow that.
The 5.6 docs say
However, the system does not enforce a requirement that the referenced
columns be UNIQUE or be declared NOT NULL. The handling of foreign key
references to nonunique keys or keys that contain NULL values is not
well defined for operations such as UPDATE or DELETE CASCADE. You are
advised to use foreign keys that reference only UNIQUE and NOT NULL
keys.
To my way of thinking, they're saying, "It was a bad idea, but we don't know how to fix it. So it's up to you to avoid it. We could warn you when you try it, but we're not going to do that, either."
Based on your comments, I'd say this constraint is right . . .
CONSTRAINT tblInterviewRecordtblSB
FOREIGN KEY (InterviewID, CoderID)
REFERENCES tblinterviewrecord (InterviewID, CoderID)
ON DELETE CASCADE ON UPDATE CASCADE
but these two are not, and should be deleted.
CONSTRAINT tblSB_ibfk_1
FOREIGN KEY (InterviewID)
REFERENCES tblinterviewrecord (InterviewID)
ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT tblSB_ibfk_2
FOREIGN KEY (CoderID)
REFERENCES tblinterviewrecord (CoderID)
ON DELETE CASCADE ON UPDATE CASCADE

mysql drop foreign key without table copy

I have an InnoDB table claims which has about 240 million rows. The table has a foreign key constraint: CONSTRAINT FK78744BD7307102A9 FOREIGN KEY (ID) REFERENCES claim_details (ID). I want to delete the table claim_details as quickly as possible.
Based on some experimentation it seems that if I use SET foreign_key_checks = 0; drop claim_details and then re-enable foreign keys, mysql will continue to enforce the constraint even though the table no longer exists. So, I believe I must drop the constraint from the table.
I have tried to use ALTER TABLE claims DROP FOREIGN KEY FK78744BD7307102A9 to drop the constraint and the query has been in a state of "copy to tmp table" for over 24 hours (on a machine with no other load). I don't understand why dropping a constraint requires making a copy of the table. Is there any way to prevent this?
mysql version 5.1.48.
Starting with MySQL 5.6, MySQL supports dropping of foreign keys in-place/without copying. Oracle calls this Online DDL.
This table lists all Online DDL operations and their runtime behavior.
From my experience, dropping foreign keys and the corresponding constraints on a 600GB table is almost instantaneous. With 5.5 it would probably have taken days.
The only disadvantage that I am aware of is, that 5.6 does not allow you to reclaim table space. I.e. if you are using innodb_file_per_table, that file will not shrink when you drop indices. Only the unused data in the file will grow. You can easily check using SHOW TABLE STATUS, and the Data_free column.
I think there is no a good way to drop that foreign key
http://dev.mysql.com/doc/refman/5.5/en/innodb-create-index-limitations.html
"MySQL 5.5 does not support efficient creation or dropping of FOREIGN KEY constraints. Therefore, if you use ALTER TABLE to add or remove a REFERENCES constraint, the child table is copied, rather than using Fast Index Creation." This probably refers also to older versions of mysql.
I think the best method will be to dump data from claims with mysqldump, recreate table without foreign key referencing to claim_details, disable key check with SET foreign_key_checks = 0; in case you have other foreign keys and import back data for claims. Just remember to make separate dumps for data and structure so you don't need to edit this huge file to remove foreign key from table creation syntax.