Magento Certified Developer

Kurzinfo


Andreas von Studnitz

  • Diplom-Informatiker
  • 6 Jahre Entwicklungs- und Projektleitungserfahrung in einer Internet-Agentur
  • Magento-Freelancer
  • Magento Certified Developer
  • 4 Jahre Magento-Erfahrung

mehr »

Kontakt

Telefon:
0170 486 0 464

E-Mail:
avs(at)avs-webentwicklung.de 

Twitter: twitter.com/avstudnitz

mehr »

< Magento: Fehler beim Index-Aufbau - Sofortmaßnahmen

Magento: Import mit der neuen, schnellen Import-Schnittstelle für Produkte und Kunden

19.09.2011 21:52

Die seit Magento CE 1.5 verfügbare neue Importfunktion beschleunigt den Import von Produkten und Kundendaten deutlich. Aber wie kann man den neuen Import eigentlich in eigenen Modulen einsetzen?

Seit der Magento-Version 1.5 (Community Edition) bzw. 1.10 (Enterprise und Professional Edition) gibt es ein neues Schnittstellen-Modul namens ImportExport. Dieses importiert und exportiert Produkte und Kundendaten. Während der alte Import kaum über eine Geschwindigkeit von wenigen Produkten pro Sekunde hinaus kommt, sind mit dem neuen Modul auch mehrere hundert Produkte pro Sekunde machbar (siehe z.B. der Beitrag von Roman Zenner).

Über die Admin-Oberfläche sind die Funktionen zum Import und Export über System -> Import/Export zugänglich und relativ intuitiv bedienbar. Für einen regelmäßigen Import sollte die Schnittstelle jedoch über ein Modul bedienbar sein.

In seinen Vorträgen bei der Magento Imagine 2011 und bei Meet Magento #5.11 hat Vinai Kopp sehr ausführlich die Verwendung des Moduls mit eigenen Import-Adaptern präsentiert. Wer sich näher mit der Technik beschäftigen möchte, sollte sich auf jeden Fall das Video des Vortrags in Leipzig (drittletzter Vortrag auf der Seite) ansehen.

Das ImportExport-Modul hat im Standard-Funktionsumfang jedoch einen großen Nachteil: es erwartet eine Datei zum Import. Möchte man stattdessen Inhalte aus einer Datenbank, einem Webservice oder einer anderen Schnittstelle verwenden, muss ein alternativer Source-Adapter implementiert werden.

Leider ist das nicht so einfach wie gewünscht, da sich die entsprechende Basis-Klasse nicht einfach wie gewünscht ableiten lässt, dank der "schönen" folgenden Klassendeklaration:

abstract class Mage_ImportExport_Model_Import_Adapter_Abstract 
implements SeekableIterator
{
final public function __construct($source)
{...}
...
}

Diese Klasse ist die Basis für eigene Source-Adapter, die definieren, wo die Daten herkommen und in welcher Form sie vorliegen. An anderer Stelle wird ein Objekt der Klasse Mage_ImportExport_Model_Import_Adapter_Abstract als Source-Adapter erwartet.

Es sind also weitere Änderungen notwendig. Damit nicht jeder Entwickler sich in die Materie einarbeiten muss, habe ich ein kleines Modul entwickelt, das sich bei Github herunterladen lässt. Es beruht darauf, dass die Daten als Array vorliegen - in ein Array kann man eigentlich immer beliebige Daten konvertieren.

Das Modul lässt sich in einem eigenen Modul beispielsweise wie folgt nutzen, nachdem mein Modul installiert wurde:

$data = array(
array(
'sku' => '1234567',
'_type' => 'simple',
'_attribute_set' => 'Default',
'_product_websites' => 'base',
'name' => 'Default',
'price' => 0.99,
'description' => 'Default',
'short_description' => 'Default',
'weight' => 0,
'status' => 1,
'visibility' => 4,
'tax_class_id' => 2,
'qty' => 76,
),
);
Mage::getSingleton('fastsimpleimport/import')
->processProductImport($data);

