2015-02-06 21 views
6

Tôi muốn phổ biến cơ sở dữ liệu của mình bằng dữ liệu 'phẳng' được trích xuất từ ​​một bảng excel. Tất cả các bản ghi được cung cấp dưới dạng mảng (tương tự như $ request-> data) nhưng có các khóa chính được đặt để giữ các giá trị. Mã của tôi:Bánh 3: Cách thêm thực thể mới vào cơ sở dữ liệu bằng bộ khóa chính?

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

Mã hoạt động, nhưng tôi tự hỏi liệu có giải pháp nào tốt hơn không?

Để làm rõ: Những gì tôi muốn là thêm một cái gì đó giống như

[ 
    ['id' => 25, 'title'=>'some title'], 
    ['id'=> 3, 'title' => 'some other title'], 
    ['id' => 4356, 'title' => 'another title'] 
] 

đến cơ sở dữ liệu rỗng của tôi. findOrCreate() thực hiện công việc. Nhưng tôi nghĩ rằng không cần thiết phải kiểm tra mọi bản ghi rằng nó chưa tồn tại trong cơ sở dữ liệu trước khi chèn.

+0

sau khi đọc kỹ http://api.cakephp.org/3.0/class-Cake.ORM.Table.html#_findOrTạo Tôi hiểu rằng Ứng dụng đã lưu. Vì vậy, $ table-> findOrCreate ($ record) thực hiện công việc. Nhưng chỉ khi $ record ** không có khóa nào không có trong bảng **. – cewi

+0

Vì vậy, đây chỉ là vấn đề được sử dụng với một cơ sở dữ liệu/bảng trống, nó sẽ không bao giờ cần thiết để cập nhật các bản ghi hiện có thay vì chèn các bản ghi mới? – ndm

+0

có đó là những gì tôi đang cố gắng đạt được. Nếu không, tôi nghĩ findOrCreate() sẽ là đúng cách. – cewi

Trả lời

3

Nếu bạn thực sự chỉ làm việc với các bảng trống, thì bạn có thể chỉ cần lưu dữ liệu ngay lập tức, không cần phải tìm và vá, chỉ cần lưu với kiểm tra tồn tại vô hiệu hóa.

Ngoài việc xem mã của bạn, dữ liệu có vẻ ở định dạng có thể được chuyển thành thực thể ngay lập tức, vì vậy bạn có thể muốn tạo tất cả chúng cùng một lúc.

$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])) { 
     // ... 
    } 
    // ... 
} 

cũng Xem

6

Một vấn đề thường gặp với các hồ sơ một cách bí ẩn mất một số dữ liệu được cung cấp cho một mới Entity là Entity không xác định các lĩnh vực (s) trong câu hỏi như _accessible.

BakeShell Bánh sẽ bỏ qua các lĩnh vực khóa chính khi tạo lớp Entity mới cho bạn, ví dụ:

<?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, 
    ]; 
} 

Có một số cách để làm việc xung quanh này.

Bạn có thể thay đổi lớp Entity của bạn để làm cho id lĩnh vực vĩnh viễn chuyển nhượng:

protected $_accessible = [ 
     'id' => true, // Now `id` can always be mass-assigned. 
     'title' => true, 
    ]; 

Hoặc bạn có thể điều chỉnh cuộc gọi của bạn để newEntity() để vô hiệu hóa khối lượng bảo vệ công việc:

$entities = $table->newEntity($data, [ 
    'accessibleFields' => ['id' => true], 
]); 

tôi ve tìm thấy quan trọng nhất take-away khi bạn đang gặp vấn đề với bánh 3 DB dữ liệu là để kiểm tra lại các thực thể ngay sau khi nó được tạo ra hoặc vá và so sánh nó với inpu của bạn t dữ liệu. Bạn vẫn cần phải có một con mắt sắc nét, nhưng làm như vậy sẽ tiết lộ rằng các thực thể không có tài sản ->id của họ đặt ở tất cả mặc dù $data xác định chúng.

Các vấn đề liên quan