framework: [5.1] [5.2] Error with `chunk` not saving second batch

I’ve come across a bug when trying to update a database in a migration using chunk where some records aren’t being saved. In our case we’re adding a nullable column, setting the values for that column and then making it nullable within a single migration. Using chunk though attempting to remove the nullable option from the column would throw an error because some records didn’t have the values set.

I’ve created a minimal example to show this off - https://github.com/EspadaV8/laravel-chunking-non-persistance/tree/develop - cloning this and running php artisan migrate:refresh --seed should produce something like the following output

Empty example table
+----+------+----------+
| id | name | new-name |
+----+------+----------+

Populated example table with `name`
+----+------------+----------+
| id | name       | new-name |
+----+------------+----------+
| 1  | mM4YJMR3i2 |          |
| 2  | ZYNNY6DBqi |          |
| 3  | okKt4kIARY |          |
| 4  | VHJ6ni85c8 |          |
+----+------------+----------+

Populated example table with `name-new` using `chuck`
+----+------------+----------------+
| id | name       | new-name       |
+----+------------+----------------+
| 1  | mM4YJMR3i2 | mM4YJMR3i2-new |
| 2  | ZYNNY6DBqi | ZYNNY6DBqi-new |
| 3  | okKt4kIARY | okKt4kIARY-new |
| 4  | VHJ6ni85c8 |                |
+----+------------+----------------+

The one row without a new-name set should’ve been set in the second chunk batch.

About this issue

  • Original URL
  • State: closed
  • Created 9 years ago
  • Comments: 18 (15 by maintainers)

Most upvoted comments

If it’s not going to be changed, then it should be noted in the Laravel docs.

I had submitted https://github.com/laravel/docs/pull/2227, but it wasn’t committed in its entirety. Taylor committed my changes to the sample code for chunk() to include orderBy(), but not the explanation about why one should use orderBy() with chunk(). I can write a more complete explanation if that would help. I just think leaving this issue out there without any explanation is creating confusion.

Made a slight change to the seeder so that it appends to the name-new column instead of just setting it to a known value and it now produces the following output

espadav8@dolores:~/Workspace/chunking-non-persistance (*)
> php artisan migrate:refresh --seed                                                                                                                                                  develop [7fd9127] modified
Rolled back: 2015_12_10_235952_create_tables
Migrated: 2015_12_10_235952_create_tables

Empty example table
+----+------+----------+
| id | name | name-new |
+----+------+----------+

Populated example table with `name`
+----+------------+------------+
| id | name       | name-new   |
+----+------------+------------+
| 1  | kVmjtZUXTH | ZoerIsEvoZ |
| 2  | 0VkvI2TSIF | DZ1R4Joz26 |
| 3  | TKaJTOiVzH | W3eOttRChc |
| 4  | bS6TeDg3xB | DJgjzlQBX5 |
+----+------------+------------+

Populated example table with `name-new` using `chuck`
+----+------------+--------------------+
| id | name       | name-new           |
+----+------------+--------------------+
| 1  | kVmjtZUXTH | ZoerIsEvoZ-new     |
| 2  | 0VkvI2TSIF | DZ1R4Joz26-new     |
| 3  | TKaJTOiVzH | W3eOttRChc-new-new |
| 4  | bS6TeDg3xB | DJgjzlQBX5         |
+----+------------+--------------------+

For some reason the second chunk call returns just 1 record, but it’s a record that’s already been returned (in this case record 3).

It looks like the queries that are being created are correct ($this->forPage($page, $count)->toSql())

select * from "example" limit 3 offset 0;
select * from "example" limit 3 offset 3;
select * from "example" limit 3 offset 6;