Die einzelnen Elemente des übergebenen Arrays repräsentieren dabei jeweils ein Produkt bzw. eine Ausprägung eines Produktes. Werden mehrere Elemente im äußeren Array übergeben, werden mehrere Produkte bzw. Ausprägungen eines Produktes angelegt bzw. angepasst.

Im Beispiel sind alle Pflichtfelder angegeben. Weitere mögliche Felder sind z.B. alle Attributcodes. Es ist aber auch möglich, z.B. Inhalte für bestimmte StoreViews, Varienten von konfigurierbaren Produkte oder Staffelpreise anzugeben, hierfür werden jeweils weitere Zeilen pro Produkt verwendet. Wichtig ist hierbei, dass der Array-Index 'sku' existiert, er muss aber keinen Wert beinhalten.

Die möglichen Varianten kann man leicht herausfinden, indem man ein Produkt wie gewünscht im Magento-Backend anlegt und anschließend exportiert. Den Aufbau der resultierenden CSV-Datei kann man in das zu importierende Array 1:1 übernehmen.

 

Der Import von Kundendaten läuft analog. Der nötige Befehl lautet

Mage::getSingleton('fastsimpleimport/import')
->processCustomerImport($data);

Der Hauptschlüssel ist das Feld "email" statt "sku". Weitere notwendige Felder lassen sich durch ausprobieren herausfinden (das Modul wirft eine entsprechende Exception) oder durch die Analyse einer Export-Datei.

 

Download bei GitHub

Kommentare

Andre , 23.09.11 13:20:
Danke für's Teilen. Ich habe den Link zu diesem Post gleich mal an den Magento-Geek bei uns im Betrieb weitergeschickt :)
Nicolas , 28.11.11 12:34:
Auch von mir ein herzliches "Dankeschön"! Dank deiner Erweiterung habe ich es recht schnell geschafft ein externes Skript zu basteln, welches eine XML-Schnittstelle unseres Lieferanten anspricht und die Produktdaten per Array an die Import-Schnittstelle übergibt. Hätte ich sonst nie so schnell hinbekommen (bin Magento-Newbie). Nun habe ich allerdings das Problem, dass es offenbar ein Memory Leak gibt - nach gut 50 importierten Artikel hat sich der verwendete Arbeitsspeicher auf über 100mb erhöht. Kannst du mir vielleicht verraten, wie ich den Speicher freigeben kann? Wäre wirklich sehr nett, bin da etwas hilflos...
Nicolas , 01.12.11 15:11:
Ich konnte das Problem übrigens umgehen, in dem ich bei jedem Aufruf von "processCustomerImport" 100 oder mehr Artikel importiere (alles andere macht Performance-technisch auch keinen Sinn). Das Memory Leak bleibt natürlich bestehen, bereitet dann jedoch erst nach einigen Tausend Artikeln Probleme...
André , 05.12.11 15:07:
auch von mir ein herzliches Dankeschön für das schöne Tutorial. Ich hoffe gegen eine Verlinkung hast du nichts?

Freundliche Grüße
Andreas von Studnitz, 07.12.11 11:49:
Nein, ich habe keine Probleme mit Verlinkungen :-)
Andreas von Studnitz, 19.12.11 11:58:
Eine ausführliche Beschreibung der Standardfunktionalitäten habe ich unter http://www.webguys.de/magento/turchen-19-produktimport-mit-der-importexport-schnittstelle/ verfasst. Darin: Import von Mehrsprachigkeit, Kategorien, Staffelpreisen, Produktbildern, Produktverknüpfungen und Gruppierten Produkten.
Thomas Müller, 23.03.12 14:33:
Wieso hast du die Methode _getUploader() überschrieben und das Import-Verzeichnis auf "promo_import" geändert? Das hat mich gerade eine Stunde Sucharbeit gekostet :D
Carmen , 29.03.12 12:39:
Hi Andreas,
ich mag ja Arrays und daher habe ich mich sehr gerne Deines Moduls bedient und soeben ein ziemlich verschränktes Array mit Zubehör und Up-Selling und mehreren Kategorien an Dein Modul übergeben - und es wird tadellos importiert.
Bis nachösterlich zum Stammtisch!
Thomas Müller, 04.05.12 16:36:
Hallo Andreas,

