Ankündigung

Einklappen
Keine Ankündigung bisher.

Große Daten in csv schreiben

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • goodm
    hat ein Thema erstellt Große Daten in csv schreiben.

    Große Daten in csv schreiben

    Tach,

    Fall: Ich möchte den Inhalt einer Tabelle nach bestimmten Kriterien auslesen und in eine CSV-Datei schreiben. Grundsätzlich kein Problem.

    Problem: Die Datenmenge übersteigt die in PHP eingestellen Größen. Es sollen ~150.000 Zeilen geschrieben werden, doch bei ~ 60.000 ist schluss.

    Welche Möglichkeiten gibt es da? Hatte mir zuerst überlegt das mit temporären Tabellen zu machen, habe aber noch nicht damit gearbeitet. Kennt ihr eine Möglichkeit dies zu bewerkstelligen? Es besteht nicht die Möglichkeit an der PHP.ini oder Apache oder sonst wo was zu verändern.

    Ich mache es so, dass die Daten in einer Schleife aus der Tabelle geholt werden und formatiert in ein Array geschrieben werden.

    Später kommt eine zweite Schleife, die dieses Array Zeile für Zeile in CSV-Datei schreibt, was bis zu den ca. 60.000 Zeilen auch einwandfrei klappt.

    Ich mache die ganze Sache (das rausholen aus der DB) mit AdoDB.
    fg

  • goodm
    antwortet
    Das Statement mit der Summe ist identisch mit dem Hauptstatement, nur habe ich die SELECT-Anweisung komplett durch COUNT(*) ersetzt.

    Und es stimmt wohl, irgendwas an dem Statement scheint wohl falsch gewesen zu sein. In einem hatte ich wohl was mit GROUP BY verwechselt (weggelassen). Nun ja, es funktioniert nun.

    Die Summe lese ich jetzt wohl komplett (umständlicher?) aus:

    PHP-Code:
    $from 0;
    $to $step 10000;
    $zaehler 1;

    do(
    $rs)
    {
        
    $limit ' LIMIT '.$from.', '.$to;
        
        
    $sum += count($rs $db->getArray($sql[1] . $limit));
        
        
    $from += $step;
    }while(
    $rs);

    ... 
    Jetzt stimmen die Ergebnisse auch.

    Vielen Dank,

    fg

    Einen Kommentar schreiben:


  • hpf
    antwortet
    Nachdem, was du gepostet hast, gibt es einfach keine weiteren Datensätze. Es liegt ja an keinem Timeout oder Memory-Limit, da das Script ja weiter läuft.

    Und warum wird die Summe nicht ausgegeben?
    PHP-Code:
    echo 'Zu erzeugende Dateien: '. ($sum) .'<br>'
    Code:
    Zu erzeugende Dateien: ...
    [EDIT]
    Achso, hast du unkenntlich gemacht, wie hier
    PHP-Code:
    $sql['main'] =  "...";
    $sql['count'] =  "..."
    Die wichtigste Information lässt du also weg - so geheim?
    Schonmal dran gedacht, dass die Statements vielleicht unterschiedliche Resultate liefern?

    Einen Kommentar schreiben:


  • goodm
    antwortet
    Zitat von nikosch Beitrag anzeigen
    150000 DS in ein Array zu prügeln, ist auch nicht gerade ein Pappenstiel. Wieso benutzt Du nicht reguläre Filefunktionen und gehst nach read-write-read-write vor?

    sieht auch verdächtig nach Query in Schleife aus.
    Ja, ich habe es so gemacht dass es das Hauptstatement in kleinere unterteilt (LIMIT ..., 10000).

    Sonst funktioniert überhaupt garnichts.

    Einen Kommentar schreiben:


  • nikosch
    antwortet
    150000 DS in ein Array zu prügeln, ist auch nicht gerade ein Pappenstiel. Wieso benutzt Du nicht reguläre Filefunktionen und gehst nach read-write-read-write vor?

    $rs = $db->getArray($sql['main'] . $limit);
    sieht auch verdächtig nach Query in Schleife aus.

    Einen Kommentar schreiben:


  • goodm
    antwortet
    ouh man, alles nochmal von vorne... (Eingabe gelöscht)

    PHP-Code:
    <?php
    //Statement
    $sql['main'] =  "...";


    $sql['count'] =  "...";

    $sum $db->getOne($sql['count']);

    echo 
    'Zu erzeugende Dateien: '. ($sum) .'<br>';

    $from 0;
    $to $step 10000;
    $zaehler 0;

    while(
    $from $sum)
    {
        
    $limit ' LIMIT '.$from.', '.$to;

        
    $rs $db->getArray($sql['main'] . $limit);

        
    $count count($rs);

        
    // Informationen nach Vorgabe formatieren
        // jeweils eine Zeile
        
    foreach($rs as $in => $ds)
        {
            
    $zaehler++;

            
    // (Daten formatiert speichern ($src)

            // Aktuelle Zeile speichern
            
    foreach ($src as $cell)
            {
                
    $dst[$zaehler] .= $cell .'|';
            }
            
    $dst[$zaehler] .= "\n";
        }

        
    $c_count += $count;

        echo 
    $count.' erzeugt ('.$c_count.') '.     $limit ' (LIMIT '.$from.', '.$to .')<br>';

        
    $from += $step;

    }

    $file 'files/NamederDatei.csv';
    $fp fopen ($file"wb");
    $i 0;

    foreach (
    $dst as $line)
    {
        
    // Fehler
        
    if(!fwrite($fp$line))
        {
            echo 
    '<p style="padding: 4px; background: red; color: #fff;"><b>Fehler:</b> Die Datei '$file.' konnte nicht beschrieben werden</p>';
            exit;
        }
        
    // Anzahl Zeilen festhalten
        
    else $i++;
    }

    // Erfolgreich erstellt
    echo '<p style="padding: 4px; background: #cdffcc;">Die Datei <b>'.$file.'</b> wurde erfolgreich erstellt. Es wurden <b>'$i .'</b> Zeilen geschrieben.</p>';

    fclose($fp);
    ?>
    Es wird auch kein Fehler ausgegeben, sondern irgendwann wird einfach nicht mehr geschrieben (habe es getestet, es wird nicht mehr ins Array geschrieben, irgendwann)

    Zu erzeugende Dateien: ...
    10000 erzeugt (10000) (LIMIT 0, 10000)
    10000 erzeugt (20000) (LIMIT 10000, 10000)
    10000 erzeugt (30000) (LIMIT 20000, 10000)
    10000 erzeugt (40000) (LIMIT 30000, 10000)
    10000 erzeugt (50000) (LIMIT 40000, 10000)
    10000 erzeugt (60000) (LIMIT 50000, 10000)
    1510 erzeugt (61510) (LIMIT 60000, 10000)
    0 erzeugt (61510) (LIMIT 70000, 10000)
    0 erzeugt (61510) (LIMIT 80000, 10000)
    0 erzeugt (61510) (LIMIT 90000, 10000)
    0 erzeugt (61510) (LIMIT 100000, 10000)
    0 erzeugt (61510) (LIMIT 110000, 10000)
    0 erzeugt (61510) (LIMIT 120000, 10000)
    0 erzeugt (61510) (LIMIT 130000, 10000)
    0 erzeugt (61510) (LIMIT 140000, 10000)
    Habe dort eine Schleife eingebaut, um den Prozess etwas zu beschleunigen.

    Einen Kommentar schreiben:


  • wolf29
    antwortet
    Hi.

    Wie sieht dein Code dafür aus? Verwendest du fputs oder fputcsv? Normalerweise ist die Größe "egal" - soweit ich weiß. Ich denke eher, dass irgendwann das Limit deines Server Platzes erreicht wurde, oder wenn das Skript länger als das Zeitlimit läuft, wird es abgeschossen (Fehler 500).

    Wolf29

    Einen Kommentar schreiben:

Lädt...
X