PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Skojarzenia w sequelize nie działają zgodnie z przeznaczeniem

Jest wiele problemów. Spróbuję rozwiązać je stopniowo.

1) Modele Domyślnie, jeśli nie zadeklarujesz primaryKey , a następnie sequelize automatycznie dodaje id kolumna dla Ciebie. Zatem legId nie jest użyteczną kolumną.

Ponadto, jeśli skojarzysz model, foreignKey odniesienie zostało dodane dla Ciebie, dlatego pawId nie powinno być deklarowane.

Zatem Legs.js należy zmodyfikować do:

module.exports = (sequelize, DataTypes) => {
  var Leg = sequelize.define('Leg', {
    originalValue: DataTypes.JSON,
    newValue: DataTypes.JSON,
    objectId: DataTypes.INTEGER // not entirely sure what this is 
  })
  Leg.associate = function (models) {
    // associations
  }
  return Leg
}

Powyższe daje mi następujące kolumny w pgAdmin :

2) Powiązania

Poniższe powiązanie nie ma sensu i powinno spowodować błąd:

Leg.hasOne(Paw)
Paw.hasMany(Leg)

Unhandled rejection Error: Cyclic dependency found. Legs is dependent of itself.
Dependency chain: Legs -> Paws => Legs

Każda Leg powinien mieć jedną Paw , dlatego proponuję następujące:

Leg.associate = function (models) {
  // Leg.belongsTo(models.Cat)
  Leg.hasOne(models.Paw, {
    foreignKey: 'pawId',
    as: 'paw'
  })
}

Paw.associate = function (models) {
  Paw.belongsTo(models.Leg, {
    as: 'leg' // note this changed to make more sense
    foreignKey: 'pawId'
  })
}

3) Klucze obce

Leg.belongsTo(models.Cat, {
  foreignKey: 'catId', // this should match
  onDelete: 'CASCADE'
})

Cat.hasMany(models.Leg, {
  foreignKey: 'catId', // this should match
  as: 'legs'
})

4) Chętne ładowanie

Przy gorliwym ładowaniu zagnieżdżonych asocjacji, musisz include ich. Powinieneś także użyć as alias pasujący do skojarzeń modelu:

Cat.findAll({
  include: [{
    model: Leg,
    as: 'legs', // Cat.legs 
    include: [{
      model: Paw,
      as: 'paw' // Leg.paw instead of Leg.pawId
    }]
  }]
})

Używając całej tej konfiguracji i powyższego zapytania, otrzymuję:

[
  {
    "id": 1,
    "userId": "1",
    "createdAt": "2018-04-15T11:22:59.888Z",
    "updatedAt": "2018-04-15T11:22:59.888Z",
    "legs": [
      {
        "id": 1,
        "originalValue": null,
        "newValue": null,
        "objectId": null,
        "createdAt": "2018-04-15T11:22:59.901Z",
        "updatedAt": "2018-04-15T11:22:59.901Z",
        "catId": 1,
        "paw": {
          "id": 1,
          "pawType": null,
          "createdAt": "2018-04-15T11:22:59.906Z",
          "updatedAt": "2018-04-15T11:22:59.906Z",
          "pawId": 1
        }
      }
    ]
  }
]

Dodatkowe

Ponieważ jest to oczywiście konfiguracja ćwiczeniowa, możesz zmodyfikować Paw być belongsToMany relacja (może połączyłeś koty łapą?) w następujący sposób:

Paw.associate = function (models) {
  Paw.belongsToMany(models.Leg, {
    foreignKey: 'pawId',
    through: 'PawLegs  // a through join table MUST be defined
  })
}

Byłby to właściwy sposób na zaimplementowanie tego, co początkowo próbowałeś za pomocą

Leg.hasOne(paw)
paw.hasMany(leg)



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. PostgreSQL jak stworzyć kopię bazy danych lub schematu?

  2. Funkcja Postgres zwracająca wiersz jako wartość JSON

  3. Wybieranie wierszy uporządkowanych według jednej kolumny i odrębnych w innej

  4. Obraz natywny danych Micronaut:nie istnieje bean typu [io.micronaut.data.operations.PrimaryRepositoryOperations]

  5. Lista wszystkich kluczy obcych PostgreSQL