11
votes

La `` propriété '' attendue doit être de type chaîne, mais plutôt un objet de type trouvé - Dynamoose

Je travaille avec AWS DynamoDB et Dynamoose pour essayer de récupérer des enregistrements à l'aide de la fonction Scan , mais je suis confronté à un problème qui ne m'est pas reconnaissable.

Stragenly, il est capable de récupérer les enregistrements d'une autre table de la même manière et d'obtenir les enregistrements avec succès.

Voici mon code:

const vehicleMasterSchema = new dynamoose.Schema({
    "id": String,
    "customer_account_number": String,
    "fuel_type": String,
    "make": String,
    "model": String,
    "odometer_gatex": String,
    "plate_no": String,
    "rfid_gatex": String,
    "sales_agreement_id": String,
    "vehicle_category": String,
    "vehicle_id": String,
}, {
    "timestamps": {
        "createdAt": "create_date",
        "updatedAt": null // updatedAt will not be stored as part of the timestamp
    }
});
const vehicleMasterModel = dynamoose.model("vehicle_master", vehicleMasterSchema, { "create": false });

router.post('/getFuelingStatus', (req, res) => {
    var companyInfo = req.body;
    try {
        console.log(typeof vehicleMasterModel);
        vehicleMasterModel.scan("customer_account_number").eq(companyInfo.customerId).exec((error, results) => {
            if (error) {
                console.error(error);
            } else {
                res.json(results);
            }
        });
    } catch (error) {
        res.json(error);
    }
});

L'erreur TypeMismatch uniquement pour ce modèle, le même code fonctionne pour l'autre table.

Erreur de console

erreur de console

Ma table

données de table

Cela semble être lié à ce problème de github sur Dyanmoose


8 commentaires

Je suppose que vous avez une valeur de propriété qui est null dans votre table.


@CharlieFish rien n'est nul dans ma table.


Hmm. Je ne sais pas ce que cela pourrait être alors. J'aurais probablement besoin de plus d'informations sur les éléments / documents de votre tableau. Je ne pense pas que je serais capable de reproduire cela avec les informations que vous avez fournies. Il y a un élément que l'on essaie d'analyser là où le model s'attend à ce qu'il s'agisse d'une chaîne mais à la place d'un objet.


Avez-vous des valeurs de propriété nulles?


non, chaque colonne a toujours sa valeur. @CharlieFish


Quand j'ai travaillé avec Dynamo, j'ai souvent vu le modèle où les chaînes de la réponse étaient comme ceci: "firstName": {"S": "John"}. Est-il possible que ce soit le format de vos données? Etrange que cela fonctionne de la même manière sur d'autres tables tho.


@AdamSpecker, c'est exactement le problème que je vois aussi - mais peut-il être résolu?


Bien sûr, changez les types dans le schéma de String à Object, ou Object: {S: string}. Je n'ai pas utilisé TS depuis un moment, donc je ne sais pas si ce sont les bons types, mais vous voyez l'idée.


3 Réponses :


4
votes

Je suppose que le problème pourrait être lié au nom de votre attribut, model .

En fait, c'est le cas réel: le code suivant, extrait du code source dans Document.ts est celui qui écrase votre propriété de model :

