Doctrine/symfony:在相同的两个表上创建 2 个多对多关系(2 个中间表)

发布于 2024-11-28 19:16:32 字数 4679 浏览 2 评论 0原文

在我非常“罕见”的情况下,我必须在同一张表上创建2个多对多关系。 我解释一下: 我有两张桌子;监视器和服务器具有多对多关系的中间表将被称为“Benchmark”。但同时我必须有另一个中间表,它可以让我将监视器中的 url 与服务器中的多个 ip 连接起来(该表称为“Url_ip”) 所以这就是我所做的:

    Monitor:
      tableName: monitor
      actAs:
        Timestampable: ~
      columns:
        id : {type: integer(4), primary: true, autoincrement: true}
        label: {type: string(45)}
        url: {type: string(80)}
        frequency: {type: integer}
        timeout: {type: integer}
        method: {type: enum, values: [GET, POST]}
        parameters: {type: string(255)}
      relations:
        Groups:
          class: Groups
          local: monitor_id
          foreign: sf_guard_group_id
          refClass: Alert
        Server:
          class: Server
          local: monitor_id
          foreign: server_id
          refClass: Benchmark
        Server2:
          class: Server
          local: monitor_id
          foreign: server_id
          foreignAlias: Ips
          refClass: Url_ip

    Url_ip:
      actAs:
        Timestampable: ~
      columns:
        monitor_id: { type: integer(4), primary: true }
        server_id: { type: integer(4), primary: true }
      relations:
        Monitor:
          foreignAlias: IpUrls
        Server:
          foreignAlias: IpUrls       

    Benchmark:
      tableName: benchmark
      actAs:
        Timestampable: ~
      columns:
        monitor_id: { type: integer(4), primary: true }
        server_id: { type: integer(4), primary: true }
        connexionTime: {type: string(45)}
        executionTime: {type: string(45)}
        responseTime: {type: string(45)}
        responseCode: {type: string(45)}
        responseMessage: {type: string(45)}
      relations:
        Monitor:
          foreignAlias: ServerMonitors
        Server:
          foreignAlias: ServerMonitors



    Server:
      tableName: server
      actAs:
        TimeStampable: ~
      columns:
        id : {type: integer(4), primary: true,autoincrement: true}
        name: {type: string(255)}
        ip: {type: string(45)}
      relations:
        Monitor:
          class: Monitor
          local: server_id
          foreign: monitor_id
          refClass: Benchmark
        Monitor2:
          class: Monitor
          foreignAlias: monitors
          local: server_id
          foreign: monitor_id
          refClass: Url_ip


Alert:
  actAs:
    Timestampable: ~
  columns:
    monitor_id: { type: integer(4), primary: true }
    sf_guard_group_id: { type: integer, primary: true }
  relations:
    Monitor:
      foreignAlias: GroupMonitors
    sfGuardGroup:
      foreignAlias: GroupMonitors

实际上这似乎有效,因为学说可以创建相应的表。 问题出在加载夹具时。我有这个错误:

  SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a c
hild row: a foreign key constraint fails (`sfmonitoring`.`alert`, CONSTRAINT `al
ert_monitor_id_monitor_id` FOREIGN KEY (`monitor_id`) REFERENCES `monitor` (`id`
))

fixures/monitors.yml

Monitor:
  monitor_one:
    id: 1
    label: task1
    url: www.task1.com
    frequency: 5
    timeout: 30
    method: GET
    parameters: a=1&b=2

  monitor_two:
    id: 2
    label: task2
    url: www.task2.com
    frequency: 5
    timeout: 20
    method: POST
    parameters: a=11&b=22

  monitor_three:
    id: 3
    label: task3
    url: www.task3.com
    frequency: 10
    timeout: 30
    method: GET
    parameters: a=111&b=211

fixures/benchmark.yml

Benchmark: 
      bench_one:
        monitor_id: 1
        server_id: 1
        connexionTime: 25
        executionTime: 25
        responseTime: 25
        responseCode: 200
        responseMessage: message de réponse

      bench_two:
        monitor_id: 2
        server_id: 2
        connexionTime: 25
        executionTime: 25
        responseTime: 25
        responseCode: 200
        responseMessage: message de réponse

      bench_three:
        monitor_id: 3
        server_id: 3
        connexionTime: 25
        executionTime: 25
        responseTime: 25
        responseCode: 200
        responseMessage: message de réponse

      bench_Four:
        monitor_id: 1
        server_id: 2
        connexionTime: 25
        executionTime: 25
        responseTime: 25
        responseCode: 200
        responseMessage: message de réponse

fixures/alerts.yml

Alert:
  alert_a:
    monitor_id: 1
    sf_guard_group_id: 1

  alert_b:
    monitor_id: 2
    sf_guard_group_id: 2Alert:
  alert_a:
    monitor_id: 1
    sf_guard_group_id: 1

  alert_b:
    monitor_id: 2
    sf_guard_group_id: 2

HELP --------->求救

in my very "rare" case, i must create 2 many-to-many relations on the same tables.
I explain:
I have a two tables ; Monitor and Server having many to many rel the intermediate table will be called "Benchmark". But in the same time i have to have another intermediate table which can allow me to couple a url from a monitor to several ip's from the servers (the table is called "Url_ip")
So here is what i've done :

    Monitor:
      tableName: monitor
      actAs:
        Timestampable: ~
      columns:
        id : {type: integer(4), primary: true, autoincrement: true}
        label: {type: string(45)}
        url: {type: string(80)}
        frequency: {type: integer}
        timeout: {type: integer}
        method: {type: enum, values: [GET, POST]}
        parameters: {type: string(255)}
      relations:
        Groups:
          class: Groups
          local: monitor_id
          foreign: sf_guard_group_id
          refClass: Alert
        Server:
          class: Server
          local: monitor_id
          foreign: server_id
          refClass: Benchmark
        Server2:
          class: Server
          local: monitor_id
          foreign: server_id
          foreignAlias: Ips
          refClass: Url_ip

    Url_ip:
      actAs:
        Timestampable: ~
      columns:
        monitor_id: { type: integer(4), primary: true }
        server_id: { type: integer(4), primary: true }
      relations:
        Monitor:
          foreignAlias: IpUrls
        Server:
          foreignAlias: IpUrls       

    Benchmark:
      tableName: benchmark
      actAs:
        Timestampable: ~
      columns:
        monitor_id: { type: integer(4), primary: true }
        server_id: { type: integer(4), primary: true }
        connexionTime: {type: string(45)}
        executionTime: {type: string(45)}
        responseTime: {type: string(45)}
        responseCode: {type: string(45)}
        responseMessage: {type: string(45)}
      relations:
        Monitor:
          foreignAlias: ServerMonitors
        Server:
          foreignAlias: ServerMonitors



    Server:
      tableName: server
      actAs:
        TimeStampable: ~
      columns:
        id : {type: integer(4), primary: true,autoincrement: true}
        name: {type: string(255)}
        ip: {type: string(45)}
      relations:
        Monitor:
          class: Monitor
          local: server_id
          foreign: monitor_id
          refClass: Benchmark
        Monitor2:
          class: Monitor
          foreignAlias: monitors
          local: server_id
          foreign: monitor_id
          refClass: Url_ip


Alert:
  actAs:
    Timestampable: ~
  columns:
    monitor_id: { type: integer(4), primary: true }
    sf_guard_group_id: { type: integer, primary: true }
  relations:
    Monitor:
      foreignAlias: GroupMonitors
    sfGuardGroup:
      foreignAlias: GroupMonitors

Actually this appears to work because doctrine can create corresponding tables.
The problem is when loading the fixures. i have this error:

  SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a c
hild row: a foreign key constraint fails (`sfmonitoring`.`alert`, CONSTRAINT `al
ert_monitor_id_monitor_id` FOREIGN KEY (`monitor_id`) REFERENCES `monitor` (`id`
))

fixures/monitors.yml

Monitor:
  monitor_one:
    id: 1
    label: task1
    url: www.task1.com
    frequency: 5
    timeout: 30
    method: GET
    parameters: a=1&b=2

  monitor_two:
    id: 2
    label: task2
    url: www.task2.com
    frequency: 5
    timeout: 20
    method: POST
    parameters: a=11&b=22

  monitor_three:
    id: 3
    label: task3
    url: www.task3.com
    frequency: 10
    timeout: 30
    method: GET
    parameters: a=111&b=211

fixures/benchmark.yml

Benchmark: 
      bench_one:
        monitor_id: 1
        server_id: 1
        connexionTime: 25
        executionTime: 25
        responseTime: 25
        responseCode: 200
        responseMessage: message de réponse

      bench_two:
        monitor_id: 2
        server_id: 2
        connexionTime: 25
        executionTime: 25
        responseTime: 25
        responseCode: 200
        responseMessage: message de réponse

      bench_three:
        monitor_id: 3
        server_id: 3
        connexionTime: 25
        executionTime: 25
        responseTime: 25
        responseCode: 200
        responseMessage: message de réponse

      bench_Four:
        monitor_id: 1
        server_id: 2
        connexionTime: 25
        executionTime: 25
        responseTime: 25
        responseCode: 200
        responseMessage: message de réponse

fixures/alerts.yml

Alert:
  alert_a:
    monitor_id: 1
    sf_guard_group_id: 1

  alert_b:
    monitor_id: 2
    sf_guard_group_id: 2Alert:
  alert_a:
    monitor_id: 1
    sf_guard_group_id: 1

  alert_b:
    monitor_id: 2
    sf_guard_group_id: 2

HELP ---------> S.O.S

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

西瑶 2024-12-05 19:16:33

您的 Alert 模型是什么样的? (这是 Url_ip 吗?)

并且最好通过模型的键而不是 ID 来引用模型。

Monitor:
  monitor1:
    ....

Alert:
  alert_a:
    Monitor: monitor1
    Group: group1

因为您现在收到的错误意味着您添加了一个引用不存在的监视器的Alert。当Alert插入Monitor之前时可能会发生这种情况。通过通过 key 而不是 id 引用 Monitor,symfony 将首先插入 Monitor

What does your Alert model look like? (Is that the Url_ip?)

And it's better to reference models by their key instead of their ID.

Monitor:
  monitor1:
    ....

Alert:
  alert_a:
    Monitor: monitor1
    Group: group1

Because the error you're getting now, means that your adding an Alert with a reference to a non-existing monitor. This could happen when the Alert is inserted before the Monitor. By referencing to the Monitor by key instead of id, symfony will insert the Monitor first.

清音悠歌 2024-12-05 19:16:33

就这样,我发现了一个小技巧!
事实上在监视器中,我确实像你说的那样:使用了钥匙!
但在组中我处理正常,但使用的是 sfGuard 的 id,而不是我的!

Alert:
  alert_a:
    Monitor: monitor1
    sf_guard_group: group1

That's it, i found a small trick!
in fact in monitor, i did like you said : used the key !
but in the Group i processed normally, but using the sfGuard's id, and not mine !

Alert:
  alert_a:
    Monitor: monitor1
    sf_guard_group: group1
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文