ich hatte gerade ein Performance-Problem mit deinem ArrayAdapter und großen Datenmengen (ca. 70.000 Datensätze). Die getColNames() Funktion ist aufgrund der vielen Aufrufe von array_merge() extrem langsam gewesen. Ich habe sie etwas umgeschrieben, so dass sie nun wesentlich schneller läuft:

public function getColNames()
{
$colNames = array();
foreach($this->_array as $row) {
foreach (array_keys($row) as $key) {
if (!is_numeric($key) && !isset($colNames[$key])) {
$colNames[$key] = $key;
}
}
}
return $colNames;
}

Vielleicht magst du dir das ja mal anschauen? Ich denke auch, dass man an dieser Stelle auch noch sauberer Arbeiten kann.
Julian , 12.06.12 23:50:
Warum gibt mir Magento beim Aufruf von Mage::getSingleton('fastsimpleimport/import') false zurück?

Ich habe den app-Ordner in den Magento app-Ordner kopiert.

Und dann eine Php-Datei im Hauptverzeichnis erstellt. Zum Schluss die app/Mage.php includet.

Wo liegt der Fehler?
Andreas von Studnitz, 15.06.12 22:14:
Hallo Julian,
hier würde ich gern die komplette Datei sehen.

Ich habe eine Beispieldatei unter https://github.com/avstudnitz/AvS_FastSimpleImport/blob/master/test.php bereitgestellt - soll diese im Hauptverzeichnis liegen, muss nur der Pfad zur Mage.php angepasst werden.
Benjamin Schnoor, 22.06.12 16:21:
Erstmal vielen Dank für deine Extension funktioniert soweit super.
Nur bekomme ich es nicht hin unterschiedliche Produktmengen zu importieren. Er nimmt immer die Menge des ersten Produktes. Habe das ganze auch mal mit einem aus zwei Produkten bestehendem Testarray ausprobiert, mit dem selben Ergebnis. Hast du vielleicht eine Idee warum dies passiert?
Danny Gerhard, 06.07.12 19:02:
Hallo, wirklich ein sehr interessantes Modul. Nur habe ich als PHP Leihe eine Frage. Wie kann ich dem modul sagen es soll die produkte und kategorien der csv in eine bestinnte unterkategorie importieren lassen? Gruss danny
Andreas von Studnitz, 06.07.12 20:50:
Hallo Danny,
wie die CSV-Datei bzw. das Array aufgebaut sein muss, um Kategorieverknüpfungen zu importieren, habe ich unter http://www.webguys.de/magento/turchen-19-produktimport-mit-der-importexport-schnittstelle/ im Kapitel "Kategorien" beschrieben.
Patrick Baber, 08.08.12 17:07:
Hallo Andreas,

zunächst einmal vielen Dank für deine hervorragende Arbeit! Ich hab jetzt allerdings ein Problem mit einem eigenen Attribut. Ich habe ein Ja/Nein-Attribut im Attributset angelegt, welches ich nun mittels Import befüllen will. Wenn ich das Feld nun mit einer 1 für Ja füllen will, bekomme ich eine Fehlermeldung:

Invalid value for 'attribut_test'

Wenn ich versuche es statt einem Integer mit einem Boolean (true) versuche zu befüllen funktioniert dies aber ebenfalls nicht. Was muss ich denn in dem Array hinterlegen, damit der Import das schluckt?

