Symfony2 在 Doctrine Fixtures Load 中执行 SQL 文件

Posted

技术标签:

【中文标题】Symfony2 在 Doctrine Fixtures Load 中执行 SQL 文件【英文标题】:Symfony2 execute SQL file in Doctrine Fixtures Load 【发布时间】:2015-02-15 04:51:18 【问题描述】:

我正在将基于 SQL Server 和 ASP 的旧 Web 应用程序迁移到 Symfony2 和 mysql。我做了一些查询并将旧数据导出到单个 SQL 文件。 当我运行命令时,如何在我的装置中执行这些文件

$php app/console doctrine:fixtures:load

现在我有一些直接与 Doctrine ORM 和实体一起工作的装置,但我有很多数据要导入。

【问题讨论】:

【参考方案1】:

我找到了一个很好的解决方案。我在ObjectManager 类中没有找到exec 方法,所以……这对我来说非常有效。

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();
    

在此解决方案中,您的夹具类必须使用该方法实现 ContainerAwareInterface

public function setContainer( ContainerInterface $container = null )

    $this->container = $container;

【讨论】:

使用 Symfony\Component\Finder\Finder; 我们可以用new \Symfony\Component\Finder\SplFileInfo('web/sql/categories.sql', '', '')代替Finder【参考方案2】:

您可以将文件内容加载为字符串,并使用 EntityManager 执行本机 SQL:

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
  

【讨论】:

ObjectManager 下没有方法getConnection。我的 IDE 对我大喊大叫。代码运行是因为我没有对象管理器。我得到一个 EntityManager 代替.......【参考方案3】:

使用Doctrine Data-Fixtures 回答 Zend Framework 2.5.3。

不确定这是否适用于给定的答案,但他们有点太努力了。如果您检查给定的$manager 对象,您会发现它已经是EntityManagerinterface ObjectManager)(至少在 ZF2 中)。因此,您可以直接获取Connection,并且可以在不使用$this->container->get('doctrine.orm.entity_manager')的情况下执行

在我用于创建第一个用户“系统”的 sn-p 下方,带有一个 createdBy FK 对其自身的引用。

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', 'system@system.test');
    $stmt->bindValue(':display_name', 'system');
    $stmt->bindValue(':password', password );   
    $stmt->bindValue(':created_by', 1);        // Self reference
    $stmt->execute();

【讨论】:

以上是关于Symfony2 在 Doctrine Fixtures Load 中执行 SQL 文件的主要内容,如果未能解决你的问题,请参考以下文章

Symfony2 - Doctrine - 在实体管理器刷新调用中捕获错误

Symfony2 / Doctrine2:不要在模式上删除全文索引:更新

Symfony2/Doctrine 提交表单需要很长时间

在 Doctrine2/Symfony2 中的重复条目上插入忽略

Symfony2 Doctrine2 获取所有表

Symfony2\Doctrine - 检索用户角色