[petite aide rapide, promis ^^]Récupérer des données depuis une feuille ods pour les insérer en BDD

Le problème exposé dans ce sujet a été résolu.

Bonjour,

Besoin d’un petit coup de main : là je m’occupe de créer (vite fait) une application pour un salon du livre. Les gentils organisateurs utilisent depuis plus de 20 ans un fichier LibreOffice avec des tonnes de macros, qui plante régulièrement, pas sécurisé du tout, bref, on m’a demandé de leur faire un nouveau système. Ca avance bien et c’est marrant à faire. J’ai créé la structure générale du site et maintenant, j’aimerais récupérer les données des feuilles ods. J’ai récupéré la liste des auteurs et les ai créés dans la nouvelle application. Il y en avait une trentaine, j’ai fait à la main. Le souci, ce sont leurs livres. J’ai un tableau de plus de 500 lignes avec des en-têtes qui m’intéressent :

  • auteur
  • titre
  • edition (peut être null même si idéalement non)
  • collection (peut être null même si idéalement non)
  • code ean (le code barre) (peut être null même si idéalement non)
  • prix (peut être null)
  • fournisseur (peut être null)

Question simple, comment je peux d’une part extraire les données, et d’autre part les associer dans ma bdd au bon id de mon entité Author…? Comme d’habitude, j’utilise Symfony.

Merci pour vos avis. En attendant je fais des tests.

Hello, le plus simple pour extraire les données est probablement de convertir en CSV. À partir de là soit tu insères directement en base (MySQL peut importer du CSV, d’autres SGBD pourront sûrement aussi), soit tu passes par un script pour trouver les éléments manquants.

Le plus simple pour retrouver les auteurs étant de faire une recherche en base (à partir du nom par exemple). Et si tu veux éviter de trop solliciter ta base tu peux garder un cache local avec un tableau/Map de clés/valeurs (du genre ['Nom' => 'id']) pour pouvoir réutiliser les résultats déjà récupérés autant que possible.

Va pour le CSV. Je vais avancer doucement, auteur par auteur, histoire de contrôler régulièrement la validité des insertions.

Et je me rends compte en avançant qu’un livre peut avoir plusieurs auteurs. Mfff. Saleté de livres jeunesse avec auteur et illustrateur ^^

Edit : ah ouais je vois bien en quoi ça va me compliquer la vie, les auteurs multiples. Relation ManyToMany, table externe pour stocker la relation livre/auteur. Du coup je pars sur une insertion en plusieurs étapes, sauf si méthode MySQL miracle.

+1 -0

Bon je m’en sors pas mal avec un fichier ODS, nativement reconnu. J’ai dû inverser ou supprimer quelques colonnes pour les faire correspondre à mon entité, mais ça passe.

Par contre, j’ai un souci MySQL, maintenant. La table book_author doit être remplie de couples id_du_livre / id_de_l’auteur. Je vais m’en sortir en passant par un controller symfony, mais comment fait-on une boucle en mysql ? J’ai trouvé ceci mais phpMyAdmin refuse même de considérer à l’exécuter :

 BEGIN
 DECLARE i int;
 SET i = 27;
 WHILE i < 52 DO
   INSERT INTO 'book_author' VALUES (i, 2);
   SET i = i +1;
 END WHILE;
 END;

Ben non, le livre est déjà créé, il a son id, il faut aussi l’insérer dans book_author, non ?

J’essaye de retrouver la syntaxe exacte de quelque chose comme :

INSERT INTO `book_author` VALUES 
(SELECT id FROM book WHERE id < 52, 2)

où le 2 serait l’id de l’auteur.

Tu peux insérer les couples de valeurs de la même façon, il suffit de lister les colonnes dans le bon ordre.

Mais attention à pas te baser sur des nombres au hasard mais plutôt à récupérer les données créées en base pour être sûr de pas avoir de décalage (comme l’id du livre que tu viendrais d’ajouter).

Et pense bien à utiliser des transactions pour garantir l’intégrité des données et pour éviter les conflits.

Te prends pas trop la tête à tout faire en SQL pur pour un script qui tournera qu’une fois : fais au plus simple ;)

Ouais j’ai tendance à oublier que "le mieux est l’ennemi du bien". Je me complique souvent la vie juste pour le petit détail à la con.

Au final :

  • je récupère auteur par auteur la liste des livres depuis le document ods original
  • j’insère cette liste dans l’interface mysql, table 'book'
  • sur Symfony, j’exécute ceci :
#[Route('/livre-auteur', name: 'user.booksAttribution')]
    public function setBookAuthor(EntityManagerInterface $em, BookRepository $br, AuthorRepository $ar): Response
    {   
        $i = 27;        
        $end = 51;
        $author = $ar->find(2);
        while( $i <= $end) {
            $book = $br->find($i);
            $book->addAuthor($author);
            $em->persist($book);
            $i++;
        }        
        $em->flush();       
        
        return $this->redirectToRoute('user.index');
    }

Ca fonctionne et ça va me permettre d’atteindre les 550 lignes assez vite. Si quelqu’un a quelque chose de mieux à proposer (Viki ? :D), je reste preneur.

Ca avance. Je me suis un peu embrouillé entre l’id d’utilisateur et l’id de l’auteur (deux entités différentes puisqu’un auteur est un utilisateur mais pas forcément l’inverse), mais c’est corrigé.

Petite question bonus :

Chaque année, chaque auteur commande des quantités de ses livres en prévision du salon (20 ex. de livre 1, 10 du livre 2, etc.) et les vend. Comment tu gérerais les entités Order et Sale en sachant que l’on doit pouvoir retrouver les commandes et les ventes des années précédentes ?

Je pensais partir sur des entités Order2024, Order2025, etc. mais, en sachant que j’aimerais ne pas mettre à jour tous les ans le site, y a-t-il un autre moyen de faire ? Une seule entité Order avec un champ createdAt, puis un tri par année au niveau de l’affichage dans la vue ?

Salut !

Je passe par là juste pour rappeler qu’il y a possibilité, avec MySQL comme probablement d’autres, de faire comme suit :

INSERT INTO book_author SELECT b.id, a.id FROM book b, author a WHERE a.name = ? AND b.name = ?

En exécutant la requête avec comme paramètres les nom d’auteur/illustrateur/traducteur et de livre, on devrait pouvoir effectuer l’insertion depuis les données d’un fichier "plat".

+1 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte