从Excel插入/更新文档对象
在我目前正在工作的项目中,我必须读取一个Excel文件(超过1000行),提取所有行,然后插入/更新数据库表从Excel插入/更新文档对象,excel,collections,symfony1,doctrine,Excel,Collections,Symfony1,Doctrine,在我目前正在工作的项目中,我必须读取一个Excel文件(超过1000行),提取所有行,然后插入/更新数据库表 就性能而言,最好将所有记录添加到Doctrine\u集合中,并在使用fromArray()方法后插入/更新它们,对吗?另一种可能的方法是为每一行创建一个新对象(Excel行将是一个对象)并保存它,但我认为这是性能最差的方法 每次上载Excel时,都需要将其行与数据库中的现有对象进行比较。如果行不作为对象存在,则应插入,否则应更新。我的第一种方法是将对象和行都转换为数组(或Doctrine
Doctrine\u集合中,并在使用fromArray()
方法后插入/更新它们,对吗?另一种可能的方法是为每一行创建一个新对象(Excel行将是一个对象)并保存它,但我认为这是性能最差的方法
Doctrine\u Collections
);然后在执行所需操作之前比较两个阵列有人能给我推荐其他可能的方法吗?我从来没有研究过条令集合,但我可以从更广泛的意义上回答数据库查询和代码逻辑。我将采用以下逻辑:-
$uploadedSheet
$storedSheet
。我猜Doctrine_Collections$uploadedSheet
和$storedSheet
的结构将是相似的(两个二维行、单元格都可以识别和比较)$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();