Accueil / Blog / N8N 2.0 Python Migration

N8N 2.0 : Migrer les Python Code Nodes - Guide Complet

Après la mise à jour vers N8N 2.0, vos Python Code Nodes échouent avec l'erreur "items is not defined" ? Ce guide vous montre comment migrer rapidement vos workflows.

TL;DR

Après la mise à jour vers N8N 2.0, vos Python Code Nodes utilisant items ou _input.all() échouent avec l'erreur "items is not defined".

La solution : remplacez items par _items (mode "Run Once for All Items") ou par _item (mode "Run Once for Each Item").

# ❌ Ancien code (N8N 1.x) - NE FONCTIONNE PLUS
for item in items:
    process(item)

# ✅ Nouveau code (N8N 2.0)
for item in _items:
    process(item)

Le Problème : Erreur "items not defined"

Symptômes

Après avoir mis à jour N8N vers la version 2.0, vos workflows Python qui fonctionnaient parfaitement commencent à échouer. Le message d'erreur typique :

NameError: name 'items' is not defined
Capture d'écran de l'erreur items is not defined dans N8N 2.0
L'erreur "items is not defined" après mise à jour vers N8N 2.0

Ou encore :

AttributeError: '_input' object has no attribute 'all'

Code qui ne fonctionne plus

# Ces syntaxes NE FONCTIONNENT PLUS en N8N 2.0

# Syntaxe 1 : items direct
for i, item in enumerate(items):
    data = item['json']
    # traitement...

# Syntaxe 2 : _input.all()
items = _input.all()
for item in items:
    data = item['json']

# Syntaxe 3 : _("NodeName").all()
previous_data = _("Extract from CSV").all()
Ancien code Python N8N utilisant la variable items
Exemple de code Python utilisant l'ancienne syntaxe avec "items"

Pourquoi Ce Changement : Native Python Runner

L'évolution de N8N 2.0

N8N 2.0 introduit un changement architectural majeur : le Native Python Runner remplace Pyodide.

Aspect Pyodide (N8N 1.x) Native Python Runner (N8N 2.0)
Exécution Python dans le navigateur via WebAssembly Python natif côté serveur
Performance Limitée Significativement améliorée
Bibliothèques Restreintes Toutes les bibliothèques Python
Syntaxe helpers _input, _() disponibles Limitée à _items / _item

Ce qui change concrètement

Le Native Python Runner offre de meilleures performances mais supprime la plupart des helpers JavaScript-like. Seules deux variables restent disponibles :

Note importante : Le message d'aide de N8N 2.0 confirme :
"The native Python option does not support _ syntax and helpers, except for _items in all-items mode and _item in per-item mode."
Code Python corrigé avec le message d'aide N8N 2.0
Le code corrigé avec _items et le message d'aide de N8N 2.0

La Solution en 3 Étapes

Étape 1 : Identifier le mode d'exécution

Ouvrez votre Code node et vérifiez le paramètre "Mode" :

Sélecteur de mode dans N8N Code Node - Run Once for All Items ou Run Once for Each Item
Le sélecteur de mode dans les paramètres du Code Node N8N
Mode dans N8N Variable à utiliser
Run Once for All Items _items
Run Once for Each Item _item

Étape 2 : Modifier le code

Mode "Run Once for All Items" (le plus courant)

# ✅ Code corrigé pour N8N 2.0
results = []

for i, item in enumerate(_items):
    try:
        raw = item['json']

        # Votre logique de traitement
        processed = {
            'field1': raw.get('column1', ''),
            'field2': raw.get('column2', '')
        }

        results.append({'json': processed})

    except Exception as e:
        print(f'Error row {i+1}: {e}')
        continue

return results

Mode "Run Once for Each Item"

# ✅ Code pour traiter un seul item
raw = _item['json']

processed = {
    'field1': raw.get('column1', ''),
    'field2': raw.get('column2', '')
}

return {'json': processed}

Étape 3 : Tester l'exécution

  1. Cliquez sur "Execute Workflow" ou utilisez le raccourci
  2. Vérifiez que le statut passe en vert "Succeeded"
  3. Inspectez les données de sortie du node
Exécution réussie du workflow N8N après correction du code Python
Exécution réussie : le workflow fonctionne après la migration vers _items

Tableau Comparatif : Avant / Après

Ancien Code (N8N 1.x) Nouveau Code (N8N 2.0)
items _items
items[0] _items[0]
len(items) len(_items)
for item in items: for item in _items:
_input.all() ❌ Non supporté, utiliser _items
_input.item _item
_("NodeName").all() ❌ Non supporté
$json _item['json'] (mode Each)

Exemple complet de migration

Avant (N8N 1.x)

# Import de données CSV avec transformation
results = []
items = _input.all()

for i, item in enumerate(items):
    raw = item.json.to_py()  # Conversion Pyodide

    name = str(raw.get('nom', '')).strip()
    if not name:
        continue

    results.append({
        'json': {
            'nom': name,
            'type': raw.get('type', 'Principal'),
            'statut': 'Actif'
        }
    })

return results

Après (N8N 2.0)

# Import de données CSV avec transformation
results = []

for i, item in enumerate(_items):  # Changement ici
    raw = item['json']  # Plus besoin de to_py()

    name = str(raw.get('nom', '')).strip()
    if not name:
        continue

    results.append({
        'json': {
            'nom': name,
            'type': raw.get('type', 'Principal'),
            'statut': 'Actif'
        }
    })

return results

Différences : Mode "All Items" vs "Each Item"

Quand utiliser quel mode ?

Cas d'usage Mode recommandé Raison
Transformation batch (CSV, Excel) Run Once for All Items Traiter tous les items en une fois
Opération sur un seul item Run Once for Each Item Plus simple, pas de boucle
Agrégations (somme, moyenne) Run Once for All Items Besoin d'accès à toutes les données
Filtrage conditionnel Run Once for Each Item Décision item par item

Exemple : Mode "Run Once for Each Item"

# Mode: Run Once for Each Item
# _item contient l'item courant

data = _item['json']

# Transformation simple
result = {
    'name': data.get('name', '').upper(),
    'processed': True,
    'timestamp': str(_now)  # _now fonctionne encore
}

return {'json': result}

Troubleshooting

Erreur : "name 'items' is not defined"

Cause : Vous utilisez la variable items qui n'existe plus en N8N 2.0.

Solution : Remplacez for item in items: par for item in _items:

Erreur : "'_input' object has no attribute 'all'"

Cause : La syntaxe _input.all() n'est plus supportée dans le Native Python Runner.

Solution : Supprimez la ligne items = _input.all() et utilisez directement _items

Erreur : "name '_' is not defined"

Cause : La fonction _("NodeName") pour accéder aux données d'un node spécifique n'existe plus.

Solution : Restructurez votre workflow pour que les données arrivent directement via la connexion, puis utilisez _items.

Erreur : "to_py() not available"

Cause : En N8N 1.x avec Pyodide, il fallait convertir les objets JavaScript avec .to_py(). Ce n'est plus nécessaire.

Solution : Utilisez raw = item['json'] au lieu de item.json.to_py()

Le workflow fonctionne en mode manuel mais pas en production

Vérification : Assurez-vous que le mode d'exécution est cohérent :

  • Mode manuel = généralement "Run Once for All Items"
  • Vérifiez que votre code utilise bien _items et non _item

FAQ

Dois-je migrer tous mes workflows Python vers N8N 2.0 ?

Oui, si vous mettez à jour vers N8N 2.0, tous les Python Code Nodes utilisant items, _input.all(), ou _("NodeName").all() devront être modifiés. Les JavaScript Code Nodes ne sont pas affectés par ce changement.

Puis-je continuer à utiliser Pyodide ?

Non, à partir de N8N 2.0, le Native Python Runner est le seul moteur Python disponible. Pyodide a été complètement remplacé.

Les bibliothèques Python sont-elles toujours disponibles ?

Oui, et même plus qu'avant ! Le Native Python Runner permet d'utiliser toutes les bibliothèques Python installées sur le serveur, sans les limitations de Pyodide.

Comment installer des bibliothèques Python supplémentaires ?

Installez-les directement sur le serveur N8N ou dans le conteneur Docker :

# Si N8N en Docker
docker exec -it n8n pip install pandas numpy

# Si N8N local
pip install pandas numpy
La variable _now fonctionne-t-elle encore ?

Oui, _now reste disponible et retourne le timestamp actuel.

Existe-t-il un outil de migration automatique ?

Non, la migration doit être faite manuellement. Cependant, le changement est simple : remplacez items par _items dans la majorité des cas.


Checklist de Migration


Ressources


Conclusion

La migration vers N8N 2.0 Native Python Runner est relativement simple : remplacez items par _items et supprimez les syntaxes obsolètes comme _input.all(). Le gain en performance et en compatibilité avec les bibliothèques Python compense largement ce petit effort de migration.

Points clés à retenir :

  1. items_items (mode All Items)
  2. _input.item_item (mode Each Item)
  3. Plus besoin de .to_py() pour convertir les données
  4. La plupart des autres helpers _ ne sont plus disponibles

Besoin d'aide avec vos workflows N8N ?

Je peux vous accompagner dans la migration de vos automatisations vers N8N 2.0 ou optimiser vos workflows existants.

Discutons de votre projet