Import big csv in Laravel - laravel

I'm using following package to import large CSV file to MySQL database:
https://github.com/Maatwebsite/Laravel-Excel
Here is my controller code:
Excel::filter('chunk')->load($file)->chunk(250, function($results) use ($count)
{
++$count;
echo "<br/> Count = " . $count;
foreach($results as $row)
{
// do stuff
}
Here is line from composer.json
"maatwebsite/excel": "~2.1.0"
Here is my config/app.php file:
'providers' => [
....
....
Maatwebsite\Excel\ExcelServiceProvider::class,
],
'aliases' => [
....
....
'Excel' => Maatwebsite\Excel\Facades\Excel::class,
]
I am getting this error and I cannot find any solution:
InvalidArgumentException in Dispatcher.php line 333:
No handler registered for command [Maatwebsite\Excel\Readers\ChunkedReadJob]
I tried following link for solution but no luck:
https://github.com/Maatwebsite/Laravel-Excel/issues/957
https://github.com/Maatwebsite/Laravel-Excel/issues/952

Are you doing some manipulations for each row of csv before inserting into the database or is it like you need to import the data directly to the database?
Just a quick tip, its your csv is in the sequence how your database table columns are ordered, you can use ubuntu terminal to import larger files :
mysql -uroot -proot --local_infile=1 3parsfdb -e "LOAD DATA LOCAL INFILE '/logfiles/Bat_res.csv' INTO TABLE Bat_res FIELDS TERMINATED BY ','"
If this is something which you want to do programatically or in cron, then you need this package. Can you try clearing laravel cache and also try
composer dump-autoload
One more thing is to ensure there are no special characters in the csv which can not get imported.

Instead of that package, try the LOAD DATA INFILE MySQL procedure, using Laravel's DB object. Here is an example.
I used this for importing big sized csv files (300M-400M) into a mysql db and worked for me.

LOAD DATA LOCAL INFILE! I really missed MySQL, I used this to ingest a huge CVS file, about 6gb in our server, this took about 20 mins.
You can use something like this:
private function importData(int $ignoreLines, string $fileName) : void
{
//$this->setLOG("Importing data, please wait", "i");
$table = 'npdata_csvfile_temp';
$importDB = "LOAD DATA LOCAL INFILE '$fileName' ";
$importDB .= "INTO TABLE $table ";
$importDB .= "COLUMNS TERMINATED BY ',' ";
$importDB .= 'OPTIONALLY ENCLOSED BY "\""';
$importDB .= "LINES TERMINATED BY '\\n' ";
$importDB .= "IGNORE $ignoreLines LINES ";
DB::connection()->getpdo()->exec($importDB);
//$this->setLOG("Done with importing data", "i");
}

Related

Laravel Storage not storing created PDF files

I am facing an issue where my created PDF's are not being stored in laravel.
I have the following set in my filesystems.php under the disks tag
'completedforms' => [
'driver' => 'local',
'root' => storage_path('app/storage/completedforms'),
],
In my controller I have the following:
$pdf = PDF::loadView('report.form19', compact('generalreport','monthlyRoll', 'nightsInMonth', 'groupfee', 'subs', 'wing','weeksinmonth', 'meetingnights', 'lastRollMap', 'month_name', 'totalmember', 'totalcadets', 'totalnco', 'totalto', 'totalofficer'));
Storage::disk('completedforms')->put('Form 19 - '.$month_name . ' ' . $lastRollMap->roll_year.'.pdf', $pdf->output());
return $pdf->download ('Form 19 - '.$month_name . ' ' . $lastRollMap->roll_year.'.pdf');
I have added use Illuminate\Support\Facades\Storage; to my Controller
The pdf is created and downloads no issues, however the file is not being saved in the located as difined for the disk in the filesystems.php.
I have created the folder manually to ensure it exists. I have even set the file name to test.php to remove any variables fromm the file name
storage_path already starts at: /storage,
so change it like so:
'root' => storage_path('/desired'),

Laravel adds mysql in file path

I am facing a weird issue with Laravel 5.5. I am working on my local xampp server and trying to execute LOAD DATA INFILE query in controller function. But I am getting error PDOException (HY000)
SQLSTATE[HY000]: General error: 29 File 'D:\xampp\mysql\data\uploads\RDMST.csv' not found (Errcode: 2 "No such file or directory")
Currently my csv file is located at public/uploads folder. I tried various path settings for filename like
$fileCsv = 'uploads/RDMST.csv';
$fileCsv = public_path().'/uploads/RDMST.csv';
But I am getting same error and please notice the error path shows mysql\data in path. I am not getting from where it is appending this two folders in path. When I echo public path , it displays this:
D:\xampp\htdocs\tax\public
So, can you please help how to use path for load file without appending this "mysql\data" in path?
Any help is greatly appreciated.
Here is my complete controller function:
public function getCsv()
{
//echo public_path(); die;
//$fileCsv = public_path().'/uploads/RDMST.csv';
$fileCsv = 'uploads/RDMST.csv';
echo $query = "LOAD DATA INFILE '".$fileCsv."'
REPLACE
INTO TABLE tblreception
(year,
reception_number,
file_date,
file_time,
instrument_type,
#created_at,
#updated_at)
SET created_at=NOW(),updated_at=null";
DB::connection()->getPdo()->exec($query);
//return view('reception');
}
Can we not use csv file path?
Thanks

Laravel file upload creates folder with a temp file

I'm trying to get my application to upload files to "public/uploads/documentos/{the-id}" but can't figure out what's wrong with my current setup. Right now, if I upload a file called "myfile.pdf", it creates a folder named "myfile.pdf" and inside of it a *.tmp file. In my database, "{the-id}/myfile.pdf" is saved as the file url but this takes me to the folder view, when what I want is to see the file inside of it.
How can I change it so that when a document is upload, it creates the file "myfile.pdf" directly under "public/uploads/documentos/{the-id}" so that I can access it like that? {the-id} is a folder created based on the patient's id, so all documents belonging to them are saved to the same folder.
Controller
public function store(Request $request)
{
$this->validate($request, [
'tipo' => 'required|max:100',
'descripcion' => 'max:200',
'fecha_documento' => 'max:20',
'archivo' => 'required|mimes:doc,docx,pdf,jpg,png,jpeg',
'mascota_id' => 'required',
'mascota_num' => 'required',
]);
$documento = new Documento;
$documento->mascota_num = $request->input('mascota_num');
$documento->mascota_id = $request->input('mascota_id');
$documento->tipo = ucfirst($request->input('tipo'));
$documento->descripcion = ucfirst($request->input('descripcion'));
$documento->fecha_documento = $request->input('fecha_documento');
if($request->hasFile('archivo')) {
$archivo = $request->file('archivo');
$archivo_folder = public_path('/uploads/documentos/') . $request->input('mascota_num');
$archivo_nombre = $archivo->getClientOriginalName();
$archivo_url = $archivo_folder . '/' . $archivo_nombre;
if (file_exists($archivo_folder)) {
$archivo->move($archivo_folder . '/' . $archivo_nombre);
} else {
File::makeDirectory($archivo_folder, $mode = 0777, true, true);
$archivo->move($archivo_folder . '/' . $archivo_nombre);
}
$documento->archivo = $request->input('mascota_num') . '/' . $archivo_nombre;
$documento->save();
return redirect()->route('mascotas.show', [$request->input('mascota_num')])->with('message', 'Documento agregado exitosamente.');
}
}
How my uploaded files look with this code:
uploads/documentos/
-- 1
-- file.pdf /folder
-- random_name.tmp /file
-- 2
-- file.pdf /folder
-- random_name.tmp /file
-- otherfile.pdf /folder
-- random_name.tmp /file
}
What I want
uploads/documentos/
-- 1
-- myfile.pdf /file
-- 2
-- myfile.pdf /file
-- otherfile.pdf /file
Ideally, I'd like to keep the files private, so I tried to upload them to the storage folder with this code:
Storage::put('documentos/'.$request->input('mascota_num').'/', $archivo_nombre);
$documento->archivo = Storage::url('documentos/'.$request->input('mascota_num').'/'.$archivo_nombre);
but {the-id} folder wasn't created and the files weren't saved, all I got was:
storage/app/documentos/
-- 1 /file without extension
-- 2 /file without extension
I'd settle for making the first part work for now. Thanks in advance for your help.
After much trial and error, I managed to upload files to the storage folder of my application.
if($request->hasFile('archivo')) {
$archivo = $request->file('archivo');
Storage::disk('documentos')->put($request->input('mascota_num') . '/' . $archivo->getClientOriginalName(), File::get($archivo));
$documento->archivo = $request->input('mascota_num') . '/' . $archivo_nombre;
$documento->save();
}
Files are saved to /storage/app/public/documentos/ under the correct patient id folder and with the correct file name.
I haven't found a way to correctly link to the files from my show blade, Storage::url('documentos/'.$documento->archivo)) shows a 404 error page, even though the file path is correct. Hopefully I can get this working next.

How to clear user cache in APCu?

I have tried to clear the user cache using this PHP code and access it from the browser:
<?php
apc_clear_cache();
apc_clear_cache('user');
apc_clear_cache('opcode');
echo json_encode(array(
'success' => true,
));
but it doesn't work.
(I am using these tools to see if it's working or not https://rtcamp.com/tutorials/php/zend-opcache/ )
Also when the user cache gets full, it doesn't restart from 0. The APCu just stops working.
I have tried to set apc.user_ttl=0, but APCu doesn't recognize it.
My settings are:
extension=apcu.so
apc.enabled=1
apc.shm_size=10240M
apc.ttl=7200
apc.enable_cli=1
apc.gc_ttl=3600
apc.entries_hint=4096
apc.slam_defense=0
apc.enable_cli = 1
apc.user_ttl=0
apc.serializer=igbinary
<?php
if (extension_loaded('apc')) {
echo "APC-User cache: " . apc_clear_cache('user') . "\n";
echo "APC-System cache: " . apc_clear_cache() . "\n";
}
if (extension_loaded('apcu')) {
echo "APCu cache: " . apcu_clear_cache() . "\n";
}
if (function_exists('opcache_reset')) {
// Clear it twice to avoid some internal issues...
opcache_reset();
opcache_reset();
}
The tool you are using is for Opcache, it doesn't know about APCu.
The script you need to look at the status of APCu is:
PHP 7: https://github.com/krakjoe/apcu/blob/master/apc.php
PHP 5: https://github.com/krakjoe/apcu/blob/PHP5/apc.php
If you believe you have found a bug, please report it on github.

Encoding german characters

I need to import with load data some perl - generated files to oracle database.
Perl-script get a webpage and write csv file.
Here a simplified script:
use File::Slurp;
my $c= ( $user && $passwd )
? get("$protocol://$user:$passwd\#$url")
: get("$protocol://$url");
write_file("$VZ_GET/$FileTS.$typ.csv",$c);
Here a sample line from the webpage:
5052;97;Jan;Ihrfelt 5053;97;Jari;Honko 5121;97;Katja;Keitaanniemi 5302;97;Ola;Södermark 5421;97;Sven;Sköld 5609;97;Peter;Näslund
Content of the webpage is saved in var $c.
Here a sample line of csv file:
5053;97;Jari;Honko
Here a load command:
LOAD DATA
INTO TABLE LIQA
TRUNCATE
FIELDS TERMINATED BY ";"
(
LIQA_ANALYST_ID,
LIQA_FIRM_ID,
LIQA_ANALYST_FIRST_NAME,
LIQA_ANALYST_LAST_NAME,
LIQA_TS_INSERT DATE 'YYYYMMDDHH24MISS'
)
Command SELECT * FROM NLS_DATABASE_PARAMETERS WHERE PARAMETER = 'NLS_CHARACTERSET'; returns AL32UTF8.
The generated csv file is recognized as UTF-8 Unicode text.
Anyhow I cant import german characters. In the csv file they are still correct. But it is not the case in the database.
I have also tried to convert $c like this:
$c = encode("iso-8859-1", $c);
The generated csv file is stll recognized as UTF-8 Unicode text.
I have no clue how can I fix it.
I have solved it:
$c = decode( 'utf-8', $c );
$c = encode( 'iso-8859-1' , $c );

Resources