从Excel插入/更新文档对象

从Excel插入/更新文档对象,excel,collections,symfony1,doctrine,Excel,Collections,Symfony1,Doctrine,在我目前正在工作的项目中,我必须读取一个Excel文件(超过1000行),提取所有行,然后插入/更新数据库表 就性能而言,最好将所有记录添加到Doctrine\u集合中,并在使用fromArray()方法后插入/更新它们,对吗?另一种可能的方法是为每一行创建一个新对象(Excel行将是一个对象)并保存它,但我认为这是性能最差的方法 每次上载Excel时,都需要将其行与数据库中的现有对象进行比较。如果行不作为对象存在,则应插入,否则应更新。我的第一种方法是将对象和行都转换为数组(或Doctrine

在我目前正在工作的项目中,我必须读取一个Excel文件(超过1000行),提取所有行,然后插入/更新数据库表

  • 就性能而言,最好将所有记录添加到
    Doctrine\u集合中,并在使用
    fromArray()
    方法后插入/更新它们,对吗?另一种可能的方法是为每一行创建一个新对象(Excel行将是一个对象)并保存它,但我认为这是性能最差的方法

  • 每次上载Excel时,都需要将其行与数据库中的现有对象进行比较。如果行不作为对象存在,则应插入,否则应更新。我的第一种方法是将对象和行都转换为数组(或
    Doctrine\u Collections
    );然后在执行所需操作之前比较两个阵列


  • 有人能给我推荐其他可能的方法吗?

    我从来没有研究过条令集合,但我可以从更广泛的意义上回答数据库查询和代码逻辑。我将采用以下逻辑:-

  • 在单个查询中从数据库获取excel工作表的所有行,并将它们存储在数组中
    $uploadedSheet

  • 创建上载excel工作表的所有行的单个数组,称之为
    $storedSheet
    。我猜Doctrine_Collections
    $uploadedSheet
    $storedSheet
    的结构将是相似的(两个二维行、单元格都可以识别和比较)

  • 3.在
    $uploadedSheet
    上运行foreach循环,如下所示,只标识需要插入和更新的行(稍后进行实际查询)——

    四,。这样就有了两个数组。现在执行2个数据库查询-

    • 大容量插入所有编号存储在
      $rowsToBeInserted
      数组中的
      $uploadedSheet

    • 批量更新
      $uploadedSheet
      的所有行,这些行的编号存储在
      $rowsToBeUpdated
      数组中

    这些批量查询是提高性能的关键


    如果这有帮助,请告诉我,或者您想知道其他信息。

    我们最近在一个项目中使用CSV数据做了一些这方面的工作。这是相当无痛的。有一个symfony插件tmCsvPlugin,但是我们扩展了很多,因为插件repo中的版本已经过时了。必须将其添加到@TODO列表:)

    问题1:

    我并不明确了解性能,但我想,将记录添加到Doctrine_集合,然后调用Doctrine_集合::save()将是最简洁的方法。我相信,如果在某个地方抛出异常,而您必须回滚到上次保存,这将非常方便

    问题2:

    如果您可以使用一个行字段作为唯一的标识符(假设为用户名),那么您可以搜索现有记录。如果您找到一条记录,并假设导入的行是一个数组,请使用doctor_record::synchronizeWithArray()更新该记录;然后将其添加到Doctrine_集合中。完成后,只需调用Collection::save()

    一个相当粗略的“n”就绪的实现:

    // set up a new collection
    $collection = new Doctrine_Collection('User');
    
    // assuming $row is an associative 
    // array representing one imported row.
    
    foreach ($importedRows as $row) {
    
        // try to find an existing record 
        // based on a unique identifier.
        $user = Doctrine_Core::getTable('User')
            ->findOneByUsername($row['username']);
    
        // create a new user record if 
        // no existing record is found.
        if (!$user instanceof User) {
            $user = new User();
        }
    
        // sync record with current data.
        $user->synchronizeWithArray($row);
    
        // add to collection.
        $collection->add($user);
    
    }
    
    // done. save collection.
    $collection->save();
    
    很粗糙,但像这样的东西对我很有用。这是假设您可以以某种方式使用导入的行数据作为唯一标识符


    注意:如果您使用的是sf1.2/1.0,请小心synchronizeWithArray()——如果我没记错的话,它没有正确实现。不过,它在doctrine 1.2中运行良好。

    您的问题是关于处理数据库操作(插入/更新)或服务器端代码逻辑(比较数组)还是两者?与我第一次想到的不同,使用doctrine_集合的fromArray()方法时,数据库的数量完全相同。是否无论如何都要保存在同一请求上合成集合的所有阵列?我将仔细分析您的解决方案建议。提前感谢hep。现在,只是一个小的更正。用户表对象上调用的方法必须是findOneByUsername(),否则返回的对象将是一个Doctrine_集合而不是用户。很抱歉,我这么做是出于一时冲动。你完全正确。固定的。
    // set up a new collection
    $collection = new Doctrine_Collection('User');
    
    // assuming $row is an associative 
    // array representing one imported row.
    
    foreach ($importedRows as $row) {
    
        // try to find an existing record 
        // based on a unique identifier.
        $user = Doctrine_Core::getTable('User')
            ->findOneByUsername($row['username']);
    
        // create a new user record if 
        // no existing record is found.
        if (!$user instanceof User) {
            $user = new User();
        }
    
        // sync record with current data.
        $user->synchronizeWithArray($row);
    
        // add to collection.
        $collection->add($user);
    
    }
    
    // done. save collection.
    $collection->save();