IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Symfony PHP Discussion :

Envoi de données en CSV vers une BDD MySQL plus précisément vers un champ en clé étrangère


Sujet :

Symfony PHP

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    214
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 214
    Par défaut Envoi de données en CSV vers une BDD MySQL plus précisément vers un champ en clé étrangère
    Bonjour,
    J'essaye d'envoyé un csv vers une bdd et certains champs me pose problèmes car ce sont des champs avec clé étrangère !
    j'ai évidement regardé la doc et cherché sur le net mais j'ai toujours des message d'erreurs.
    Ce que je cherche à faire : Insérer les données du CSV directement dans la table [Signalement]. Dans ce CSV, j'ai une colonne "Nom de la structure", ce nom doit faire référence à un [nom] qui est dans la table [Structure] mais pas dans ma table [Signalement], et avec son [nom] j'aimerais identifier son [id] et ainsi récupérer d'autres information par son intermédiaire
    Pour bien faire, avant de passer par un système de form pour importer un csv, j'ai commencé ce travail par une commande :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
     
    <?php
    namespace App\Command;
    use App\Entity\Structure;
    use DateTimeImmutable;
    use League\Csv\Reader;
    use App\Entity\Signalement;
    use League\Csv\Statement;
    use Doctrine\ORM\EntityManagerInterface;
    use Symfony\Component\Console\Command\Command;
    use Symfony\Component\Console\Style\SymfonyStyle;
    use Symfony\Component\Console\Attribute\AsCommand;
    use Symfony\Component\Console\Input\InputArgument;
    use Symfony\Component\Console\Input\InputInterface;
    use Symfony\Component\Console\Output\OutputInterface;
     
    class ImportCSVCommand extends Command {
        private $em;    
        public function __construct(EntityManagerInterface $em) {
            parent::__construct();
            $this->em = $em;
        }
     
        protected function configure(): void {
            $this
                ->setName('csv:import')
                ->setDescription("Import CSV in DB") ;
        }
     
        protected function execute(InputInterface $input,OutputInterface $output): int {
            $io = new SymfonyStyle($input, $output);
            $io->title('Import CSV ...');
            $csv = Reader::from('src/Data/listedeproduit.csv', 'r');
            $csv->setHeaderOffset(0);
            $csv->setDelimiter(';');
            $csv->setEscape('');
            $records = $csv->getRecords();
     
            foreach ($records as $record){          
                $structure = (new Structure())
                     ->setNom($record['Nom de la structure']);           
     
                $signalement = (new Signalement())
                    ->setNumero($record['Identifiant de la fiche'])                
                    ->setStructure($structure) ;
                    //etc...
     
                $this->em->persist($signalement);
     
            }
            $this->em->flush();                
            $io->success('Great CSV in DB !');
            return Command::SUCCESS;
        }    
    }
    Avec ce code j'avais une première erreur de ce genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
     A new entity was found through the relationship 'App\Entity\Signalement#structure' that was not configured to cascade persist   
       operations for entity: 9. To solve this issue: Either explicitly call EntityManager#persist() on this unknown entity or configure cascade persist this association in the mapping for example @ManyToOne(..,cascade={"persist"}).
    De ce que j'ai compris c'est parce que l'entity Structure n'était pas persister... ! J'ai donc ajouter
    $this->em->persist($structure); en dessous de l'autre persist...
    Mais a partir de là il me met un autres message d'erreur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SQLSTATE[23000]: Integrity constraint violation: 1048 Le champ 'finess_g' ne peut être vide (null)
    il concerne un autre champs de Structure mais pas de Signalement dont je ne me sert pas ici...

    Je pense que j'ai pas compris quelques chose ou que je fait mal un truc ! Mais déjà dans un premier temps j'ai l'impression que le (new STructure) n'est pas bon dans le sens ou je n'essaie pas de rentrer une nouvelle structure mais un nouveau signalement et dans ce signalement j'ai une colonne structure_id !

    Voilà ! je sais pas si j'ai été très clair !! Merci

  2. #2
    Membre émérite
    Homme Profil pro
    Autre
    Inscrit en
    Juillet 2021
    Messages
    488
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Juillet 2021
    Messages : 488
    Par défaut
    Bonjour,

    L'erreur indique que 'finess_g' ne doit pas avoir pas la valeur null : il faut donc soit renseigner sa valeur lors de l'import, soit définir cette propriété comme nullable dans le mapping de ton entité.

    https://www.doctrine-project.org/pro...operty-mapping

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    214
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 214
    Par défaut
    Hummm oui ok, mais comme j'ai dit, le champ "finess_g"ne concerne ni le CSV, ni l'Entité dans lequel je veux inséré mon CSV !
    Voici une vue de ce que je veux faire :


    Nom : struc.PNG
Affichages : 46
Taille : 63,2 Ko

    En gros, dans le CSV, il y aura le nom de la structure, mais dans l'Entité [Signalement] il n'y a pas de champs pour le nom de la structure, mais seulement un champ structure_id qui fait le lien avec l'Entité [Structure] qui lui, a le champ nom (de la structure) !
    Il faut savoir surtout que la base de donnée concernant les structures est déjà faite, donc aucun ajout à faire ! J'ai déjà toute une base de structure ! Donc il y a de forte chance que le nom de la structure (et tout ce qui la concerne) dans le CSV soit déjà présente dans cette base
    Le but est donc de récupérer son id avec le nom que l'on a sur le CSV !
    Est ce que la bonne méthode serait dans un premier temps trouver un moyen de récupéré le nom de la structure du CSV, de tchecker avec la base de donnée actuelle des structures de la retrouvé et ensuite récupéré son id, pour que, ensuite inséré le CSV dans Signalement en remplaçant le nom par l'id ?

  4. #4
    Membre émérite
    Homme Profil pro
    Autre
    Inscrit en
    Juillet 2021
    Messages
    488
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Juillet 2021
    Messages : 488
    Par défaut
    Pour vérifier si la structure existe déjà, tu peux utiliser la méthode findOneBy du repository de ton entité à partir de l'EntityManager déjà injecté dans ta commande.
    Cette méthode retourne l'instance de Structure si celle-ci existe ou la valeur null dans le cas contraire.

    Exemple non testé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    //ImportCSVCommand::execute()
    $structure = $this->em->getRepository(Structure::class)->findOneBy(['name' => $record['Nom de la structure']]);
     
    if (null === $structure) {
      $structure = (new Structure())->setNom($record['Nom de la structure']);
      $this->em->persist($structure);
    }
     
    $signalement = (new Signalement())
      ->setNumero($record['Identifiant de la fiche'])                
      ->setStructure($structure) ;

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    214
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 214
    Par défaut
    C'est exactement ça qu'il me fallait ! Merci Pytet

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Parser un fichier texte vers CSV ou une BDD avec Python ?
    Par Nico_projet dans le forum Général Python
    Réponses: 3
    Dernier message: 07/07/2019, 20h53
  2. [MySQL] Envoyer les données d'un CSV dans une BDD Mysql
    Par guyfoot dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 24/09/2007, 08h13
  3. [MySQL] enregistrer des données CSV dans une BDD
    Par NicoO_O dans le forum PHP & Base de données
    Réponses: 6
    Dernier message: 29/11/2006, 00h10
  4. Probleme d'envoi de courriels a partir d'une bdd MySQL
    Par Chimere dans le forum Requêtes
    Réponses: 2
    Dernier message: 06/06/2006, 14h47
  5. Réponses: 5
    Dernier message: 05/03/2006, 14h21

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo