Interne CSV-Import-Funktion und eine Unique-OXID

Nach dem ich mir die Lektüre des [U]Threads[/U] zu dem o.g. Thema durchgelesen habe, habe ich versucht, das Problem irgendwie umzugehen um die Artikel nicht händisch eintragen zu müssen aber dennoch die OXID-übliche ID zu haben.

Ich habe in den CSV-Import-Dateien etwas rumgeschnüffelt und an der Stelle, an der das Feld OXID überprüft wird eine kleine Änderung vorgenommen.
Bisher war es so, dass falls in der CSV-Datei keine OXID definiert wurde, der Fehler “ERROR: Articlenumber/ID missing!” kam. Ich habe das jetzt etwas umgewandelt und dazu gebracht, dass falls eine OXID gar nicht vorhanden ist, eine neue automatisch generiert wird.

Hier die abgeänderte Funktion (Datei: …/core/oxerpcsv.php; Zeile: um die 353):

protected  function _checkIDField( $sID )
    {
        if ( !isset( $sID ) || !$sID ) {
            $aRow['OXID'] = oxUtilsObject::getInstance()->generateUID();
        } elseif ( strlen( $sID) > 32 ) {
            throw new Exception( "ERROR: Articlenumber/ID longer then allowed (32 chars max.)!");
        }
    }

Was meint Ihr zu dieser Vorgehensweise? Habt Ihr dazu irgendwelche Bedenken?

[QUOTE=knackig;38441]Nach dem ich mir die Lektüre des [U]Threads[/U] zu dem o.g. Thema durchgelesen habe, habe ich versucht, das Problem irgendwie umzugehen um die Artikel nicht händisch eintragen zu müssen aber dennoch die OXID-übliche ID zu haben.

Ich habe in den CSV-Import-Dateien etwas rumgeschnüffelt und an der Stelle, an der das Feld OXID überprüft wird eine kleine Änderung vorgenommen.
Bisher war es so, dass falls in der CSV-Datei keine OXID definiert wurde, der Fehler “ERROR: Articlenumber/ID missing!” kam. Ich habe das jetzt etwas umgewandelt und dazu gebracht, dass falls eine OXID gar nicht vorhanden ist, eine neue automatisch generiert wird.

Hier die abgeänderte Funktion (Datei: …/core/oxerpcsv.php; Zeile: um die 353):

protected  function _checkIDField( $sID )
    {
        if ( !isset( $sID ) || !$sID ) {
            $aRow['OXID'] = oxUtilsObject::getInstance()->generateUID();
        } elseif ( strlen( $sID) > 32 ) {
            throw new Exception( "ERROR: Articlenumber/ID longer then allowed (32 chars max.)!");
        }
    }

Was meint Ihr zu dieser Vorgehensweise? Habt Ihr dazu irgendwelche Bedenken?[/QUOTE]
Das wird so nicht funktionieren…

“$aRow” ist ja nur lokal in der function definiert…

Vermutlich muss das “$this->aRow” werden.

Warum willst Du denn die völlig unnütze OXID ID haben? Beleg das Feld OXID ganz einfach mit einem eindeutigen Index aus den Importdateien (evtl. sogar aus Deiner WAWI) und das wars doch.

mfG

Michael

@modellzentrum:
+1

Die Hash-ID von Oxid führt nur zu völliger Unübersichtlichkeit, wenn man direkt mit den Daten in SQL arbeiten will, oder mal schnell sehen will, wer eigentlich Vater ist etc.

Eine eigene sprechende ID ist da viel hilfreicher.

[QUOTE=avenger;38535]Das wird so nicht funktionieren…

“$aRow” ist ja nur lokal in der function definiert…

Vermutlich muss das “$this->aRow” werden.[/QUOTE]

Das hat auf dem Wege, wie ich das gemacht habe, sehr gut funktioniert. Falls keine ID im Feld OXID eingetragen ist, wird eine neue generiert. Habe auf diese Weise die Produkte (oxarticles) und hinterher, schon mit Zuordnung der vergebenen OXID die Produktbeschreibungen (oxartextends). Im Shop ist jetzt alles wie ich wollte.

@modellzentrum
@oxal
Ich habe diesen Weg gewählt, da ich die Produkte nur beim ersten Mal importieren muss. Später werden die Sachen eher manuell gepflegt (es ist eine recht überschaubare Produktmenge), da wäre der Aufwand für die Anpassung der System-ID-Vergabe doch um einiges größer als der Nutzen daraus. Schauen wir mal, vielleicht werde ich mich später noch umentscheiden und werde das noch ändern, für den jetzigen Zeitpunkt reicht es mir :wink:

Ich arbeite gerade an einer ETL-Lösung zwischen ERP (WaWi) und Shop-Datenbank, wobei das Thema OXID UID um so wichtiger wird je höher das Datenvolumen.

