mariadb won't create foreign key - foreign-keys

I think I'm using the right syntax for MariaDB, but my foreign key constraint is not being created.
Here's the create table DDL:
CREATE TABLE items (
id INT auto_increment primary key,
description TEXT NOT NULL
);
CREATE TABLE item_events (
id INT NOT NULL,
calendar_event_guid TEXT(255) NOT NULL,
foreign key item_events_id_fk (id) REFERENCES items (id)
);
Then, when I ask MariaDB to show me what I created, I get this:
+-------------+-----------------
| Table | Create Table +-------------+-----------------
| item_events | CREATE TABLE `item_events` (
`id` int(11) NOT NULL,
`calendar_event_guid` text COLLATE utf8_unicode_ci NOT NULL,
KEY `item_events_id_fk` (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
+-------------+-----------------
or, just showing the DDL:
CREATE TABLE `item_events` (
`id` int(11) NOT NULL,
`calendar_event_guid` text COLLATE utf8_unicode_ci NOT NULL,
KEY `item_events_id_fk` (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
Notice that it only created a "KEY", not a foreign key. The items table is correctly created.
Surely, this is really simple :)

Related

Why MySQL workbench is making all my foreign keys unique?

I've created a MySQL Model with a few tables, some of them with fk's to another table. I usually export the SQL from MySQL Model to my database using the "Forward Engineer SQL CREATE Script" inside File -> Export -> Forward Engineer SQL CREATE Script. The problem here is that when I generate the creation script, all my fk's become unique. I didn't check UQ option in MySQL Model but it creates a script with unique fk's anyway, so, I need to change the SQL file generated and remove all the unwanted uniques. Anyone has a clue why this is happening?
Generated script:
CREATE TABLE IF NOT EXISTS `u514786799_detranleiloes`.`Lotes` (
`createdAt` DATE NOT NULL,
`updatedAt` DATE NOT NULL,
`id` INT UNIQUE NOT NULL AUTO_INCREMENT,
`LeiloesId` INT UNIQUE NOT NULL,
`conservado` TINYINT NULL,
`numero` INT NOT NULL,
`CRDsId` INT UNIQUE NULL,
PRIMARY KEY (`id`),
INDEX `fk_Lotes_Leiloes_idx` (`LeiloesId` ASC),
INDEX `fk_Lotes_CRDs1_idx` (`CRDsId` ASC),
CONSTRAINT `fk_Lotes_Leiloes`
FOREIGN KEY (`LeiloesId`)
REFERENCES `u514786799_detranleiloes`.`Leiloes` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_Lotes_CRDs1`
FOREIGN KEY (`CRDsId`)
REFERENCES `u514786799_detranleiloes`.`CRDs` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB
AUTO_INCREMENT = 1;

Regular expression to extract certain columns from SQL "CREATE TABLE" statements

Let's say I have a MySQL dump which creates a lot of tables.
Example:
CREATE TABLE `my_table` (
`id` bigint(20) NOT NULL,
`REVTYPE` tinyint(4) DEFAULT NULL
`some_other_column` varchar(255)
);
What whould be a valid regular expression to find the following:
All lines which start with "CREATE TABLE" and which contains "my_" in the table name
Then extracting the line containing "tinyint"
So the result would look like:
CREATE TABLE `my_table` (
`REVTYPE` tinyint(4) DEFAULT NULL
This regex seems to work:
^((CREATE.*my_.*\n)|(\s+.*tinyint.*\n)|(\s+.*(?!tinyint)\n))
CREATE TABLE `my_table` (
`id` bigint(20) NOT NULL,
`id` bigint(22) NOT NULL,
`REVTYPE` tinyint(4) DEFAULT NULL,
`id` bigint(20) NOT NULL,
`REVTYPE` tinyint(5) DEFAULT NULL,
`some_other_column` varchar(255)
);
becomes (replace with $2$3) :
CREATE TABLE `my_table` (
`REVTYPE` tinyint(4) DEFAULT NULL,
`REVTYPE` tinyint(5) DEFAULT NULL,
);
[I assume the OP wants the ); at the end -advise if not true.]
.
See regex101 link:

Django and mariadb not working with istartswith correctly using german umlauts

the following query should only return all cities starting with "Ö" (German umlaut).
letter = 'Ö'
City.objects.filter(name__istartswith=letter)
But it returns cities starting with O and Ö.
I use django 1.11 and mariadb.
I allready set COLLATE on that table to utf8_bin but this haven't changed the behavior within django.
This is the simplified SQL query
SELECT `cities_city`.`name` FROM `cities_city` WHERE `cities_city`.`name` LIKE "Ö%";
and here the SHOW CREATE TABLE output:
SHOW CREATE TABLE `cities_city`
-> ;
+-------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| cities_city | CREATE TABLE `cities_city` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(200) CHARACTER SET utf8 NOT NULL,
`slug` varchar(255) CHARACTER SET utf8 DEFAULT NULL,
`name_std` varchar(200) CHARACTER SET utf8 NOT NULL,
`location` point NOT NULL,
`population` int(11) NOT NULL,
`elevation` int(11) DEFAULT NULL,
`kind` varchar(10) CHARACTER SET utf8 NOT NULL,
`timezone` varchar(40) CHARACTER SET utf8 NOT NULL,
`country_id` int(11) NOT NULL,
`region_id` int(11) DEFAULT NULL,
`subregion_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `cities_city_country_id_2f07e352_uniq` (`country_id`,`region_id`,`subregion_id`,`id`,`name`),
KEY `cities_city_b068931c` (`name`),
KEY `cities_city_16c3f481` (`name_std`),
KEY `cities_city_region_id_0227cdac_fk_cities_region_id` (`region_id`),
KEY `cities_city_subregion_id_9fbab97d_fk_cities_subregion_id` (`subregion_id`),
CONSTRAINT `cities_city_country_id_779ae117_fk_cities_country_id` FOREIGN KEY (`country_id`) REFERENCES `cities_country` (`id`),
CONSTRAINT `cities_city_region_id_0227cdac_fk_cities_region_id` FOREIGN KEY (`region_id`) REFERENCES `cities_region` (`id`),
CONSTRAINT `cities_city_subregion_id_9fbab97d_fk_cities_subregion_id` FOREIGN KEY (`subregion_id`) REFERENCES `cities_subregion` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=11468436 DEFAULT CHARSET=utf8 COLLATE=utf8_bin |
+-------------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
The problem is a subtle one.
The clue is here:
SELECT * FROM information_schema.`COLUMNS` WHERE table_name = 'cities_city';
The explanation...
`name` varchar(200) CHARACTER SET utf8 NOT NULL,
is COLLATE utf8_general_ci because that is the default collation for utf8.
This table default:
) ENGINE=InnoDB AUTO_INCREMENT=11468436 DEFAULT CHARSET=utf8 COLLATE=utf8_bin
gives utf8_bin to any newly added rows.
Perhaps you did the obvious ALTER TABLE to change to _bin? Instead:
ALTER TABLE cities_city
CONVERT TO CHARACTER SET utf8
COLLATE utf8_bin;
this will go into each string column and make the change. Note that indexes (etc) must be rebuilt when the collation changes.

RegEx to remove lines from MySQL dump

CREATE TABLE `transaction` (
`id` mediumint(9) NOT NULL AUTO_INCREMENT,
`description` text NOT NULL,
PRIMARY KEY (`id`),
FULLTEXT KEY `description` (`description`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
How can I remove FULLTEXT line from MySQL dump above and comma on the line before so it looks something like this:
CREATE TABLE `transaction` (
`id` mediumint(9) NOT NULL AUTO_INCREMENT,
`description` text NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
The removal should be easy using sed but I'm not sure how to remove this comma on the line above so the dump is successfully imported:
sed -i '/FULLTEXT KEY.*/d' dump.sql
Sometimes there is also more columns with FULLTEXT index:
CREATE TABLE `entity` (
`id` mediumint(9) NOT NULL AUTO_INCREMENT,
`company_name` varchar(255) NOT NULL DEFAULT '',
`description` text NOT NULL,
PRIMARY KEY (`id`),
FULLTEXT KEY `company_name` (`company_name`),
FULLTEXT KEY `description` (`description`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Sed script:
#!/bin/bash
sed -e '/FULLTEXT/d' |
sed -ne '
/ENGINE=InnoDB/!{H}
/ENGINE=InnoDB/{x; s/,[ \t]*$//; p; }
${g;p;}
'
Input:
CREATE TABLE `transaction` (
`id` mediumint(9) NOT NULL AUTO_INCREMENT,
`description` text NOT NULL,
PRIMARY KEY (`id`),
FULLTEXT KEY `description` (`description`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `entity` (
`id` mediumint(9) NOT NULL AUTO_INCREMENT,
`company_name` varchar(255) NOT NULL DEFAULT '',
`description` text NOT NULL,
PRIMARY KEY (`id`),
FULLTEXT KEY `company_name` (`company_name`),
FULLTEXT KEY `description` (`description`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Sample Run:
/home/user> ./1.sed < input
CREATE TABLE `transaction` (
`id` mediumint(9) NOT NULL AUTO_INCREMENT,
`description` text NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `entity` (
`id` mediumint(9) NOT NULL AUTO_INCREMENT,
`company_name` varchar(255) NOT NULL DEFAULT '',
`description` text NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
sed is for simple substitutions on individual lines, that is all. For anything else you should use awk for clarity, brevity, portability, efficiency, robustness and most other desirable qualities of software. All of the sed constructs to do anything other than s, g, and p (with -n) became obsolete in the mid-1970s when awk was invented and exist today just for mental exercise.
Given this input:
$ cat file
CREATE TABLE `transaction` (
`id` mediumint(9) NOT NULL AUTO_INCREMENT,
`description` text NOT NULL,
PRIMARY KEY (`id`),
FULLTEXT KEY `description` (`description`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `entity` (
`id` mediumint(9) NOT NULL AUTO_INCREMENT,
`company_name` varchar(255) NOT NULL DEFAULT '',
`description` text NOT NULL,
PRIMARY KEY (`id`),
FULLTEXT KEY `company_name` (`company_name`),
FULLTEXT KEY `description` (`description`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
With GNU awk for multi-char RS:
$ awk -v RS=',\\s*FULLTEXT[^\n]*)' -v ORS= '1' file
CREATE TABLE `transaction` (
`id` mediumint(9) NOT NULL AUTO_INCREMENT,
`description` text NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `entity` (
`id` mediumint(9) NOT NULL AUTO_INCREMENT,
`company_name` varchar(255) NOT NULL DEFAULT '',
`description` text NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Since you are using GNU sed (for -i) I assume you will have no problem using GNU awk and if you need inplace editing add -i inplace at the start.
awk -vRS=";" 'NF{gsub(/),\n +FULLTEXT.*)/,")\n)",$0);$0=$0";"}1' file

How to update and set unit_id to be NULL, unit id is foreign key from unit table

How to update and set unit_id to be NULL, unit id is foreign key and I need to set to be NULL
CREATE TABLE troops
(
id serial NOT NULL,
unit_id integer,
type integer NOT NULL,
level integer NOT NULL,
CONSTRAINT troops_pkey PRIMARY KEY (id),
CONSTRAINT troops_unit_id_fkey FOREIGN KEY (unit_id)
REFERENCES units (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE CASCADE
)
WITH (
OIDS=FALSE
);
I have tried to update troops and set unit_id to be NULL ( I put NULL not 0 in pqxx statement in C++ ) but I get error like
insert or update on table "troops" violates foreign key constraint "troops_unit_id_fkey"
DETAIL: Key (unit_id)=(0) is not present in table "units".
When I try from pgadmin I can set unit_id to be NULL in troops but pqxx ( from c++ code I try to update) converts NULL to 0, how to solve this ?