doctrine 2 reverse engineering issue for a database - php

I have a database that i want to do some reverse engineering to tables using doctrine 2, so i used this simple commands
php app/console doctrine:mapping:import --force ProjectBundle yml
php app/console doctrine:mapping:convert annotation ./src
php app/console doctrine:generate:entities ProjectBundle
but the problem doctrine did not reverse engineered one join table containing two foreign keys but it did for another.
here you will find an sql statements for creating the two join tables the first have been reverse engineered the last one not
CREATE TABLE IF NOT EXISTS `control`.`project_problem_place` (
`id_place` INT(11) NOT NULL,
`id_problem` INT(11) NOT NULL,
`id_project` INT(11) NOT NULL,
PRIMARY KEY (`id_place`, `id_problem`, `id_project`),
INDEX `FK_project1` (`id_project` ASC),
INDEX `FK_problem1` (`id_problem` ASC),
CONSTRAINT `FK_problem1`
FOREIGN KEY (`id_problem`)
REFERENCES `control`.`problem` (`id`),
CONSTRAINT `FK_project1`
FOREIGN KEY (`id_project`)
REFERENCES `control`.`project` (`id`),
CONSTRAINT `FK_place1`
FOREIGN KEY (`id_place`)
REFERENCES `control`.`place` (`id`))
ENGINE = InnoDB
DEFAULT CHARACTER SET = latin1;
CREATE TABLE IF NOT EXISTS `control`.`project_code` (
`id_project` INT(11) NOT NULL,
`id_code` INT(11) NOT NULL,
PRIMARY KEY (`id_project`, `id_code`),
INDEX `FK_CODE2` (`id_code` ASC),
CONSTRAINT `FK_PROJECT2`
FOREIGN KEY (`id_project`)
REFERENCES `control`.`project` (`id`),
CONSTRAINT `FK_CODE2`
FOREIGN KEY (`id_code`)
REFERENCES `control`.`code` (`id`))
ENGINE = InnoDB
DEFAULT CHARACTER SET = latin1;
Thank you.

Related

needed in a foreign key constraint error by doctrine

I have database project migration from Symfony 3.2 -> 3.4
I made new project and copy entity to the new 3.4 environment.
then,
php bin/console doctrine:schema:update --force
it shows the error.
An exception occurred while executing 'DROP INDEX IDX_EFE42E9BC5E35EFC ON placeinfos_placecats':
SQLSTATE[HY000]: General error: 1553 Cannot drop index 'IDX_EFE42E9BC5E35EFC': needed in a foreign key constraint
So, I am checking the placeinfos_placecats table,
mysql> show create table placeinfos_placecats;
| placeinfos_placecats | CREATE TABLE `placeinfos_placecats` (
`placeinfo_id` int(11) NOT NULL,
`placecat_id` int(11) NOT NULL,
PRIMARY KEY (`placeinfo_id`,`placecat_id`),
KEY `IDX_EFE42E9BC5E35EFC` (`placecat_id`),
CONSTRAINT `FK_EFE42E9B6762112` FOREIGN KEY (`placeinfo_id`) REFERENCES `PlaceInfo` (`id`) ON DELETE CASCADE,
CONSTRAINT `FK_EFE42E9BC5E35EFC` FOREIGN KEY (`placecat_id`) REFERENCES `PlaceCat` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci |
There is constraint IDX_EFE42E9BC5E35EFC.
And then, what the doctrine tries to do,
php bin/console doctrine:schema:update --dump-sql
DROP INDEX IDX_EFE42E9BC5E35EFC ON placeinfos_placecats;
DROP INDEX IDX_EFE42E9B6762112 ON placeinfos_placecats;
ALTER TABLE placeinfos_placecats DROP PRIMARY KEY;
ALTER TABLE placeinfos_placecats ADD place_info_id INT NOT NULL, ADD place_cat_id INT NOT NULL, DROP placeinfo_id, DROP placecat_id;
ALTER TABLE placeinfos_placecats ADD CONSTRAINT FK_EFE42E9B6947D603 FOREIGN KEY (place_info_id) REFERENCES place_info (id) ON DELETE CASCADE;
ALTER TABLE placeinfos_placecats ADD CONSTRAINT FK_EFE42E9B4463AE2A FOREIGN KEY (place_cat_id) REFERENCES place_cat (id) ON DELETE CASCADE;
CREATE INDEX IDX_EFE42E9B6947D603 ON placeinfos_placecats (place_info_id);
CREATE INDEX IDX_EFE42E9B4463AE2A ON placeinfos_placecats (place_cat_id);
ALTER TABLE placeinfos_placecats ADD PRIMARY KEY (place_info_id, place_cat_id);
ALTER TABLE fos_user DROP FOREIGN KEY FK_957A6479B6E0899D;
ALTER TABLE fos_user CHANGE userkey user_key VARCHAR(255) DEFAULT NULL;
ALTER TABLE fos_user ADD CONSTRAINT FK_957A6479B6E0899D FOREIGN KEY (metainfo_id) REFERENCES meta_info (id);
ALTER TABLE media__gallery_media DROP FOREIGN KEY FK_80D4C5414E7AF8F;
ALTER TABLE media__gallery_media DROP FOREIGN KEY FK_80D4C541EA9FDD75;
ALTER TABLE media__gallery_media ADD CONSTRAINT FK_80D4C5414E7AF8F FOREIGN KEY (gallery_id) REFERENCES media__gallery (id) ON DELETE CASCADE;
ALTER TABLE media__gallery_media ADD CONSTRAINT FK_80D4C541EA9FDD75 FOREIGN KEY (media_id) REFERENCES media__media (id) ON DELETE CASCADE;
DROP INDEX IDX_5C6DD74E12469DE2 ON media__media;
ALTER TABLE media__media DROP category_id;
What does it mean???
Just dropping and adding constraint again??
Why doctrine wants to do like this ?
Then ,how should I solve it??
I just deleted the table manually via adminer. Withot "foreign key check".
Then, I did bin/console doctrine:schema:update -f and its ok!
I suppose this closely connected with Foreign Key restrictions. So, you can somehow exclude this check in doctrine.
But be careful. I guess method below isn't really good way for prod.
Actually, you could delete a special KEYNAME via adminer!
IDX_EFE42E9BC5E35EFC, for example...

Doctrine exception - [Doctrine\ORM\Mapping\MappingException]

Hi I'm new in symfony.
I'm trying to generate entities from an existing database with doctrine.
When I run this command:
php bin/console doctrine:mapping:import --force AppBundle xml
I get this exception :
[Doctrine\ORM\Mapping\MappingException]
Property "shop" in "Bug" was already declared, but it must be declared only once
I have tried to search other solutions, but I didn't find anythings.
How can I solve this problem?
This is how mysql workbench creates my table:
CREATE TABLE IF NOT EXISTS `db`.`bug` (
`id_bug` INT(11) NOT NULL AUTO_INCREMENT,
`bug_name` VARCHAR(200) NOT NULL,
`comment` VARCHAR(1000) NOT NULL,
`status` INT(11) NOT NULL DEFAULT '0',
`customer_id` VARCHAR(255) CHARACTER SET 'utf8' NOT NULL,
`shop_id` VARCHAR(255) CHARACTER SET 'utf8' NOT NULL,
`admin_id` VARCHAR(255) CHARACTER SET 'utf8' NOT NULL,
PRIMARY KEY (`id_bug`),
INDEX `fk_bug_customer1_idx1` (`customer_id` ASC),
INDEX `fk_bug_shop1_idx` (`shop_id` ASC),
INDEX `fk_bug_admin1_idx1` (`admin_id` ASC),
CONSTRAINT `fk_bug_customer1`
FOREIGN KEY (`customer_id`)
REFERENCES `db`.`customer` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_bug_shop1`
FOREIGN KEY (`shop_id`)
REFERENCES `db`.`shop` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_bug_admin1`
FOREIGN KEY (`admin_id`)
REFERENCES `db`.`admin` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB
DEFAULT CHARACTER SET = latin1;
I'm working in symfony 3.3, mysql and php7.
Thanks.
There were two problem:
First of all there was a relaction duplicated on the same enitity
It was not the only problem. We noticed that in doctrine occours problems when there is a primary key that is also a foreign key, so we added a new field id for the primary key.

Doctrine, how to left join an entity which wasn't generated?

I have rights:
CREATE TABLE `rights` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
UNIQUE INDEX `U_name` (`name`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB;
and profiles:
CREATE TABLE `profile` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
UNIQUE INDEX `U_name` (`name`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB;
I want to connect profiles to rights and also profiles to profiles:
CREATE TABLE `profile_profile` (
`profile_id1` INT(10) UNSIGNED NOT NULL DEFAULT '0',
`profile_id2` INT(10) UNSIGNED NOT NULL DEFAULT '0',
PRIMARY KEY (`profile_id1`, `profile_id2`),
INDEX `I_profile_id2` (`profile_id2`),
CONSTRAINT `FK_profile_profile-profile-1` FOREIGN KEY (`profile_id1`) REFERENCES `profile` (`id`) ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT `FK_profile_profile-profile-2` FOREIGN KEY (`profile_id2`) REFERENCES `profile` (`id`) ON UPDATE CASCADE ON DELETE CASCADE
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB;
CREATE TABLE `profile_right` (
`profile_id` INT(10) UNSIGNED NOT NULL DEFAULT '0',
`right_id` INT(10) UNSIGNED NOT NULL DEFAULT '0',
PRIMARY KEY (`profile_id`, `right_id`),
INDEX `I_right_id` (`right_id`),
CONSTRAINT `FK_profile_right-profile` FOREIGN KEY (`profile_id`) REFERENCES `profile` (`id`) ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT `FK_profile_right-rights` FOREIGN KEY (`right_id`) REFERENCES `rights` (`id`) ON UPDATE CASCADE ON DELETE CASCADE
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB;
a better overview:
so I generate entities:
php apps/doctrine.php dev orm:generate-entities libs/ --no-backup
--extend="\Doctrine\Entity\BaseEntity"
here come the problems. The Profile and Rights entities gets created, while Profile_rights and Profile_profile not. How to use them then?
In doctrine, join tables are not represented by an Entity.
You can find a #ORM\ManyToMany in your entities, with a #ORM\JoinTable and all informations about your associations.
This is the representation of your join table(s), use getters and setters like said by #Richard to access them.
Get more informations in the Associations mapping (to see all kind of associations) and Working with associations (to learn how work with them) chapters of the documentation.
Hope you have a good experience with doctrine.
EDIT
After look more at your UML, at least one of your associations doesn't need a many-to-many (As said by the first answer), but if they really have join tables in SQL, and you imported them by reverse engineering, they will surely be exactly as they are in SQL (a many-to-many with join table).
If you want to access the joining entity on a ManyToMany relationship you need to break it down to a OneToMany, ManyToOne.
E.g.
Profile - OneToMany < ProfileRight > ManyToOne - Profile.
Whether you should is another question. You only need to do this if you want to store extra data on the join table.
With what you have there it's trivial to get rights for a profile. For any profile you have loaded you simply call
$profile->getRights()
and doctrine will (assuming your generated entity mappings are correct) transparently fetch all the associated Rights entities for you based on the join table.
Similarly if you add a Right to a profile:
$right = new Right();
$profile->addRight($right);
Doctrine will transparently add the join table entry for you.

SQLSTATE[HY000]: General error: 1025 Error on rename error when dropping foreign key in Doctrine Migration

I am seeing the error below when I run the following query inside a Doctrine migration:
ALTER TABLE crmpicco_course_version DROP FOREIGN KEY FK_C060B146DE13F470
Migration 20151209153121 failed during Execution.
Error An exception occurred while executing
'ALTER TABLE crmpicco_course_version DROP FOREIGN KEY FK_C060B146DE13F470':
SQLSTATE[HY000]: General error:
1025 Error on rename of './crmpicco_dev/crmpicco_course_version'
to './crmpicco_dev/#sql2-77c-b0a' (errno: 152)
This is the table I am trying to change:
CREATE TABLE `crmpicco_course_version` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`course_id` int(11) NOT NULL,
`updated_by_id` int(11) DEFAULT NULL,
`name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`start_date` datetime DEFAULT NULL,
`end_date` datetime DEFAULT NULL,
`created_at` datetime NOT NULL,
`updated_at` datetime NOT NULL,
PRIMARY KEY (`id`),
KEY `IDX_C060B146896DBBDE` (`updated_by_id`),
KEY `IDX_C060B146DE13F470` (`course_id`),
CONSTRAINT `FK_C060B146896DBBDE` FOREIGN KEY (`updated_by_id`) REFERENCES `crmpicco_user` (`id`),
CONSTRAINT `FK_C060B146DE13F470` FOREIGN KEY (`course_id`) REFERENCES `crmpicco_course` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
What is preventing me from dropping this foreign key successfully?
When I run SHOW ENGINE INNODB STATUS I get the following:
------------------------
LATEST FOREIGN KEY ERROR
------------------------
151209 16:25:42 Error IN dropping of a FOREIGN KEY CONSTRAINT of TABLE "crmpicco_dev"."crmpicco_course_version",
IN SQL command
ALTER TABLE crmpicco_course_version DROP FOREIGN KEY FK_C060B146DE13F470
Cannot find a CONSTRAINT WITH the given id "FK_C060B146DE13F470".
After endless dropping and recreating of my local database I found that this was caused by Doctrine creating the same ALTER statement more than once and also in the wrong order.
I had to change the statements around manually to make sure I migrated data from my old table to my new table before creating the new foreign key constraint on the new table. Without this change I was getting the error above and others.

Creating composite foreign key on a primary key

I have a table called events with event_id as a primary key and a table person with person_id as a primary key.
I want to have a table that contains two columns event_id and person_id as foreign keys to the above two primary keys.
I am able to create a foreign key something like this:
create table pe(
event_id INTEGER UNSIGNED UNIQUE,
person_id INTEGER UNSIGNED UNIQUE,
FOREIGN KEY (event_id) REFERENCES events(event_id),
FOREIGN KEY (person_id) REFERENCES person(person_id)
);
but I cannot insert values like:
----------------------
event_id person_id
----------------------
1 1
1 2
2 1
2 2
----------------------
For that I need a composite foreign key.
I am not able to decide how to do that. Any suggestions or help are much appreciated!
Thanks a lot!
You need to make the combination of event_id and person_id unique. I'd just make the combination the primary key, as follows:
create table pe(
event_id INTEGER UNSIGNED,
person_id INTEGER UNSIGNED,
FOREIGN KEY (event_id) REFERENCES events(event_id),
FOREIGN KEY (person_id) REFERENCES person(person_id),
PRIMARY KEY (event_id, person_id)
);
Because you have set individual unique key for each column. Here's how to enforce composite unique key,
create table pe
(
event_id INTEGER UNSIGNED,
person_id INTEGER UNSIGNED,
FOREIGN KEY (event_id) REFERENCES events(event_id),
FOREIGN KEY (person_id) REFERENCES person(person_id),
UNIQUE (event_id, person_id) // <<== or it could be PRIMARY KEY
);
I played around with this schema to check what you were trying to do:
CREATE TABLE `events` (
`event_id` int(11) NOT NULL AUTO_INCREMENT,
`event_name` varchar(255) NOT NULL,
PRIMARY KEY (`event_id`),
UNIQUE KEY `event_name_UNIQUE` (`event_name`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
CREATE TABLE `person` (
`person_id` int(11) NOT NULL AUTO_INCREMENT,
`person_name` varchar(225) DEFAULT NULL,
PRIMARY KEY (`person_id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
CREATE TABLE `pe` (
`event_id` int(11) NOT NULL,
`person_id` int(11) NOT NULL,
PRIMARY KEY (`event_id`,`person_id`),
KEY `fk_events_has_person_person1` (`person_id`),
KEY `fk_events_has_person_events` (`event_id`),
CONSTRAINT `fk_events_has_person_events` FOREIGN KEY (`event_id`) REFERENCES `events` (`event_id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_events_has_person_person1` FOREIGN KEY (`person_id`) REFERENCES `person` (`person_id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8
I think your confusion lies in where you put the UNIQUE property. Each event and person needs to be unique. That is guaranteed by the primary key in the respective tables and you can also add a UNIQUE constraint in, for example, a column like person_name to ensure actual values are unique. There was nothing wrong with your foreign keys; the problem was that you added UNIQUE constraints to each field of the interim table. That's a mistake. If you want to ensure that each row of the interim table is unique then you need to add a composite primary key or as JW suggested a composite UNIQUE constraint.

Categories