从Excel中插入/更新Doctrine对象

在我目前工作的项目中,我必须读取一个Excel文件(超过1000行),提取所有这些文件并将其插入/更新到数据库表中。

  1. 在性能方面,最好将所有logging添加到Doctrine_Collection ,并在使用fromArray()方法后插入/更新它们,对吧? 另一种可能的方法是为每一行创build一个新的对象(Excel行将是一个对象),并保存它,但我认为它的性能最差。

  2. 每次上传Excel时,都需要将其行与数据库上的现有对象进行比较。 如果该行不存在作为对象,则应该插入,否则更新。 我的第一种方法是把对象和行都变成数组(或Doctrine_Collections ); 然后在执行所需操作之前比较两个arrays。

任何人都可以提出任何其他可能的方法?

我们最近在一个项目中用CSV数据做了一点。 这是相当无痛的。 有一个symfony插件tmCsvPlugin,但我们扩展了这一点,因为插件回购的版本已经过时了。 必须添加到@TODO列表:)

问题1:

我没有明确地了解性能,但是我猜想将这些logging添加到Doctrine_Collection然后调用Doctrine_Collection :: save()将是最新的方法。 我敢肯定,如果在某个地方抛出了一个exception,那么你将不得不在最后一次保存时回滚。

问题2:

如果您可以使用行字段作为唯一的标识符(让我们假设一个用户名),那么您可以search现有的logging。 如果您发现一条logging,并假定您导入的行是一个数组,则使用Doctrine_Record :: synchronizeWithArray()更新此logging; 然后将其添加到Doctrine_Collection。 完成后,只需调用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 / doctrine 1.0,请注意synchronizeWithArray() – 如果我没有记错的话,它没有正确实现。 但它在教条1.2中工作正常。

我从来没有在Doctrine_Collections上工作过,但是我可以从广义上回答数据库查询和代码逻辑。 我会应用以下逻辑:

  1. 在单个查询中从数据库中获取Excel表格的所有行并将其存储在数组$uploadedSheet

  2. 创build上传的Excel表单的所有行的单个数组,将其称为$storedSheet 。 我猜Doctrine_Collections $uploadedSheet$storedSheet的结构是相似的(两维 – 行,单元格可以被识别和比较)。

3.按照以下步骤在$uploadedSheet上运行foreach循环,并只标识需要插入的行和要更新的行(稍后再进行实际查询) –

 $rowsToBeUpdated =array(); $rowsToBeInserted=array(); foreach($uploadedSheet as $row=>$eachRow) { if(is_array($storedSheet[$row])) { foreach($eachRow as $column=>$value) { if($value != $storedSheet[$row][$column]) {//This is a representation of comparison $rowsToBeUpdated[$row]=true; break; //No need to check this row anymore - one difference detected. } } } else { $rowsToBeInserted[$row] = true; } } 

这样你有两个数组。 现在执行2个数据库查询 –

  • 批量插入$uploadedSheet的所有行,其数字存储在$rowsToBeInserted数组中。

  • 批量更新$uploadedSheet的所有行,其数量存储在$rowsToBeUpdated数组中。

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

让我知道这是否有帮助,或者你想知道别的。

Interesting Posts