Cake 3:如何使用primaryKey设置将新实体添加到数据库?

cew*_*ewi 6 cakephp cakephp-3.0

我想用从excel表中提取的"flat"数据填充我的数据库.所有记录都以数组形式提供(类似于$ request-> data),但其primaryKeys设置必须保留哪些值.我的代码:

$imported = 0;  
foreach ($data as $record) {  
    $entity = $table->findOrCreate([$table->primaryKey() => $record[$table->primaryKey()]]);  
    $entity = $table->patchEntity($entity, $record);  
    if ($table->save($entity)) {  
        $imported++;  
    }  
}  
Run Code Online (Sandbox Code Playgroud)

代码有效,但我想知道是否有更好的解决方案?

澄清:我想要的是添加类似的内容

 [  
  ['id' => 25, 'title'=>'some title'],   
  ['id'=> 3, 'title' => 'some other title'],  
  ['id' => 4356,  'title' => 'another title']  
]  
Run Code Online (Sandbox Code Playgroud)

到我的空数据库.findOrCreate()完成这项工作.但我认为没有必要在插入之前测试数据库中尚未存在的每条记录.

bep*_*ter 6

神秘地丢失一些提供给新数据的记录的常见问题Entity是实体没有将所讨论的字段定义为_accessible.

Cake的BakeShell将在为您生成新的Entity类时跳过主键字段,例如:

<?php
namespace App\Model\Entity;

use Cake\ORM\Entity;

/**
 * Widget Entity.
 */
class Widget extends Entity {

    /**
     * Fields that can be mass assigned using newEntity() or patchEntity().
     *
     * @var array
     */
    protected $_accessible = [
        // `id` is NOT accessible by default!
        'title' => true,
    ];
}
Run Code Online (Sandbox Code Playgroud)

有几种方法可以解决这个问题.

您可以修改您的Entity类以使该id字段永久可分配:

    protected $_accessible = [
        'id' => true, // Now `id` can always be mass-assigned.
        'title' => true,
    ];
Run Code Online (Sandbox Code Playgroud)

或者您可以调整呼叫newEntity()以禁用质量分配保护:

$entities = $table->newEntity($data, [
    'accessibleFields' => ['id' => true],
]);
Run Code Online (Sandbox Code Playgroud)

我发现当你遇到Cake 3 DB数据问题时,最重要的一点就是在创建或修补后立即仔细检查实体,并将其与输入数据进行比较.你仍然需要敏锐的眼光,但这样做会显示实体根本没有定义它们的->id属性$data.


ndm*_*ndm 4

如果您确实只使用空表,那么您可以立即保存数据,无需查找和修补,只需在禁用存在检查的情况下保存即可。

另外,从代码来看,数据似乎采用了可以立即转换为实体的格式,因此您可能希望立即创建它们。

$entities = $table->newEntities($data, [
    // don't forget to restrict assignment one way or
    // another when working with external input, for
    // example by using the `fieldList` option
    'fieldList' => [
        'id',
        'title'
    ]
]);

// you may want to check the validation results here before saving

foreach ($entities as $entity) {
    if ($table->save($entity, ['checkExisting' => false])) {
        // ...
    }
    // ...
}
Run Code Online (Sandbox Code Playgroud)

也可以看看