bcc-code / directus-schema-sync

The better way to sync your Directus schema and data between environments
Apache License 2.0
90 stars 4 forks source link

Issue: Order of importing items #15

Closed bernatvadell closed 5 months ago

bernatvadell commented 5 months ago

Describe the Bug

When importing the operations, they were exported without taking into account the order of dependencies. That is, if an operation "resolves" another operation, and it is inside the array, it is usually created later.

Console error:

ERROR: Invalid foreign key for field "resolve" in collection "directus_operations".
    err: {
      "type": "",
      "message": "Invalid foreign key for field \"resolve\" in collection \"directus_operations\".",
      "stack":
          DirectusError: Invalid foreign key for field "resolve" in collection "directus_operations".
              at foreignKeyViolation (directus/node_modules/.pnpm/@directus+api@15.0.0_@unhead+vue@1.8.9_pinia@2.1.7_vue@3.3.13/node_modules/@directus/api/dist/database/errors/dialects/postgres.js:87:12)
              at extractError directus/node_modules/.pnpm/@directus+api@15.0.0_@unhead+vue@1.8.9_pinia@2.1.7_vue@3.3.13/node_modules/@directus/api/dist/database/errors/dialects/postgres.js:21:20)
              at translateDatabaseError (directus/node_modules/.pnpm/@directus+api@15.0.0_@unhead+vue@1.8.9_pinia@2.1.7_vue@3.3.13/node_modules/@directus/api/dist/database/errors/translate.js:26:28)
              at directus/node_modules/.pnpm/@directus+api@15.0.0_@unhead+vue@1.8.9_pinia@2.1.7_vue@3.3.13/node_modules/@directus/api/dist/services/items.js:148:29
              at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
      "name": "DirectusError",
      "extensions": {
        "collection": "directus_operations",
        "field": "resolve"
      },
      "code": "INVALID_FOREIGN_KEY",
      "status": 400
    }

To Reproduce

Deploy a new directus instance, create a flow with two connected operations. Install the library and export the data. You should see something like this:

[
...
{
    "date_created": "2023-07-21T11:00:36.940Z",
    "flow": "f958b0d6-671d-4f51-8122-31f4935495d8",
    "id": "4d8c8f04-a8b3-4f99-a64c-51a9574280d7",
    "key": "read_viaje",
    "name": "ReadViaje",
    "options": {
      "collection": "viaje",
      "query": {
        "filter": {
          "id": {
            "_eq": "{{read_item_viaje[0].viaje}}"
          }
        }
      }
    },
    "position_x": 57,
    "position_y": 1,
    "reject": null,
    "resolve": "d3ebf874-55a2-4b27-bcf0-95171bb10146",
    "type": "item-read"
  },
  {
    "date_created": "2023-07-24T08:31:21.194Z",
    "flow": "f958b0d6-671d-4f51-8122-31f4935495d8",
    "id": "d3ebf874-55a2-4b27-bcf0-95171bb10146",
    "key": "obtener_empresa",
    "name": "ObtenerEmpresa",
    "options": {
      "collection": "empresa",
      "query": {
        "filter": {
          "id": {
            "_eq": "{{read_viaje[0].empresa}}"
          }
        }
      }
    },
    "position_x": 2,
    "position_y": 17,
    "reject": null,
    "resolve": "25f29ceb-f1f4-4928-a05f-56ce50d69964",
    "type": "item-read"
  }
  ....
  ]

In this case, the operation will be inserted first: 4d8c8f04-a8b3-4f99-a64c-51a9574280d7, and this has in the resolve column the operation: "d3ebf874-55a2-4b27-bcf0-95171bb10146" which, as it does not yet exist in the database , will give an FK error.

I had thought that it might be interesting to disable the FKs during the synchronization process, and enable them again once it is finished. In case of error, we would rollback the transaction.

Version

1.6.1

Installed Extension Via

NPM Custom

u12206050 commented 5 months ago

Ah right good point. Will have to check this out a bit to see how to solve it.

bposman commented 5 months ago

I've encountered this error with our own sync system, flows/operations is unique as far as I can see having a circular reference. The only way I found to do it is to run in two passes with the first time omitting the resolve column.

u12206050 commented 5 months ago

Good news. This is now fixed in version 1.6.3 You would need to update the directus_config.json file and add linkedFields to directus_operations:


{
      directus_operations: {
        watch: ['operations'],
        excludeFields: ['user_created'],
        linkedFields: ['resolve', 'reject'], // <<--- This tells the sync to check these two fields and order inserts accordingly
        query: {
          filter: {
            flow: { trigger: { _neq: 'webhook' } },
          },
        },
      },
    }```