Gruss Päddl
Patrick Baber, 08.08.12 17:24:
OK, ich habe es doch jetzt tatsächlich herausgefunden. Es muss als String mit "yes" oder "no" übergeben werden ;-)
Andreas von Studnitz, 08.08.12 17:26:
Hallo Patrick,
versuch es doch mal mit "Yes" oder "Ja".
Eydun , 28.08.12 04:02:
It would be great, if you could also create some example for importering configurable products.
Pi , 17.09.12 11:42:
Zur Installation ein Import Verzeichnis auf dem Server anlegen und in app\code\community\AvS\FastSimpleImport\etc\config.xml den Pfad vier mal bei "import_product_types" setzen. Dann die Dateien einfach per ftp hochladen.

Hat man die Config vorher nicht gesetzt bekommt man "Service Temporarily Unavailable" und muss "maintenance.flag" löschen damit der Shop wieder geht.
Andreas von Studnitz, 17.09.12 11:45:
@pi
Den Kommentar verstehe ich nicht. Zur Installation reicht es normalerweise aus, die Dateien einzuspielen und evtl. den Cache zu leeren.
Pi , 17.09.12 17:29:
Ja, du hast recht das hat am Ende auch nicht funktioniert. Dateien in /app kopieren, in test.php den Pfad auf "app/Mage.php" ändern und Cache leeren hat jetzt funktioniert. Hatte anfangs nicht den Cache geleert. Jetzt geht es, super danke!
Christian Kehres, 18.09.12 15:42:
Hallo, also das Script funktioniert soweit ganz gut,... ich habe nur ein Problem mit mehrzeiligen Beschreibungen z.B.

Ich habe eine XML welche ich in ein Array umwandel, dieses Array schicke ich dann an dein Modul hier, funktioniert super, nur sobald die Beschreibung z.B. mehrzeilig ist bleibt die Beschreibung in Magento einfach komplett leer. Jemand ne Idee?
Christian Kehres, 02.10.12 09:21:
Ich habe irgendwie generell Probleme mit "name", "description" und "short_description"... Diese sind bei mir immer leer wenn es Mehrzeilig WAR. Habe aus den mehrzeiligen Einträgen Einzeiler gemacht, aber trotzdem, die 3 Spalten bleiben einfach leer, Preis, SKU etc werden Problemlos importiert,... ich steh hier gewaltig aufem Schlauch.

Hier ein Beispiel:
GEHT:: [name] => Container Container mit 105 % Vollauszug und Soft Einzug Formulareinsatz 10 x DIN A4 X705

GEHT NICHT:: [name] => Container Container mit 105 % Vollauszug und Soft Einzug Querunterteilung 1 Stück für 43,3 cm X47545
Pi , 02.10.12 15:54:
Inzwischen läuft mein Import. Vielen Dank für das tolle Modul!

Bei mir ist der Import jedoch nicht so schnell wie im Video. Statt der 100'000 in 12 Minuten schafft er eher so 200 in 12 min. Liegt vielleicht an der Layered Navigation die mit mehreren Eigenschaften nutze.
Andreas von Studnitz, 02.10.12 16:17:
@Pi Es könnte auch an der Partiellen Indizierung liegen, wenn du die an hast - sie frisst viel Performance.
Pi , 16.10.12 16:33:
Danke, ohne Partiellen Indizierung läuft es deutlich schneller!

Neue Problem: Ich hätte gerne eine Mindestbestellmenge pro Artikel. Dazu setze ich:
use_config_min_sale_qty = 0
min_sale_qty = $value

Mir scheint dabei wird der erste Wert von min_sale_qty und use_config_min_sale_qty für alle Artikel verwendet. Ich hab leider noch nicht rausgefunden ob das am Plugin oder am Import selbst liegt.
Pi , 17.10.12 10:02:
Bugfix dafür in Product.php, Zeile 1609
Mage_ImportExport_Model_Import_Entity_Product::_saveStockItem(), $row initialisieren:

