Symfony:加载具有多列主键(也是外键)的对象的固定装置
我在 symfony 中为我的项目编写固定装置,当我尝试将固定装置添加到具有多列主键的对象时遇到问题,该主键也是其他表的外键。
这是 MySql Workbench 中的架构:
我使用 Workbench 生成了 sql 代码,然后生成 < code>schema.yml 文件,其中包含 symfony 任务 php symfonydoctrine:build-schema
。
这是为这些表生成的 sql:
-- -----------------------------------------------------
-- Table `mydb`.`MetodoEnvio`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `mydb`.`MetodoEnvio` ;
CREATE TABLE IF NOT EXISTS `mydb`.`MetodoEnvio` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
`nombre` VARCHAR(45) NOT NULL ,
`precio` DECIMAL(10,2) NOT NULL ,
PRIMARY KEY (`id`) )
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_general_ci;
-- -----------------------------------------------------
-- Table `mydb`.`ZonaEnvio`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `mydb`.`ZonaEnvio` ;
CREATE TABLE IF NOT EXISTS `mydb`.`ZonaEnvio` (
`id` INT UNSIGNED NOT NULL ,
`numero` INT(3) UNSIGNED NOT NULL ,
`etiqueta` VARCHAR(255) NOT NULL ,
PRIMARY KEY (`id`, `numero`) ,
INDEX `fk_ZonaEnvio_MetodoEnvio` (`id` ASC) ,
INDEX `numeroZona_INDEX` (`numero` ASC) ,
CONSTRAINT `fk_ZonaEnvio_MetodoEnvio`
FOREIGN KEY (`id` )
REFERENCES `mydb`.`MetodoEnvio` (`id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_general_ci;
-- -----------------------------------------------------
-- Table `mydb`.`PrecioEnvio`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `mydb`.`PrecioEnvio` ;
CREATE TABLE IF NOT EXISTS `mydb`.`PrecioEnvio` (
`idMetodo` INT UNSIGNED NOT NULL ,
`zona` INT(3) UNSIGNED NOT NULL ,
`inicioRango` DECIMAL(10,2) NOT NULL COMMENT 'Marca el inicio del rango de peso para el cual este precio aplica.' ,
`finRango` DECIMAL(10,2) NULL COMMENT 'Marca el fin del rango de peso para el cual este precio aplica.' ,
`precio` DECIMAL(10,2) NOT NULL ,
PRIMARY KEY (`idMetodo`, `inicioRango`, `finRango`, `zona`) ,
INDEX `fk_PrecioEnvio_ZonaEnvio` (`idMetodo` ASC, `zona` ASC) ,
CONSTRAINT `fk_PrecioEnvio_ZonaEnvio`
FOREIGN KEY (`idMetodo` , `zona` )
REFERENCES `mydb`.`ZonaEnvio` (`id` , `numero` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_general_ci;
-- -----------------------------------------------------
-- Table `mydb`.`IntervaloMetodoEnvio`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `mydb`.`IntervaloMetodoEnvio` ;
CREATE TABLE IF NOT EXISTS `mydb`.`IntervaloMetodoEnvio` (
`idMetodo` INT UNSIGNED NOT NULL ,
`zona` INT(3) UNSIGNED NOT NULL ,
`intervalo` DECIMAL(10,2) NOT NULL ,
`precio` DECIMAL(10,2) NOT NULL ,
PRIMARY KEY (`idMetodo`, `zona`) ,
INDEX `fk_IntervaloMetodoEnvio_ZonaEnvio` (`idMetodo` ASC, `zona` ASC) ,
CONSTRAINT `fk_IntervaloMetodoEnvio_ZonaEnvio`
FOREIGN KEY (`idMetodo` , `zona` )
REFERENCES `mydb`.`ZonaEnvio` (`id` , `numero` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_general_ci;
这是为这些表生成的模式:
MetodoEnvio:
connection: doctrine
tableName: MetodoEnvio
columns:
id:
type: integer(4)
fixed: false
unsigned: true
primary: true
autoincrement: true
nombre:
type: string(45)
fixed: false
unsigned: false
primary: false
notnull: true
autoincrement: false
precio:
type: 'decimal(10, 2)'
fixed: false
unsigned: false
primary: false
notnull: true
autoincrement: false
relations:
TiendaOrden:
local: id
foreign: metodoenvio
type: many
ZonaEnvio:
local: id
foreign: id
type: many
ZonaEnvio:
connection: doctrine
tableName: ZonaEnvio
columns:
id:
type: integer(4)
fixed: false
unsigned: true
primary: true
autoincrement: false
numero:
type: integer(4)
fixed: false
unsigned: true
primary: true
autoincrement: false
etiqueta:
type: string(255)
fixed: false
unsigned: false
primary: false
notnull: true
autoincrement: false
relations:
MetodoEnvio:
local: id
foreign: id
type: one
IntervaloMetodoEnvio:
local: id
foreign: idmetodo
type: many
IntervaloMetodoEnvio_2:
class: IntervaloMetodoEnvio
local: numero
foreign: zona
type: many
PrecioEnvio:
local: id
foreign: idmetodo
type: many
PrecioEnvio_2:
class: PrecioEnvio
local: numero
foreign: zona
type: many
PrecioEnvio:
connection: doctrine
tableName: PrecioEnvio
columns:
idmetodo:
type: integer(4)
fixed: false
unsigned: true
primary: true
autoincrement: false
zona:
type: integer(4)
fixed: false
unsigned: true
primary: true
autoincrement: false
iniciorango:
type: 'decimal(10, 2)'
fixed: false
unsigned: false
primary: true
autoincrement: false
finrango:
type: 'decimal(10, 2)'
fixed: false
unsigned: false
primary: true
autoincrement: false
precio:
type: 'decimal(10, 2)'
fixed: false
unsigned: false
primary: false
notnull: true
autoincrement: false
relations:
ZonaEnvio:
local: idmetodo
foreign: id
type: one
ZonaEnvio_2:
class: ZonaEnvio
local: zona
foreign: numero
type: one
IntervaloMetodoEnvio:
connection: doctrine
tableName: IntervaloMetodoEnvio
columns:
idmetodo:
type: integer(4)
fixed: false
unsigned: true
primary: true
autoincrement: false
zona:
type: integer(4)
fixed: false
unsigned: true
primary: true
autoincrement: false
intervalo:
type: 'decimal(10, 2)'
fixed: false
unsigned: false
primary: false
notnull: true
autoincrement: false
precio:
type: 'decimal(10, 2)'
fixed: false
unsigned: false
primary: false
notnull: true
autoincrement: false
relations:
ZonaEnvio:
local: idmetodo
foreign: id
type: one
ZonaEnvio_2:
class: ZonaEnvio
local: zona
foreign: numero
type: one
然后,我编写了以下固定装置:
MetodoEnvio:
personal:
nombre: Retiro Personal
precio: 0.0
mrw:
nombre: MRW
precio: 5.0
dhl:
nombre: DHL
precio: -1.0
ZonaEnvio:
dhl_zona1:
MetodoEnvio: dhl
numero: 1
etiqueta: DHL (Envios en la Zona Metropolitana)
dhl_zona5:
MetodoEnvio: dhl
numero: 5
etiqueta: DHL (Envios al interior del pais)
PrecioEnvio:
fila1_zona1:
ZonaEnvio: dhl_zona1
inicioRango: 0.00
finRango: 0.50
precio: 26.90
fila1_zona5:
ZonaEnvio: dhl_zona5
inicioRango: 00
finRango: 0.50
precio: 59.60
IntervaloMetodoEnvio:
dhl_zona_1:
ZonaEnvio: dhl_zona1
intervalo: 0.5
precio: 3.05
dhl_zona_5:
ZonaEnvio: dhl_zona5
intervalo: 0.5
precio: 7.15
当我执行命令 php symfonydoctrine:data-load
时,它返回错误:
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`mydb`.`PrecioEnvio`, CONSTRAINT `fk_PrecioEnvio_ZonaEnvio` FOREIGN KEY (`idMetodo`, `zona`) REFERENCES `ZonaEnvio` (`id`, `numero`) ON DELETE NO ACTION ON UPDATE NO ACTION)
由于错误与外键有关,我认为它可能与我在架构中的引用有关,如 ZonaEnvio: dhl_zona1
等行。我如何引用“父对象”?我认为这不像继承,而是像一种弱关系...
请原谅我的问题太长,但我想为您提供所有必要的信息,以便您可以帮助我!
非常感谢您的帮助!
im writing fixtures for my project in symfony, and i have preblems when trying to add fixtures to objects with a multiple column primary key, which is also foreign key to other table.
Here's the schema in MySql Workbench:
I generated the sql code with workbench, and then generated the schema.yml
file with the symfony task php symfony doctrine:build-schema
.
this is the sql generated for these tables:
-- -----------------------------------------------------
-- Table `mydb`.`MetodoEnvio`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `mydb`.`MetodoEnvio` ;
CREATE TABLE IF NOT EXISTS `mydb`.`MetodoEnvio` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
`nombre` VARCHAR(45) NOT NULL ,
`precio` DECIMAL(10,2) NOT NULL ,
PRIMARY KEY (`id`) )
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_general_ci;
-- -----------------------------------------------------
-- Table `mydb`.`ZonaEnvio`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `mydb`.`ZonaEnvio` ;
CREATE TABLE IF NOT EXISTS `mydb`.`ZonaEnvio` (
`id` INT UNSIGNED NOT NULL ,
`numero` INT(3) UNSIGNED NOT NULL ,
`etiqueta` VARCHAR(255) NOT NULL ,
PRIMARY KEY (`id`, `numero`) ,
INDEX `fk_ZonaEnvio_MetodoEnvio` (`id` ASC) ,
INDEX `numeroZona_INDEX` (`numero` ASC) ,
CONSTRAINT `fk_ZonaEnvio_MetodoEnvio`
FOREIGN KEY (`id` )
REFERENCES `mydb`.`MetodoEnvio` (`id` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_general_ci;
-- -----------------------------------------------------
-- Table `mydb`.`PrecioEnvio`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `mydb`.`PrecioEnvio` ;
CREATE TABLE IF NOT EXISTS `mydb`.`PrecioEnvio` (
`idMetodo` INT UNSIGNED NOT NULL ,
`zona` INT(3) UNSIGNED NOT NULL ,
`inicioRango` DECIMAL(10,2) NOT NULL COMMENT 'Marca el inicio del rango de peso para el cual este precio aplica.' ,
`finRango` DECIMAL(10,2) NULL COMMENT 'Marca el fin del rango de peso para el cual este precio aplica.' ,
`precio` DECIMAL(10,2) NOT NULL ,
PRIMARY KEY (`idMetodo`, `inicioRango`, `finRango`, `zona`) ,
INDEX `fk_PrecioEnvio_ZonaEnvio` (`idMetodo` ASC, `zona` ASC) ,
CONSTRAINT `fk_PrecioEnvio_ZonaEnvio`
FOREIGN KEY (`idMetodo` , `zona` )
REFERENCES `mydb`.`ZonaEnvio` (`id` , `numero` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_general_ci;
-- -----------------------------------------------------
-- Table `mydb`.`IntervaloMetodoEnvio`
-- -----------------------------------------------------
DROP TABLE IF EXISTS `mydb`.`IntervaloMetodoEnvio` ;
CREATE TABLE IF NOT EXISTS `mydb`.`IntervaloMetodoEnvio` (
`idMetodo` INT UNSIGNED NOT NULL ,
`zona` INT(3) UNSIGNED NOT NULL ,
`intervalo` DECIMAL(10,2) NOT NULL ,
`precio` DECIMAL(10,2) NOT NULL ,
PRIMARY KEY (`idMetodo`, `zona`) ,
INDEX `fk_IntervaloMetodoEnvio_ZonaEnvio` (`idMetodo` ASC, `zona` ASC) ,
CONSTRAINT `fk_IntervaloMetodoEnvio_ZonaEnvio`
FOREIGN KEY (`idMetodo` , `zona` )
REFERENCES `mydb`.`ZonaEnvio` (`id` , `numero` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_general_ci;
this is the schema generated for these tables:
MetodoEnvio:
connection: doctrine
tableName: MetodoEnvio
columns:
id:
type: integer(4)
fixed: false
unsigned: true
primary: true
autoincrement: true
nombre:
type: string(45)
fixed: false
unsigned: false
primary: false
notnull: true
autoincrement: false
precio:
type: 'decimal(10, 2)'
fixed: false
unsigned: false
primary: false
notnull: true
autoincrement: false
relations:
TiendaOrden:
local: id
foreign: metodoenvio
type: many
ZonaEnvio:
local: id
foreign: id
type: many
ZonaEnvio:
connection: doctrine
tableName: ZonaEnvio
columns:
id:
type: integer(4)
fixed: false
unsigned: true
primary: true
autoincrement: false
numero:
type: integer(4)
fixed: false
unsigned: true
primary: true
autoincrement: false
etiqueta:
type: string(255)
fixed: false
unsigned: false
primary: false
notnull: true
autoincrement: false
relations:
MetodoEnvio:
local: id
foreign: id
type: one
IntervaloMetodoEnvio:
local: id
foreign: idmetodo
type: many
IntervaloMetodoEnvio_2:
class: IntervaloMetodoEnvio
local: numero
foreign: zona
type: many
PrecioEnvio:
local: id
foreign: idmetodo
type: many
PrecioEnvio_2:
class: PrecioEnvio
local: numero
foreign: zona
type: many
PrecioEnvio:
connection: doctrine
tableName: PrecioEnvio
columns:
idmetodo:
type: integer(4)
fixed: false
unsigned: true
primary: true
autoincrement: false
zona:
type: integer(4)
fixed: false
unsigned: true
primary: true
autoincrement: false
iniciorango:
type: 'decimal(10, 2)'
fixed: false
unsigned: false
primary: true
autoincrement: false
finrango:
type: 'decimal(10, 2)'
fixed: false
unsigned: false
primary: true
autoincrement: false
precio:
type: 'decimal(10, 2)'
fixed: false
unsigned: false
primary: false
notnull: true
autoincrement: false
relations:
ZonaEnvio:
local: idmetodo
foreign: id
type: one
ZonaEnvio_2:
class: ZonaEnvio
local: zona
foreign: numero
type: one
IntervaloMetodoEnvio:
connection: doctrine
tableName: IntervaloMetodoEnvio
columns:
idmetodo:
type: integer(4)
fixed: false
unsigned: true
primary: true
autoincrement: false
zona:
type: integer(4)
fixed: false
unsigned: true
primary: true
autoincrement: false
intervalo:
type: 'decimal(10, 2)'
fixed: false
unsigned: false
primary: false
notnull: true
autoincrement: false
precio:
type: 'decimal(10, 2)'
fixed: false
unsigned: false
primary: false
notnull: true
autoincrement: false
relations:
ZonaEnvio:
local: idmetodo
foreign: id
type: one
ZonaEnvio_2:
class: ZonaEnvio
local: zona
foreign: numero
type: one
Then, i wrote the following fixtures:
MetodoEnvio:
personal:
nombre: Retiro Personal
precio: 0.0
mrw:
nombre: MRW
precio: 5.0
dhl:
nombre: DHL
precio: -1.0
ZonaEnvio:
dhl_zona1:
MetodoEnvio: dhl
numero: 1
etiqueta: DHL (Envios en la Zona Metropolitana)
dhl_zona5:
MetodoEnvio: dhl
numero: 5
etiqueta: DHL (Envios al interior del pais)
PrecioEnvio:
fila1_zona1:
ZonaEnvio: dhl_zona1
inicioRango: 0.00
finRango: 0.50
precio: 26.90
fila1_zona5:
ZonaEnvio: dhl_zona5
inicioRango: 00
finRango: 0.50
precio: 59.60
IntervaloMetodoEnvio:
dhl_zona_1:
ZonaEnvio: dhl_zona1
intervalo: 0.5
precio: 3.05
dhl_zona_5:
ZonaEnvio: dhl_zona5
intervalo: 0.5
precio: 7.15
When i do the command php symfony doctrine:data-load
, it returns the error:
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`mydb`.`PrecioEnvio`, CONSTRAINT `fk_PrecioEnvio_ZonaEnvio` FOREIGN KEY (`idMetodo`, `zona`) REFERENCES `ZonaEnvio` (`id`, `numero`) ON DELETE NO ACTION ON UPDATE NO ACTION)
Since the error has to do with foreign keys, i think it might have something to do with my references in the schema, in lines like ZonaEnvio: dhl_zona1
. How do i reference the "parent object"? I think this is not like an inheritance but instead like a weak relationship...
Please forgive the length of my question, but i wanted to provide you with all the necessary information so you can help me!
THANK YOU VERY MUCH FOR YOUR HELP!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是一个 mysql 约束错误,这意味着要插入的值在相关表中不存在。
您的装置格式与我对版本 1.x symfony/doctrine 组合的理解不符。查看此帮助以了解正确的格式: http:// www.symfony-project.org/doctrine/1_2/en/05-Data-Fixtures。例如,创建 id 为 1 的行:
然后,当您需要引用与 id = 1 的 MetodoEnvio 相关的表时,您可以使用 MetodoEnvio_1,尽管您可能可以简单地使用 id: 1,因为知道 id 将为 1 。
That is a mysql constraint error which means the value being inserted does not exist in the related table.
Your fixture format does not match my understanding of what it should be for the version 1.x symfony/doctrine combination. Take a look at this help for the proper format: http://www.symfony-project.org/doctrine/1_2/en/05-Data-Fixtures. For example, creating a row with id 1:
Then when you need to refer to a table that relates to MetodoEnvio with id = 1, you can utilize MetodoEnvio_1, although you probably can simply use id: 1, knowing that the id will be 1.
我发现问题是什么了。它与 schema.yml 文件中关系的定义方式有关。请注意,它表示定义与同一类的两个关系的两个字段主键:
Relatios 在
PrecioEnvio
和IntervaloMetodoEnvio
中定义如下,这两个都是ZonaEnvio
的弱实体代码>.因此,我只需要为我的装置中的两个关系提供值,并将它们指向先前定义的ZonaEnvio
对象的同一实例。像这样:注意
两条线都在同一个夹具定义中并指向同一个实例。这样,装置就成功加载了。
无论如何,感谢您的努力gview!
I found what the problem was. It has to do with how the relations were defined in the
schema.yml
file. Notice it represents the two fields primary key defining two relations to the same class:Relatios are defined like this in
PrecioEnvio
andIntervaloMetodoEnvio
, both weak entities ofZonaEnvio
. So, I just needed to give values for both relations in my fixtures, and point them to the same instance of theZonaEnvio
object previously defined. Like this:Notice
both lines are in the same fixture definition and point to the same instance. That way, fixtures are successfully loaded.
Thanks anyways for your efforts gview!