Ich habe eine CSV-Datei, die ich einfügen möchte, die aus ~ 1.500 Zeilen und 97 Spalten besteht. Ein vollständiger Import dauert ca. 2-3 Stunden und ich würde dies gerne verbessern, wenn es einen Weg gibt. Derzeit führe ich für jede Zeile ein $ post_id = wp_insert_post und dann ein add_post_meta für die 97 zugeordneten Spalten mit jeder Zeile aus. Das ist ziemlich ineffizient ...
Gibt es eine bessere Möglichkeit, dies so zu tun, dass eine post_id die Beziehung zwischen post und seinen post_meta-Werten beibehält?
Im Moment versuche ich dies auf meinem lokalen Computer mit Wamp, aber ich werde es auf einem VPS laufen lassen
wp-insert-post
Corey Rowell
quelle
quelle
Antworten:
Ich hatte vor einiger Zeit ähnliche Probleme mit einem benutzerdefinierten CSV-Import, habe jedoch letztendlich einige benutzerdefinierte SQL-Anweisungen für die Masseneinfügung verwendet. Aber ich hatte diese Antwort bis dahin noch nicht gesehen:
Post Insert und Delete für Bulk-Operationen optimieren?
benutzen
wp_defer_term_counting()
, um die Zählung von Begriffen zu aktivieren oder zu deaktivieren.Auch wenn Sie den Quellcode für das WordPress-Import-Plugin auschecken, sehen Sie diese Funktionen unmittelbar vor dem Massenimport:
und dann nach dem Bulk Insert:
Das könnte man also ausprobieren ;-)
Beiträge als Entwurf importieren statt veröffentlichen beschleunigt die Arbeit ebenfalls, da der langsame Prozess, für jeden einen eindeutigen Slug zu finden, übersprungen wird. Man könnte sie zB später in kleineren Schritten veröffentlichen, aber beachten Sie, dass diese Art der Vorgehensweise die importierten Beiträge irgendwie markieren müsste, damit wir später nicht nur irgendwelche Entwürfe veröffentlichen! Dies würde eine sorgfältige Planung und höchstwahrscheinlich eine benutzerdefinierte Codierung erfordern.
Wenn zB viele ähnliche Post-Titel (gleich
post_name
) importiert werden sollen, dannwp_unique_post_slug()
kann dies aufgrund der Iteration der Schleifenabfrage langsam werden, um einen verfügbaren Slug zu finden. Dies kann möglicherweise eine große Anzahl von Datenbankabfragen erzeugen.Seit WordPress 5.1 ist der
pre_wp_unique_post_slug
Filter verfügbar, um die Schleifeniteration für den Slug zu vermeiden. Siehe Kernticket # 21112 . Hier ist ein Beispiel:Wenn man es zB
$override_slug = _truncate_post_slug( $slug, 200 - ( strlen( $suffix ) + 1 ) ) . "-$suffix"
mit$suffix
as versucht$post_id
, dann würden wir feststellen, dass dies erwartungsgemäß$post_id
immer0
für neue Beiträge gilt. Es gibt jedoch verschiedene Möglichkeiten, eindeutige Zahlen in PHP zu generieren, wie zuniqid( '', true )
. Verwenden Sie diesen Filter jedoch mit Sorgfalt, um sicherzustellen, dass Sie eindeutige Schnecken haben. Wir könnten zB später eine Gruppenzählungsabfrage durchführenpost_name
, um sicherzugehen.Eine andere Möglichkeit wäre die Verwendung von WP-CLI , um eine Zeitüberschreitung zu vermeiden. Siehe z. B. meine Antwort für das Erstellen von 20.000 Posts oder Pages mit einer CSV-Datei?
Dann können wir unser benutzerdefiniertes PHP-Importskript
import.php
mit dem WP-CLI-Befehl ausführen :Vermeiden Sie auch den Import einer großen Anzahl hierarchischer Beitragstypen, da die aktuelle Benutzeroberfläche von wp-admin dies nicht gut handhabt. Siehe zB Benutzerdefinierter Beitragstyp - Liste der Beiträge - weißer Bildschirm des Todes
Hier ist der großartige Tipp von @otto:
Vor Bulk - Einsätze , deaktivieren Sie den
autocommit
Modus explizit:Führen Sie nach den Masseneinfügungen Folgendes aus:
Ich denke auch, dass es eine gute Idee wäre, etwas Haushalt zu führen wie:
Ich habe dies nicht auf MyISAM getestet, aber dies sollte auf InnoDB funktionieren .
Wie von @kovshenin erwähnt, würde dieser Tipp für MyISAM nicht funktionieren .
quelle
SET autocommit=0;
vor den Einsätzen, gefolgt von einemCOMMIT;
danach.$wpdb->query('SET autocommit = 0;');
vor den Einfügungen machen, aber können wir$wpdb->query('START TRANSACTION;');
in diesem Fall überspringen ? Ich werde das MySQL-Handbuch durchsehen, um mehr darüber zu erfahren ;-) Prost.wp_suspend_cache_addition( true )
sollten Sie KEINE Informationen in den Objektcache stellen. @Birgire erwähnte auch, dass sie dies nicht mit MyISAM getestet haben - stören Sie sich nicht, die Speicher-Engine unterstützt keine Transaktionen, so dass das Setzen von Autocommit oder das Starten einer Transaktion keine Auswirkung hat.Sie müssen den Beitrag einfügen, um Ihre ID zu erhalten, aber die
$wpdb->postmeta
Tabelle ist sehr einfach aufgebaut. Sie könnten wahrscheinlich eine einfacheINSERT INTO
Anweisung wie die folgende aus den MySQL-Dokumenten verwenden:INSERT INTO tbl_name (a,b,c) VALUES(1,2,3),(4,5,6),(7,8,9);
In deinem Fall...
Das wird nichts mit Kodierung, Serialisierung, Escape, Fehlerprüfung, Vervielfältigung oder anderem zu tun haben, aber ich würde erwarten, dass es schneller ist (obwohl ich es nicht versucht habe).
Ich würde dies auf einer Produktionsstätte nicht ohne gründliche Tests tun, und wenn ich es nur ein- oder zweimal tun müsste, würde ich die Kernfunktionen nutzen und ein langes Mittagessen einnehmen, während Dinge importieren.
quelle
->prepare()
Ihre SQL-Anweisungen behandeln. Was würde in Ihrem Szenario passieren, wenn die ID-Spalte in der CSV so etwas enthalten würde1, 'foo', 'bar'); DROP TABLE wp_users; --
? Wahrscheinlich etwas Schlimmes.Ich musste folgendes hinzufügen:
Beachten Sie, dass dabei
do_all_pings
Pingbacks, Enclosures, Trackbacks und andere Pings übersprungen werden (Link: https://developer.wordpress.org/reference/functions/do_all_pings/ ). Mein Verständnis beim Betrachten des Codes ist, dass ausstehende Pingbacks / Trackbacks / Enclosures weiterhin verarbeitet werden, nachdem Sie dieseremove_action
Zeile entfernt haben, aber ich bin nicht ganz sicher.Update: habe ich auch hinzugefügt
Darüber hinaus benutze ich:
quelle
Wichtiger Hinweis zu
'SET autocommit = 0;'
nach dem Einstellen
autocommit = 0
ob das Skript die Ausführung stoppt (aus irgendeinem Grund, wie z. B. einemexit
schwerwiegenden Fehler oder usw.), werden Ihre Änderungen NICHT IN DB GESPEICHERT!In diesem Fall
update_option
wird nicht in DB gespeichert!Der beste Rat ist also, sich als Vorsichtsmaßnahme
COMMIT
registrieren zushutdown
lassen (falls ein unerwartetes Beenden eintritt).quelle