$row = array();
$row['product_id'] = $this->_newSku[$rowData[self::COL_SKU]]['entity_id'];
$row['stock_id'] = 1;
Andreas P, 19.02.13 10:26:
Klasse Import Schnittstelle funktioniert einwandfrei, nur kann man irgendwie noch die import.php datei so verändern das nicht vorhandene Kategorien erstellt werden?
Andreas von Studnitz, 19.02.13 11:15:
Hallo Andreas,
das müsstest du in einem vorgelagerten Schritt selbst tun. Seit Kurzem unterstützt der Import auch Kategorien, eine kurze Beschreibung mit Beispiel dazu findest du unter https://github.com/avstudnitz/AvS_FastSimpleImport#features.
Andreas P, 21.02.13 12:16:
hallo,
Kann ich mit deiner Schnittstelle auch Kategorien Updaten?
Andreas , 17.05.13 11:48:
Hi Andreas,

tolles script! gibt es eine möglichkeit mehr als ein produktbild zu importieren?

danke und gruss

anreas
Andreas von Studnitz, 17.05.13 11:59:
Ja - in einem zweiten Subarray nochmal die entsprechenden Felder befüllen. In meinem Beitrag unter http://www.webguys.de/magento/turchen-19-produktimport-mit-der-importexport-schnittstelle/ sind das stattdessen separate Zeilen, aber das Format ist das gleiche.
Timo Schwarz, 16.06.13 23:27:
Hallo,
super Anleitung hat uns sehr geholfen.
Haben damit 42.000 Artikel in 12 Sprachen sehr zügig in den Shop importieren können.

Jedoch haben wir eine Frage, die Artikel sind alle im Backend vorhanden und den Kategorien zugewiesen, leider werden Sie aber im Frontend nicht angezeigt.

Daten sind alle gefüllt, Indizes neu aufgebaut und die Caches gelöscht. Können uns nicht wirklich erklären woran es noch liegen könnte.

Kann uns hier jemand helfen?
Vielleicht haben wir hier beim importieren eine Spalte vergessen auszufüllen?
andreas , 22.06.13 14:42:
hallo,
selbiges problem wie timo habe ich auch!

gruss
andreas , 02.07.13 11:11:
Hi,

es scheint so: wenn der bestand mehr als 1 ist wird das produkt nicht in den katalog übernommen!

wenn ich hardcoremässig:

qty' => 1 und 'is_in_stock' => 1

setze klappt alles super.

Gruss

andreas
Ginger , 28.07.13 21:20:
Hallo,
vielen Dank für diese sehr hilfreiche Anleitung.

Gibt es die Möglichkeit, dass ich in einem Produkt-Array unterschiedliche Produkttitel für die Views "Deutsch" und "Englisch" vergeben kann?

Grüße Ginger
Andreas von Studnitz, 28.07.13 21:29:
Hallo Ginger,
hier hilft die Anleitung unter http://www.webguys.de/magento/turchen-19-produktimport-mit-der-importexport-schnittstelle/ - Abschnitt "Mehrsprachigkeit" - weiter.
Chris K., 12.09.13 15:28:
Hallo,
ich muss vorweg schicken, ich habe so gar keine Ahnung von dem Allen.
Ich versage schon beim Installieren des Modules.
Könnte ich bitte eine kurze Anleitung haben, wie ich das implementiere?
Achso: Magento ver.1.7.0.2 unter IIS 7
Danke im voraus...
Andreas von Studnitz, 12.09.13 15:38:
Hallo Chris,
ich fürchte, zum sinnvollen Benutzen des Moduls sind grundlegende Programmierkenntnisse mit PHP und Magento unabdingbar. Das Modul wird installiert wie jedes andere Modul auch. Aber man muss noch ein eigenes Modul bzw. PHP-Skript schreiben, um es einzusetzen.
Franz Haupt, 13.11.13 10:01:
wie sieht ein array mit mehreren Bildern für den produkt Importer aus. Bei mir sieht das so aus:
'thumbnail' => 'produkt_1_1.jpg',
'small_image' => 'produkt_1_1.jpg',
'image' => 'produkt_1_1.jpg',
'_media_image' => 'produkt_1_1.jpg',


funzt net.
Ausserdem muss ich immer meida_gallery angeben. Was bedeutet das?
Kommentar hinzufügen












Den Code eingeben: *


* - Pflichtfeld