Imports de données

user-friendly

avec Loopback

@ClementRicateau 

cRicateau 

contexte

application metier

fichiers csv à importer

HYPOTHÈSE 1

UN SEUL framework POUr LE BACKEND

HYPOTHÈSE 2

 

sprints sans cahier des charges

HYPOTHÈSE 3

IMPORTs DE DONNÉES PAR UN utilisateur

L'import a échoué. Merci de corriger les erreurs et de ré-essayer
L'import a réussi (2 lignes importées sur 200 000)

...sans corrompre la base

pierre a LE DROIT DE SE TROMPER...

 

pierre est autonome  pour corriger LES ERREURS

Pierre INFORMÉ DE L'ÉTAT SON UPLOAD DE FICHIERS

1. upload d'un fichier CSV

en base de données

jdrouet/loopback-component-storage-postgres

2. fork d'un process node

var fork;

fork = require('child_process').fork;

Invoice.upload_fork = function(params) {
  return fork(__dirname + "/../../server/scripts/import-script.coffee", params);
};

 

3. STOCKEr EN BASE L'ÉTAT DE L'IMPORT dans un modèle

4. début d'une transaction sql

Invoice.beginTransaction(
  {
     isolationLevel: Post.Transaction.READ_COMMITTED
  }, function(err, tx) {
  // Now we have a transaction (tx)
});

itérer sur toutes les lignes

5. process d'import (1/2)

valider les données

5. process d'import (2/2)

create or update

OU

errors.push(err)

6. post-process

stocker les erreurs en base

rollback

commit transaction

7. suppression du fichier et maj du statut

et pierre...

encore des fichiers!

les mixins

    {
      "_meta": {
        ...
        "mixins": [
          ...
          "./mixins"
        ]
      }
    }

model-config.json

common/mixins/upload.js

Model.import = function(file) {
  var tx;
  tx = {};
  return Model.startTransaction(tx, file)
  .then(function() {
    return Model.importProcess(tx, file);
  })
  .then(function() {
    return Model.exitAfterSuccess(tx);
  })
  .catch(function(err) {
    return Model.exitAfterError(tx);
    });
  });
};

les mixins loopback

{
  "name": "Invoice",
  "base": "PersistedModel",
  "mixins": {
    "Upload": {},
  },

invoice.json

paramétrisation

{
  "name": "Invoice",
  "base": "PersistedModel",
  "mixins": {
    "Upload": {},
    "CsvUpload": {
      "requiredHeaders": [
        "invoiceId",
        "amount"
      ],
      "validators": {
        "invoiceId": {
          "required": true,
          "type": "string"
        },
        "amount": {
          "required": true,
          "type": "integer"
        }
      }
  },

Une seule fonction à coder par import!

bilan

choix delimiteur?

Pierre + CSV

difficultés techniques

callbacks + gestion d'erreurs chainée

tout promissifier!

loopback-promisify

Loopback 3.0

autres difficultés

source de données peu fiable

EXPERIMENT

FAIL

LEARN

REPEAT

Pour aller plus loin...

sécurité: détection du type de fichiers

détection de l'encodage

réparation automatique d'erreurs

Merci DE VOTRE ATTENTION

cRicateau/loopback-csv-import

[Meetup Hybride] Ce que j'ai appris en créant une appli de transformation de photos

By Clément Ricateau

[Meetup Hybride] Ce que j'ai appris en créant une appli de transformation de photos

  • 1,026