web-dev-qa-db-fra.com

Symfony2 exécute un fichier SQL dans la charge de fixations de la doctrine

Je migre une ancienne application Web basée sur SQL Server et ASP vers Symfony2 et MySQL. J'ai effectué des requêtes et exporté d'anciennes données vers des fichiers SQL individuels. Comment puis-je exécuter ces fichiers dans mes fixtures quand je lance la commande

$php app/console doctrine:fixtures:load

Maintenant, certains appareils fonctionnent directement avec Doctrine ORM et les entités, mais j'ai beaucoup de données à importer.

15
Pablo

Je trouve une bonne solution. Je n'ai pas trouvé de méthode exec dans la classe ObjectManager, alors ... cela fonctionne très bien pour moi.

public function load(ObjectManager $manager)
{
    // Bundle to manage file and directories
    $Finder = new Finder();
    $Finder->in('web/sql');
    $Finder->name('categories.sql');

    foreach( $Finder as $file ){
        $content = $file->getContents();

        $stmt = $this->container->get('doctrine.orm.entity_manager')->getConnection()->prepare($content);
        $stmt->execute();
    }
}

Dans cette solution, votre classe de fixture doit implémenter la ContainerAwareInterface avec la méthode

public function setContainer( ContainerInterface $container = null )
{
    $this->container = $container;
}
13
Pablo

Vous pouvez charger le contenu du fichier sous forme de chaîne et exécuter le code SQL natif à l'aide de EntityManager:

class SQLFixtures extends AbstractFixture implements OrderedFixtureInterface
{    
  $filename = '/path/to/sql/file.sql';

  public function load(ObjectManager $manager) {
    $sql = file_get_contents($filename);  // Read file contents
    $manager->getConnection()->exec($sql);  // Execute native SQL

    $manager->flush();
  }

  public function getOrder() {
    return 99;  // Order in which this fixture will be executed
  }
}
12

Répondez à Zend Framework 2.5.3 en utilisant Doctrine Data-Fixtures .

Je ne sais pas si cela s’applique aux réponses données, mais ils essaient un peu trop fort. Si vous inspectez l'objet $manager donné, vous constaterez qu'il s'agit déjà de la EntityManager (de interface ObjectManager) (au moins, dans ZF2). En tant que tel, vous pouvez obtenir le Connection directement et il est possible d'exécuter sans utiliser $this->container->get('doctrine.orm.entity_manager')

Ci-dessous un extrait que j'utilise pour créer le premier utilisateur "système", avec une référence createdBy FK à lui-même.

public function load(ObjectManager $manager)
{
    $sql = 'INSERT INTO users (
              id, username, email, display_name, `password`, created_by) 
            VALUES (:id, :username, :email, :display_name, :password, :created_by)';

    $password = $this->createSuperDuperEncryptedPassword();

    // $manager === `EntityManager|ObjectManager`, `->getConnection()` is available
    $stmt = $manager->getConnection()->prepare($sql); 

    $stmt->bindValue(':id', 1);
    $stmt->bindValue(':username', 'system');
    $stmt->bindValue(':email', '[email protected]');
    $stmt->bindValue(':display_name', 'system');
    $stmt->bindValue(':password', password );   
    $stmt->bindValue(':created_by', 1);        // Self reference
    $stmt->execute();
}
0
rkeet