I am starting to explore Symfony and after create the schema by importing this sql script and create the entities following these commands:
Importing mapping information by generating the metadata files:
$ php app/console doctrine:mapping:import --force AcmeBlogBundle xml
Build related entity classes:
-> Generates entity classes with annotation mappings
$ php app/console doctrine:mapping:convert annotation ./src
$ php app/console doctrine:generate:entities AcmeBlogBundle
The command:
$ php app/console doctrine:schema:update --force
fails with the following error:
[Doctrine\DBAL\Exception\DriverException]
An exception occurred while executing 'ALTER TABLE writtings CHANGE id id INT AUTO_INCREMENT NOT NULL':
SQLSTATE[HY000]: General error: 1025 Error on rename of './amimusa/#sql-425_5e' to './amimusa/writtings' (errno: 150)
[Doctrine\DBAL\Driver\PDOException]
SQLSTATE[HY000]: General error: 1025 Error on rename of './amimusa/#sql-425_5e' to './amimusa/writtings' (errno: 150)
[PDOException]
SQLSTATE[HY000]: General error: 1025 Error on rename of './amimusa/#sql-425_5e' to './amimusa/writtings' (errno: 150)
The dump file generated is:
ALTER TABLE writtings CHANGE id id INT AUTO_INCREMENT NOT NULL;
ALTER TABLE writtings ADD CONSTRAINT FK_F9A6AFF48726D6E4 FOREIGN KEY (publication_type) REFERENCES publications_type (id);
ALTER TABLE musas CHANGE id id INT AUTO_INCREMENT NOT NULL;
ALTER TABLE publications DROP FOREIGN KEY contributor_FK;
ALTER TABLE publications DROP FOREIGN KEY state_FK;
ALTER TABLE publications DROP FOREIGN KEY writting_FK;
ALTER TABLE publications CHANGE id id INT AUTO_INCREMENT NOT NULL, CHANGE id_contributor id_contributor INT DEFAULT NULL, CHANGE id_state id_state INT DEFAULT NULL, CHANGE id_writting id_writting INT DEFAULT NULL;
ALTER TABLE publications ADD CONSTRAINT FK_32783AF440C1075C FOREIGN KEY (id_writting) REFERENCES writtings (id);
ALTER TABLE publications ADD CONSTRAINT FK_32783AF44D1693CB FOREIGN KEY (id_state) REFERENCES states (id);
ALTER TABLE publications ADD CONSTRAINT FK_32783AF4C27D5A64 FOREIGN KEY (id_contributor) REFERENCES contributors (id);
ALTER TABLE publications_musas DROP FOREIGN KEY musa_FK;
ALTER TABLE publications_musas DROP FOREIGN KEY publication_FK;
ALTER TABLE publications_musas DROP FOREIGN KEY musa_FK;
ALTER TABLE publications_musas CHANGE id_publication id_publication INT NOT NULL, CHANGE id_musa id_musa INT NOT NULL;
ALTER TABLE publications_musas ADD CONSTRAINT FK_7EF2161FB72EAA8E FOREIGN KEY (id_publication) REFERENCES publications (id);
ALTER TABLE publications_musas ADD CONSTRAINT FK_7EF2161FFB53D80 FOREIGN KEY (id_musa) REFERENCES musas (id);
DROP INDEX musa_fk ON publications_musas;
CREATE INDEX IDX_7EF2161FFB53D80 ON publications_musas (id_musa);
ALTER TABLE publications_musas ADD CONSTRAINT musa_FK FOREIGN KEY (id_musa) REFERENCES musas (id) ON UPDATE CASCADE ON DELETE CASCADE;
ALTER TABLE contributors CHANGE id id INT AUTO_INCREMENT NOT NULL;
ALTER TABLE states CHANGE id id INT AUTO_INCREMENT NOT NULL;
Anybody could help me to understand why the update fails?
Also I can't figure out why these operations are required since everything has been created from scratch.
As Cerad commented:
The reverse engineering stuff is not perfect. Doctrine likes to have
things defined it's own way. I'd suggest dropping the database then
use doctrine:schema:create to rebuild it the way doctrine wants it to
be.
$ php app/console doctrine:schema:drop --force
$ php app/console doctrine:schema:create
Has fixed the issue.
Related
I am trying to delete a record from table users.
Tried deleteing it with a DELETE-statement (DELETE FROM users WHERE user_id=10" as well as in my DB browser, but I get the above error, specifically it says: "Error deleting record: foreign key mismatch - "games" referencing "groups" (DELETE FROM "main"."users" WHERE rowid IN ('10');)".
Below my schema:
CREATE TABLE users (
user_id INTEGER PRIMARY KEY,
name VARCHAR(255) NOT NULL,
hash VARCHAR(255) NOT NULL,
UNIQUE(name));
CREATE TABLE 'groups' (
'group_name' VARCHAR(255) NOT NULL,
'turn' INTEGER NOT NULL,
'user_id'INTEGER,
FOREIGN KEY ('user_id') REFERENCES 'users'('user_id')
ON UPDATE CASCADE
ON DELETE CASCADE
);
CREATE TABLE games (
game_id INTEGER PRIMARY KEY,
active INTEGER,
turn INTEGER,
group_name VARCHAR(255) NOT NULL,
FOREIGN KEY (turn) REFERENCES groups(turn_id)
ON UPDATE CASCADE
ON DELETE CASCADE,
FOREIGN KEY (group_name) REFERENCES groups(group_name)
ON UPDATE CASCADE
ON DELETE NO ACTION
);
Why is this a problem? user_id is not even a foreign key in 'games'?? Thank you!
The problem in the end was my DB Browser for SQLite (3.11.2) whose GUI allows deletions but they don't actually work. When I tied again in the bash and closed and restarted the DB Browser, the rows were gone. Uninsightful but figured I'd post nonetheless in case anyone else comes across this.
I am using oracle12C as database and using get_ddl for getting ddl of database objects.Now i have two tables Table1 and Table2 and Table1 has partition, Table2 is using primary constraint of Table1 as reference constraint and also using PARTITIONED BY REFERENCE.For eg :-
TABLE1 :-
create table parent_emp(
empno number primary key,
job varchar2(20),
sal number(7,2),
deptno number(2)
)
partition by list(job)(
partition p_job_dba values ('DBA'),
partition p_job_mgr values ('MGR'),
partition p_job_vp values ('VP')
);
TABLE2 :-
CREATE TABLE "SECONDARYUSER"."REFERENCE_EMP"(
"ENAME" VARCHAR2(10),
"EMP_ID" NUMBER,
"EMPNO" NUMBER,
CONSTRAINT "FK_EMPNO" FOREIGN KEY ("EMPNO")
REFERENCES "SECONDARYUSER"."PARENT_EMP" ("EMPNO") ENABLE
)
PARTITION BY REFERENCE ("FK_EMPNO")(
PARTITION "P_JOB_DBA" ,
PARTITION "P_JOB_MGR" ,
PARTITION "P_JOB_VP" )
My issue is I want to disable-enable constraints from Table1 and Table2 but when I execute following script to disable Table1 primary key:
alter table parent_emp disable constraint SYS_C0010720 cascade;
it gives following error:-
02297. 00000 - "cannot disable constraint (%s.%s) - dependencies exist"
*Cause: an alter table disable constraint failed becuase the table has
foriegn keys that are dpendent on this constraint.
*Action: Either disable the foreign key constraints or use disable cascade
So I tried to disable Table2 foreign key constraint and execute the following query:
alter table reference_emp disable constraint FK_EMPNO cascade;
but it gave the following error:-
alter table reference_emp disable constraint FK_EMPNO cascade
Error report:
SQL Error: ORA-14650: operation not supported for reference-partitioned tables
Please suggest me how can I disable-enable constraints in this condition.
I tried to re-engineer a database, that I use at work. The one at work is MS Access. At home, it's MariaDB. For convenience, I use MySQL Workbench.
When sending the complete SQL dump to the server, I get an error concerning some foreign key not being correctly formed. I guess, it is a minor mistake, but still I cannot find it.
My InnoDB status tells me this:
LATEST FOREIGN KEY ERROR
2018-10-03 00:18:29 409c7450 Error in foreign key constraint of table `mydb`.`IF`:
FOREIGN KEY (`belegid`)
REFERENCES `mydb`.`tblBelegPositionen` (`belegfID`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_tblBelege_tblECKassenschnittPositionen10`
FOREIGN KEY (`belegid`)
REFERENCES `mydb`.`tblECKassenschnittPositionen` (`belegfID`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB:
Cannot find an index in the referenced table where the
referenced columns appear as the first columns, or column types
in the table and the referenced table do not match for constraint.
Note that the internal storage type of ENUM and SET changed in
tables created with >= InnoDB-4.1.12, and such columns in old tables
cannot be referenced by such columns in new tables.
See http://dev.mysql.com/doc/refman/5.6/en/innodb-foreign-key-constraints.html
for correct foreign key definition.
Create table '`mydb`.`IF`' with foreign key constraint failed. There is no index in the referenced table where the referenced columns appear as the first columns near '
FOREIGN KEY (`belegid`)
REFERENCES `mydb`.`tblBelegPositionen` (`belegfID`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_tblBelege_tblECKassenschnittPositionen10`
FOREIGN KEY (`belegid`)
REFERENCES `mydb`.`tblECKassenschnittPositionen` (`belegfID`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB'.
The really weird thing is that I do not have any table named "IF"...
Can anyone make heads or tails of this for me? That would be very much appreciated.
-- Table `mydb`.`tblBelegPositionen`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `mydb`.`tblBelegPositionen` ;
SHOW WARNINGS;
CREATE TABLE IF NOT EXISTS `mydb`.`tblBelegPositionen` (
`belegposid` INT NOT NULL AUTO_INCREMENT,
`belegposBetrag` DOUBLE NOT NULL,
`zahlartfID` INT NOT NULL,
`belegfID` INT NOT NULL,
PRIMARY KEY (`belegposid`))
ENGINE = InnoDB;
SHOW WARNINGS;
-- Table `mydb`.`tblECKassenschnittPositionen`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `mydb`.`tblECKassenschnittPositionen` ;
SHOW WARNINGS;
CREATE TABLE IF NOT EXISTS `mydb`.`tblECKassenschnittPositionen` (
`ecposid` INT NOT NULL AUTO_INCREMENT,
`belegfID` INT NOT NULL,
`ecposBetrag` DOUBLE NOT NULL,
`kassenschnittfID` INT NOT NULL,
PRIMARY KEY (`ecposid`))
ENGINE = InnoDB;
SHOW WARNINGS;
-- Table `mydb`.`tblBelege`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `mydb`.`tblBelege` ;
SHOW WARNINGS;
CREATE TABLE IF NOT EXISTS `mydb`.`tblBelege` (
`belegid` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`belegKassierer` INT NOT NULL,
`belegDatum` DATETIME NOT NULL,
`kassefID` INT NOT NULL,
`belegSchicht` INT NULL,
`gvfID` INT NOT NULL,
`belegJahr` YEAR NULL,
`belegDruckErfolgt` TINYINT(1) NULL,
`belegDruckDatum` DATETIME NULL,
`belegPeriodenfremdeBuchung` TINYINT(1) NULL,
PRIMARY KEY (`belegid`, `gvfID`, `kassefID`),
CONSTRAINT `fk_tblBelege_tblBelegPositionen10`
FOREIGN KEY (`belegid`)
REFERENCES `mydb`.`tblBelegPositionen` (`belegfID`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_tblBelege_tblECKassenschnittPositionen10`
FOREIGN KEY (`belegid`)
REFERENCES `mydb`.`tblECKassenschnittPositionen` (`belegfID`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
SHOW WARNINGS;
Ok, so there are a couple of things to know here, as there were a couple of errors. You must check all the items that the error mentions, for correctness, to avoid trouble.
The cannot find an index in the referenced table portion of the error message means that the column/field specified in the REFERENCES clause must be indexed in the other table.
Then, the column type definition of the column specified in the FOREIGN KEY clause must match the column type of the column specified in the REFERENCES clause too, so even though the first item corrects part of the problem, there will still be an error related to another portion of the message: ...or column types in the table and the referenced table do not match.
So, to fix item 1, run these 2 queries:
ALTER TABLE `tblbelegpositionen` ADD INDEX(`belegfID`);
ALTER TABLE `tbleckassenschnittpositionen` ADD INDEX(`belegfID`);
Then to fix item 2, I had to change the first column of table tblBelege
from this:
`belegid` INT UNSIGNED NOT NULL AUTO_INCREMENT,
to this:
`belegid` INT NOT NULL,
...so that they matched the same type as the belegfID column as defined in the other tables. After those two changes, I was able to successfully run your CREATE TABLE `tblBelege` statement.
So, to recap:
Run your create table statements for tblbelegpositionen and
tbleckassenschnittpositionen.
Then run the 2 ALTER statements shown above for item 1.
Modify the first column of table tblBelege to match the column types as defined to belegfID in the other tables for item 2.
Then run your modified CREATE TABLE statement (with the item 2 change applied) to create the tblBelege table.
I'm a little confused about the same FOREIGN KEY referencing 2 different tables, but if it works for you, then ok. (not saying that it cannot be done, I've never used a foreign key that way) Perhaps you meant the opposite, to have a foreign key in the other 2 tables (1 in each table) that refer to tblBelege instead? If so, then you could add unsigned to the type definition for belegfID and it would work, and would not need the change that I mentioned with item 2.
Oh, and after you run the ALTER statements, you can view the table structure by running:
SHOW CREATE TABLE `tblbelegpositionen`;
SHOW CREATE TABLE `tbleckassenschnittpositionen`;
...to get the KEY definition that was added to include with your CREATE TABLE statements. Since they both create the same key, you really only need to run one of those statements and then add the KEY definition to both table statements.
When I create tables for my entities, Doctrine creates auth."user" table no problem:
[vagrant#localhost thiriscart]$ ./bin/console doctrine:schema:update --force --dump-sql
CREATE SCHEMA auth;
CREATE SCHEMA catalog;
CREATE SEQUENCE auth.user_id_seq INCREMENT BY 1 MINVALUE 1 START 1;
CREATE SEQUENCE catalog.category_id_seq INCREMENT BY 1 MINVALUE 1 START 1;
CREATE SEQUENCE catalog.product_id_seq INCREMENT BY 1 MINVALUE 1 START 1;
CREATE TABLE auth."user" (id INT NOT NULL, username VARCHAR(255) NOT NULL, PRIMARY KEY(id));
CREATE TABLE catalog.category (id INT NOT NULL, parent_id INT DEFAULT NULL, created_by INT NOT NULL, updated_by INT NOT NULL, title VARCHAR(255) NOT NULL, description TEXT NOT NULL, slug VARCHAR(255) NOT NULL, lft INT NOT NULL, rgt INT NOT NULL, root INT DEFAULT NULL, lvl INT NOT NULL, created_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, updated_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, PRIMARY KEY(id));
CREATE INDEX IDX_D3431049727ACA70 ON catalog.category (parent_id);
CREATE INDEX IDX_D3431049DE12AB56 ON catalog.category (created_by);
CREATE INDEX IDX_D343104916FE72E1 ON catalog.category (updated_by);
CREATE TABLE catalog.product (id INT NOT NULL, main_category INT NOT NULL, title VARCHAR(255) NOT NULL, digest TEXT NOT NULL, description TEXT NOT NULL, base_price NUMERIC(10, 2) NOT NULL, PRIMARY KEY(id));
CREATE INDEX IDX_BC02688FDF6E08B4 ON catalog.product (main_category);
ALTER TABLE catalog.category ADD CONSTRAINT FK_D3431049727ACA70 FOREIGN KEY (parent_id) REFERENCES catalog.category (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE;
ALTER TABLE catalog.category ADD CONSTRAINT FK_D3431049DE12AB56 FOREIGN KEY (created_by) REFERENCES auth."user" (id) NOT DEFERRABLE INITIALLY IMMEDIATE;
ALTER TABLE catalog.category ADD CONSTRAINT FK_D343104916FE72E1 FOREIGN KEY (updated_by) REFERENCES auth."user" (id) NOT DEFERRABLE INITIALLY IMMEDIATE;
ALTER TABLE catalog.product ADD CONSTRAINT FK_BC02688FDF6E08B4 FOREIGN KEY (main_category) REFERENCES catalog.category (id) NOT DEFERRABLE INITIALLY IMMEDIATE;
Updating database schema...
Database schema updated successfully! "16" queries were executed
But doesn't drop it:
[vagrant#localhost thiriscart]$ ./bin/console doctrine:schema:drop --force --dump-sql
ALTER TABLE catalog.category DROP CONSTRAINT fk_d3431049727aca70;
ALTER TABLE catalog.category DROP CONSTRAINT fk_d3431049de12ab56;
ALTER TABLE catalog.category DROP CONSTRAINT fk_d343104916fe72e1;
ALTER TABLE catalog.product DROP CONSTRAINT fk_bc02688fdf6e08b4;
DROP SEQUENCE auth.user_id_seq CASCADE;
DROP SEQUENCE catalog.category_id_seq CASCADE;
DROP SEQUENCE catalog.product_id_seq CASCADE;
DROP SEQUENCE ext_log_entries_id_seq CASCADE;
DROP SEQUENCE auth.user_id_seq CASCADE;
DROP SEQUENCE catalog.category_id_seq CASCADE;
DROP SEQUENCE catalog.product_id_seq CASCADE;
DROP SEQUENCE ext_translations_id_seq CASCADE;
DROP SEQUENCE ext_log_entries_id_seq CASCADE;
DROP TABLE ext_translations;
DROP TABLE ext_log_entries;
DROP TABLE catalog.category;
DROP TABLE catalog.product
Even with --full-database option the DROP TABLE statement is generated, but, apparently, not executed:
[vagrant#localhost thiriscart]$ ./bin/console doctrine:schema:drop --force --full-database --dump-sql
ALTER TABLE catalog.category DROP CONSTRAINT fk_d3431049727aca70;
ALTER TABLE catalog.category DROP CONSTRAINT fk_d3431049de12ab56;
ALTER TABLE catalog.category DROP CONSTRAINT fk_d343104916fe72e1;
ALTER TABLE catalog.product DROP CONSTRAINT fk_bc02688fdf6e08b4;
DROP SEQUENCE ext_log_entries_id_seq CASCADE;
DROP SEQUENCE ext_translations_id_seq CASCADE;
DROP SEQUENCE auth.user_id_seq CASCADE;
DROP SEQUENCE catalog.category_id_seq CASCADE;
DROP SEQUENCE catalog.product_id_seq CASCADE;
DROP TABLE ext_translations;
DROP TABLE ext_log_entries;
DROP TABLE auth."user";
DROP TABLE catalog.category;
DROP TABLE catalog.product
[vagrant#localhost thiriscart]$ ./bin/console doctrine:schema:update --force --dump-sql
CREATE TABLE auth."user" (id INT NOT NULL, username VARCHAR(255) NOT NULL, PRIMARY KEY(id));
ALTER TABLE catalog.category DROP CONSTRAINT FK_D3431049DE12AB56;
ALTER TABLE catalog.category DROP CONSTRAINT FK_D343104916FE72E1;
ALTER TABLE catalog.category ADD CONSTRAINT FK_D3431049DE12AB56 FOREIGN KEY (created_by) REFERENCES auth."user" (id) NOT DEFERRABLE INITIALLY IMMEDIATE;
ALTER TABLE catalog.category ADD CONSTRAINT FK_D343104916FE72E1 FOREIGN KEY (updated_by) REFERENCES auth."user" (id) NOT DEFERRABLE INITIALLY IMMEDIATE;
Updating database schema...
[Doctrine\DBAL\Exception\TableExistsException]
An exception occurred while executing 'CREATE TABLE auth."user" (id INT NOT NULL, username VARCHAR(255) NOT NULL, PRIM
ARY KEY(id))':
SQLSTATE[42P07]: Duplicate table: 7 ERROR: relation "user" already exists
[Doctrine\DBAL\Driver\PDOException]
SQLSTATE[42P07]: Duplicate table: 7 ERROR: relation "user" already exists
[PDOException]
SQLSTATE[42P07]: Duplicate table: 7 ERROR: relation "user" already exists
doctrine:schema:update [--complete] [--dump-sql] [-f|--force] [--em [EM]]
Use doctrine:schema:update with the --complete parameter to fully sync the database with your entities.
app/console doctrine:schema:update --force --complete
or
app/console doctrine:schema:update --dump-sql --complete
The Alembic migration for a SQLite database:
def upgrade():
with op.batch_alter_table('my_table') as batch_op:
batch_op.add_column(sa.Column('parent_id', sa.String(24)))
batch_op.create_foreign_key('parent_constraint', 'my_table', ['parent_id'], ['id'])
which is supposed to create a foreign key parent_id referencing id of the same table my_table, creates a reference to a table called _alembic_batch_temp:
CREATE TABLE "my_table" (
id VARCHAR(24) NOT NULL,
parent_id VARCHAR(24),
PRIMARY KEY (id),
CONSTRAINT parent_constraint FOREIGN KEY(parent_id) REFERENCES _alembic_batch_temp (id)
)
How to create self-referencing constraints when altering a table?
After some research I found that the problem here is the way Alembic does the batch migration. In short, at the current version (0.7.6) of Alembic it's not possible to create relation with self by migration.
As described in the Alembic documentation, to do the migration, new table is created with a temporary name and changes from the alter table
code. In this case:
CREATE TABLE _alembic_batch_temp (
id VARCHAR(24) NOT NULL,
parent_id VARCHAR(24),
PRIMARY KEY (id),
CONSTRAINT parent_constraint FOREIGN KEY(parent_id) REFERENCES _alembic_batch_temp (id)
)
The table is filled with the data from the old table:
INSERT INTO _alembic_batch_temp (id) SELECT id FROM my_table;
Then the old table is removed:
DROP TABLE my_table;
Finally the newly created table is renamed to it's proper name:
ALTER TABLE _alembic_batch_temp RENAME TO my_table;
The problem with this way of doing things is already visible in the first code snippet. The newly created foreign key is referencing the temporary table and once it's created it can't be changed due to restrictions in SQLite. So after the renaming of the table you end up with the table you provided:
CREATE TABLE "my_table" ( # new name
id VARCHAR(24) NOT NULL,
parent_id VARCHAR(24),
PRIMARY KEY (id),
CONSTRAINT parent_constraint FOREIGN KEY(parent_id) REFERENCES _alembic_batch_temp (id) # old reference
)
To Avoid this situation you can create the batch migration manually:
Rename the old table to some temporary name:
ALTER TABLE my_table RENAME TO migration_temp_table;
Create new table with proper name and proper reference:
CREATE TABLE my_table (
id VARCHAR(24) NOT NULL,
parent_id VARCHAR(24),
PRIMARY KEY (id),
CONSTRAINT parent_constraint FOREIGN KEY(parent_id) REFERENCES my_table (id)
)
Copy the data:
INSERT INTO my_table (id) SELECT id FROM migration_temp_table;
Remove the old table:
DROP TABLE migration_temp_table;