J'ai un fichier csv que je veux insérer qui se compose de ~ 1 500 lignes et 97 colonnes. Cela prend environ 2-3 heures pour faire une importation complète et j'aimerais améliorer cela s'il y a un moyen. Actuellement, pour chaque ligne, je fais un $ post_id = wp_insert_post puis un add_post_meta pour les 97 colonnes associées à chaque ligne. C'est assez inefficace ...
Existe-t-il une meilleure façon de procéder à ce sujet de manière à ce que a puisse obtenir un post_id pour conserver la relation entre post et ses valeurs post_meta?
En ce moment, j'essaie cela sur ma machine locale avec Wamp, mais je vais l'exécuter sur un VPS
wp-insert-post
Corey Rowell
la source
la source
Réponses:
J'ai eu des problèmes similaires il y a quelque temps avec une importation CSV personnalisée, mais j'ai fini par utiliser du SQL personnalisé pour l'insertion en bloc. Mais je n'avais pas encore vu cette réponse:
Optimiser la post-insertion et la suppression pour les opérations en masse?
à utiliser
wp_defer_term_counting()
pour activer ou désactiver le comptage des termes.De plus, si vous vérifiez la source du plugin d'import WordPress, vous verrez ces fonctions juste avant l'importation en masse:
puis après l'insertion en vrac:
Donc ça pourrait être quelque chose à essayer ;-)
L'importation de messages en tant que brouillon au lieu de les publier accélérera également les choses, car le lent processus de recherche d'un slug unique pour chacun est ignoré. On pourrait par exemple les publier plus tard en étapes plus petites, mais notez que ce type d'approche devrait marquer les articles importés d'une manière ou d'une autre, donc nous ne publions pas plus tard des brouillons! Cela nécessiterait une planification minutieuse et très probablement un codage personnalisé.
S'il y a par exemple beaucoup de titres de poste similaires (identiques
post_name
) à importer, alorswp_unique_post_slug()
peut devenir lent, en raison de l'itération de la requête de boucle pour trouver un slug disponible. Cela peut éventuellement générer un grand nombre de requêtes db.Depuis WordPress 5.1, le
pre_wp_unique_post_slug
filtre est disponible pour éviter l'itération de boucle pour le slug. Voir ticket principal # 21112 . Voici un exemple:Si l'on essaie par exemple
$override_slug = _truncate_post_slug( $slug, 200 - ( strlen( $suffix ) + 1 ) ) . "-$suffix"
avec$suffix
as$post_id
, alors nous noterons que$post_id
c'est toujours0
pour les nouveaux messages, comme prévu. Il existe différentes manières de générer des nombres uniques en PHP, commeuniqid( '', true )
. Mais utilisez ce filtre avec soin pour vous assurer d'avoir des limaces uniques. Nous pourrions par exemple exécuter une requête de comptage de groupe par la suitepost_name
pour être sûr.Une autre option serait d'utiliser WP-CLI pour éviter le dépassement de délai. Voir par exemple ma réponse postée pour création de 20 000 messages ou pages à l'aide d'un fichier .csv?
Ensuite, nous pouvons exécuter notre script d'importation PHP personnalisé
import.php
avec la commande WP-CLI:Évitez également d'importer un grand nombre de types de publication hiérarchiques, car l'interface utilisateur wp-admin actuelle ne le gère pas bien. Voir par exemple le type de message personnalisé - liste des messages - écran blanc de la mort
Voici le bon conseil de @otto:
Avant les insertions en masse , désactivez le
autocommit
mode explicitement:Après les insertions en masse, exécutez:
Je pense aussi que ce serait une bonne idée de faire un peu de ménage comme:
Je n'ai pas testé cela sur MyISAM mais cela devrait fonctionner sur InnoDB .
Comme mentionné par @kovshenin, cette astuce ne fonctionnerait pas pour MyISAM .
la source
SET autocommit=0;
avant les encarts, suivi d'unCOMMIT;
après.$wpdb->query('SET autocommit = 0;');
avant les insertions, mais pouvons-nous sauter$wpdb->query('START TRANSACTION;');
dans ce cas? Je vais consulter le manuel MySQL pour en savoir plus à ce sujet ;-) cheers.wp_suspend_cache_addition( true )
devrait aider à NE PAS mettre de trucs dans le cache d'objets. @Birgire a également mentionné qu'ils n'avaient pas testé cela avec MyISAM - ne vous embêtez pas, le moteur de stockage ne prend pas en charge les transactions, donc la configuration de l'autocommit ou le démarrage d'une transaction n'aura aucun effet.Vous devrez insérer le message pour obtenir votre ID, mais le
$wpdb->postmeta
tableau est très simple dans sa structure. Vous pourriez probablement utiliser uneINSERT INTO
déclaration simple , comme celle-ci dans les documents MySQL:INSERT INTO tbl_name (a,b,c) VALUES(1,2,3),(4,5,6),(7,8,9);
Dans ton cas...
Cela ne traitera pas de l'encodage, de la sérialisation, de l'échappement, de la vérification des erreurs, des duplications ou de quoi que ce soit d'autre, mais je m'attendrais à ce que ce soit plus rapide (même si je n'ai pas essayé).
Je ne ferais pas cela sur un site de production sans des tests approfondis, et si je n'avais qu'à le faire une ou deux fois, j'utiliserais les fonctions de base et prendrais un long déjeuner pendant que les choses importent.
la source
->prepare()
vos instructions SQL. Dans votre scénario, que se passerait-il si la colonne ID dans le CSV contenait quelque chose comme1, 'foo', 'bar'); DROP TABLE wp_users; --
? Quelque chose de mal probablement.J'ai dû ajouter ceci:
Gardez à l'esprit que cela sautera
do_all_pings
, qui traitera les pingbacks, les pièces jointes, les trackbacks et autres pings (lien: https://developer.wordpress.org/reference/functions/do_all_pings/ ). Ma compréhension de la lecture du code est que les pingbacks / trackbacks / enceintes en attente seront toujours traités après avoir supprimé cetteremove_action
ligne, mais je ne suis pas complètement sûr.Mise à jour: j'ai également ajouté
Au-delà, j'utilise:
la source
Remarque importante sur
'SET autocommit = 0;'
après avoir défini
autocommit = 0
si le script arrête l'exécution (pour une raison quelconque, commeexit
une erreur fatale ou etc ...), alors vos modifications NE SERONT PAS ENREGISTRÉES DANS DB!Dans ce cas
update_option
, ne sera pas enregistré dans DB!Ainsi, le meilleur conseil est de vous être
COMMIT
enregistré enshutdown
fonction en tant que précatuion (en cas de sortie inattendue).la source