const {isValidType, matchedTypeDetails, typeDetailsArray} = utils.dynamoose.getValueTypeCheckResult(schema, value, genericKey, settings, {"standardKey": true, typeIndexOptionMap});
if (!isValidType) {
  throw new Error.TypeMismatch(`Expected ${key} to be of type ${typeDetailsArray.map((detail) => detail.dynamicName ? detail.dynamicName() : detail.name.toLowerCase()).join(", ")}, instead found type ${typeof value}.`);
...

Voici à quoi ressemble le Document avant:

document avant

Et après l'exécution du code susmentionné:

document après

Ce code est exécuté lors du traitement de la fonction Scan exec dans DocumentRetriever.ts lorsque la bibliothèque mappe chaque Item retourné par DynamoDB à leur représentation interne de Document , exactement dans cette ligne de code:

const array: any = (await Promise.all(result.Items.map(async (item) => await new this.internalSettings.model.Document(item, {"type": "fromDynamo"}).conformToSchema({"customTypesDynamo": true, "checkExpiredItem": true, "saveUnknown": true, "modifiers": ["get"], "type": "fromDynamo"})))).filter((a) => Boolean(a));

L'erreur que vous avez signalée est une conséquence de ce changement lorsque le type de l' Item renvoyé est vérifié par rapport à votre modèle de schéma dans la fonction checkTypeFunction :

Object.defineProperty(this, "model", {
  "configurable": false,
  "value": model
});

S'il vous plaît, essayez un autre nom, je pense que cela fonctionnera correctement.


7 commentaires

Hey jcc, le nom du model est certainement déroutant, mais je ne pense pas que ce soit le problème sous-jacent. J'ai le même problème avec imageUrl que mon nom de propriété. J'ai ajouté un lien dans la question vers un problème github avec une discussion plus large et plus de ressources.


Salut Kyle. Merci beaucoup d'avoir partagé le lien, je vais l'examiner. Et merci beaucoup pour la clarification: certainement, si vous obtenez la même erreur avec un autre nom de propriété, le problème devrait probablement être autre. J'examine le code source de la bibliothèque en essayant de creuser dedans. Pouvez-vous me dire quelle version de la bibliothèque utilisez-vous?


Hey Jcc, merci! En utilisant la dernière version sur 2.3.0 . Si vous obtenez un PR au repo ou un exemple reproductible minimal , certainement plus de 500 représentants à venir :)


@KyleMit, à quoi ressemblent les données réelles que vous avez illustrées dans le problème GitHub? S'il vous plaît, pouvez-vous fournir des échantillons des articles réellement retournés par DynamoDB? D'autre part, l'erreur apparaît toujours, au hasard? Pouvez-vous nous faire part de vos commentaires?


@KyleMit Je vois que vous avez fait une enquête à ce sujet, mais après avoir tout lu, je me surprends à croire que votre cas présente un autre problème que ce Q ici et le problème de github . Je pense que vous auriez dû créer une nouvelle question avec votre cas (schémas / code) pour aider les gens qui essaient de comprendre cela.


@ChristosLytras - bon point et je pourrais ouvrir un problème si je peux taquiner un MCVE, mais mon cas est lié à une grande base de code, je dois donc faire beaucoup de travail avant de publier un problème. En attendant, c'est la question dynamoose la plus votée de tous les temps sans réponse d'hier. La prime pour la visibilité. Les gens peuvent se sentir libres de répondre sans tenir compte de mon cas d'utilisation particulier, mais je soupçonne que quelque chose de similaire se passe pour les personnes qui l'ont voté.


@KyleMit J'ai mis à jour ma réponse avec plus d'informations. J'ai peur que votre problème ne soit peut-être pas lié aux Owais. Comme vous pouvez le voir, je pense que son problème est clairement identifié. S'il vous plaît, si vous le jugez approprié, développez la question avec plus d'informations sur votre problème, je vais essayer de vous aider si je le peux.



1
votes

Le schéma doit être comme ceci:

const ImageGalleryFoldersSchema = new Schema({
  key: {
    type: String,
    hashKey: true,
    required: true,
  },
  displayName: {
    type: String,
    required: true,
  },
  parentFolderKey: {
    type: String,
    required: false,
  },
  isActive: {
    type: Boolean,
    default: true,
    required: false,
  },
}, {
  timestamps: true,
});


0 commentaires

0
votes

Peut-être que votre problème est dû à un comportement asynchrone.

Pour être plus précis, je pense qu'au moment où vous appelez la chaîne de fonctions "scan", la requête du corps n'est pas terminée. Cependant, en raison de la nature du levage, l'objet "companyInfo" était déjà en cours d'initialisation avant que vous n'entriez l'appel de fonction.

Par conséquent, vous pouvez obtenir l'erreur «TypeMismatch» spécifiée.

Pourriez-vous s'il vous plaît essayer d'implémenter la structure async / await-structure suivante et me dire si cela aide:

router.post('/getFuelingStatus', async (req, res) => {
    var companyInfo = await req.body;
    try {
        console.log(typeof vehicleMasterModel);
        vehicleMasterModel.scan("customer_account_number").eq(companyInfo.customerId).exec((error, results) => {
            if (error) {
                console.error(error);
            } else {
                res.json(results);
            }
        });
    } catch (error) {
        res.json(error);
    }
});


0 commentaires