Die o.g. Änderung im oxerpcsv.php Code
$aRow[‘OXID’] = oxUtilsObject::getInstance()->generateUID();
funktioniert zwar ein einziges mal gut, birgt aber fatale Spätfolgen in sich, wie folgende Testreihe zeigt:

CSV Import-Tests in Tabelle “oxarticles”:

(I) ORIGINAL CODE:
… throw new Exception(“ERROR: Articlenumber/ID missing!”);

  1. Test -> PROBLEM
    "ERROR: Articlenumber/ID missing!"

  2. Test –> ohne UID Generierung
    Bei Import-Schritt 2 “OXID = überspringen” gewählt.
    Es wird die Artikelnr. (z.B. 4711) auch bei der OXID generiert.
    OXID = 4711

(II) GEÄNDERTER CODE:
… $aRow[‘OXID’] = oxUtilsObject::getInstance()->generateUID();

  1. Test –> OK mit UID
    Es wird eine 32-stellige UID generiert.
    OXID= 2cdf32c6b808cf436f29c4947ad2accc

  2. Test –> PROBLEM bei UPDATE
    Nach erneutem Upload z.B. Artikelpreis-Update:
    Der selbe Artikel wird erneut mit neuer UID erzeugt – also redundant
    OXID = 2cd948b280a479fa36bcbddc316ce434

  3. Test -> PROBLEM keine UID
    Erneuter Upload jedoch Import-Schritt 2 “OXID = überspringen” gewählt.
    Der selbe Artikel wird erneut angelegt – also redundant.
    Wobei die Artikelnr. (z.B. 4711) auch bei der OXID generiert wird
    OXID = 4711 (z.B.)

Einfache LÖSUNG zur UID:

Generiere für die zu importierende CSV-Datei gleich in der Sortimentsliste - z.B. in Excel per VBA - zu jedem Artikel 32-stellige GUID’s als Festwert, dann kannst Du auf Basis dieser ID’s konfliktlos Artikel in die OXID-Datenbank importieren und updaten so oft als nötig

Danke für die Anregungen… in der Tat, sobald ich die gleiche Tabelle 2 Mal importiere, wird eine neue ID generiert. Wenn ich aber die Liste der bereits eingepflegten Artikel anpassen möchte, dann werde ich eh den aktuellen Stand aus dem Shop ziehen, dabei wird dann natürlich auch die OXID gezogen und ist auch bei dem späterem Import schon mit im Spiel und muss nicht neu generiert werden.

Meine Lösung ist in erster Linie für den schnellen Upload von NEUEN Artikeln und nicht für die dauerhafte Pflege des Einträge. Die von mir vorgesehene Aufgabe hat diese Änderung gut überstanden :wink:

Gruß und gute Nacht

Ich frage mich echt warum ihr hier Probleme erfindet die vorhern noch nicht da waren.

Einfach beim CSV-Import eine fortlaufende Artikelnummer aus der Wawi mitgeben als oxartnum und fertig. Bei mir sind das übersichtliche 5-6 stellige Zahlen. Aus der oxartnum wird die oxid. Ich kann damit jederzeit Artikel neu erstellen, updaten, alles. Und unique sind die auch.

CYA

Für verschiedene Shops kann die Situation und damit die Lösung aber eine andere sein und sich auch später noch ganz anders weiterentwickeln.

Es gibt viele Import-Wege: Mit oder ohne WaWi und WaWi-Schnittstelle usw.
Wer (noch) keine WaWi hat, möchte vielleicht erst mal den Oxid-Shop mit Artikeln befüllen, austesten usw. bevor weitere Überlegungen angestellt werden. Zum Einstieg bietet sich der in Oxid vorhandene, generische Import aus einer CSV-Datei an.

Dabei stellt sich gleich die Frage, wieviele Artikel und Kategorien verarbeitet werden müssen, welchen Aufwand die Datenaufbereitung vom Ursprung her erfordert und mit welchem Verfahren das in akzeptabler Zeit erfolgen kann.

[ol]
[li] GENERIC IMPORT aus einer CSV-Datei taktet mit ca. 1 Artikel/Sekunde.
[/li]Also bei 1.000 Art. ca. 16 Minuten, bei 50.000 Art. ca. 14 Stunden rein rechnerisch.
Hinzu kommen noch Timeouts und anderer Trouble der die Zeit erhöht.

[li] DATEN-TRANSFER aus einer CSV-Datei oder aus der WaWi-DB, je nach Schnittstelle oder ETL-Software DIREKT ODER INDIREKT zur Shop-DB, ca. 1Art./sec oder 500 bis zu max. 10.000 Art./sec., abhängig vom Transferprozess und anderen Parametern.
[/li][/ol]

FAZIT:

Wenn eine WaWi schon passende UIDs generiert, können diese natürlich in Oxid übernommen werden – egal auf welchem Import-Weg.

Wenn, wie im vorliegenden Fall, (noch) keine WaWi existiert oder ein anderer Weg passender ist, dann gibt es dazu die oben und zuvor schon diskutierten Lösungswege.