       }
       
       for rs in entity.relationships {
-        guard let key = contraintKeyForRelationship(rs) else { continue }
-        guard !registeredJoins.contains(key)            else { continue }
+        guard let key = rs.constraintKey     else { continue }
+        guard !registeredJoins.contains(key) else { continue }
         relships.append(rs)
         registeredJoins.insert(key)
       }

  func columnNameForAttribute(_ attr: Attribute) -> String {
    // could also do a translation when missing
    return attr.columnName ?? attr.name
  }
  
  fileprivate func contraintKeyForRelationship(_ rs: Relationship) -> String? {
    guard !rs.joins.isEmpty else { return nil }

    func keyForJoin(_ join: Join) -> String {
      return (join.sourceName ?? "_") + "=>" + (join.destinationName ?? "_")
    }
    
    if rs.joins.count == 1 { return keyForJoin(rs.joins[0]) }
    
    let sortedJoins = rs.joins.map(keyForJoin).sorted()
    return sortedJoins.joined(separator: ",")
  }
  
  func createTableStatementsForEntityGroup(_ entities: [ Entity ],

    var statements = [ SQLExpression ]()
    statements.reserveCapacity(entities.count * 2)
    
    let entityGroups = entities.extractEntityGroups()
    
    if options.dropTables {
      for group in entityGroups {
