mongo_orm Exception : missing bson key : publish_acl (Exception)

Lorsque vous étendez vos définitions de champs dans les classes de documents mongo_orm, notamment avec des documents intégrés, vous pouvez rencontrer l'erreur d'exécution suivante ( !):

Exception : clé bson manquante : (Exception)

Ce n'est pas une erreur dans votre code - votre code se lève, parce que la structure de la base de données n'est pas comme il s'attend à ce qu'elle soit !

Voici l'exemple de code que j'utilise pour créer une base de données Auth & ACL Mongo pour VerneMQ :

classe PublishACL < Mongo::ORM::EmbeddedDocument
     modèle de champ : Chaîne
     champ max_qos : Int32
     champ allowed_retain : Bool
     champ max_payload_size : Int32
fin

classe SubscribeACL < Mongo::ORM::EmbeddedDocument
     modèle de champ : Chaîne
     champ max_qos : Int32
fin

class MQTTCredentials < Mongo::ORM::Document
     nom_collection "vmq_acl_auth"
     field mountpoint : String
     champ client_id : String
     field username : String
     field passhash : String
     embeds_many :publish_acl, class_name : Papi::PublishACL 
     embeds_many :subscribe_acl, class_name : Papi::SubscribeACL

Les clés # sont uniques par apikey_prefix.
def self.getcredentials(apikey_prefix : String, bcm_serial : String)
     succès = faux
     1TP3Si les informations d'identification n'existent pas encore, elles sont ajoutées.
     creds = self.first({"client_id" => bcm_serial, "username" => apikey_prefix})
     if !creds
         creds = self.new()
     fin

     (snip)

    publish_acl = PublishACL.new()
     subscribe_acl = SubscribeACL.new()
     # https://vernemq.com/docs/configuration/db-auth.html
     publish_acl.pattern = "#" (en anglais)
     publish_acl.max_qos = 2 # Int
     publish_acl.allowed_retain = true

    subscribe_acl.pattern = "#"
     subscribe_acl.max_qos = 2
    
     creds.publish_acl << publish_acl
     creds.subscribe_acl << subscribe_acl 
     succès = creds.save

(snip)

fin

fin

Les ACL ont été insérées alors que j'avais déjà des entrées de base de données sans elles :

image

Message d'erreur de MongoORM :

Exception : clé bson manquante : publish_acl (Exception)
   de src/db.cr:0:4 in 'from_bson' (en anglais)
   from lib/mongo_orm/src/mongo_orm/querying.cr:93:7 in 'all'.
   from lib/mongo_orm/src/mongo_orm/querying.cr:90:3 in 'all' (en anglais)

  (snip)

  à partir de /usr/share/crystal/src/fiber.cr:47:34 dans '->'.
   de ? ??

MongoORM ne trouve pas les champs attendus publish_acl et subscribe_acl, qui ont été ajoutés ultérieurement.

Solution : abandonnez (ou mettez à niveau) les documents de la collection qui ne sont pas conformes à votre nouvelle norme.

Voici, par exemple, à quoi ressemble une entrée de base de données pour l'exemple ci-dessus :

image

Bonus

dans lib/mongo_orm/src/mongo_orm/extended_bson.cr:40 : no overload matches 'BSON#[]=' with types String, Array(Papi::PublishACL)

Les surcharges le sont :

- BSON#[]=(key, value : Int32)

- BSON#[]=(key, value : Int64)

- BSON#[]=(clé, valeur : Binaire)

- BSON#[]=(clé, valeur : Bool)

- BSON#[]=(clé, valeur : Float64 | Float32)

- BSON#[]=(clé, valeur : MinKey)

- BSON#[]=(clé, valeur : MaxKey)

- BSON#[]=(clé, valeur : néant)

- BSON#[]=(key, value : ObjectId)

- BSON#[]=(key, value : String)

- BSON#[]=(clé, valeur : Symbole)

- BSON#[]=(clé, valeur : Temps)

- BSON#[]=(key, value : Timestamp)

- BSON#[]=(clé, valeur : Code)

- BSON#[]=(clé, valeur : BSON)

- BSON#[]=(clé, valeur : Regex)

- BSON#[]=(key, value : Mongo::ORM::EmbeddedDocument)

bson[_key] = valeur

Vous ne peut pas faire cela (actuellement) avec MongoORM :

creds.publish_acl = [ publish_acl ].

à la place, vous devez utiliser :

creds.publish_acl << publish_acl