Est-il possible qu’une table MySQL envoie un événement déclencheur lorsqu’une nouvelle ligne est ajoutée qui peut être détectée par un script python afin qu’une action puisse être effectuée par le script python?

Certaines personnes essaient d’écrire un déclencheur MySQL qui publie une sorte de notification pour que le script Python le remarque. Mais ce serait une solution incomplète.

Un déclencheur INSERT s’exécute lorsque l’INSERT se produit, pas lorsque la transaction contenant l’INSERT est validée. Cela signifie que toute notification publiée par le déclencheur peut être prématurée. La transaction peut être annulée soit par le choix de l’application appelante, soit par une erreur provoquée par une instruction SQL ultérieure. Si le script Python a été informé d’une nouvelle ligne, mais que la ligne n’est pas là, cela va créer de la confusion.

Une meilleure solution consiste à ce que l’application qui exécute l’INSERT termine sa transaction, et seulement après que la transaction se soit correctement validée, puis affichez un avis que le script Python peut recevoir.

Une bonne méthode consiste à utiliser une file d’attente de messages pour notifier le script Python, tel que RabbitMQ, pour implémenter un modèle de publication / abonnement.

Apparemment, une façon de le faire est d’avoir un thread actif sur votre consommateur qui utilise les appels de blocage à la fonction GET_LOCK () de MySQL comme un mutex (primitive d’exclusion mutuelle).

Ceci est, apparemment, décrit ici: Quelle est la meilleure façon d’implémenter une table de file d’attente de messagerie dans mysql

… Ce type particulier de verrou semble être consultatif et l’API inclut un paramètre de délai d’expiration. Un exemple d’utilisation, de Python, apparaît ici: https://gist.github.com/shevron/…

Je suppose que le protocole serait que votre producteur maintienne le verrou, pousse le travail dans la file d’attente (INSÉRER dans la table appropriée), puis relâche brièvement le verrou pour déclencher le ou les consommateurs qui attendent sur le verrou.

Je penserais que le consommateur garderait trace de l’ID (ligne) le plus élevé qui a été traité et, à chaque activation (déverrouillage), interrogerait l’ensemble WHERE id>: last_processed_id: … puis mettrait à jour la dernière valeur d’ID traitée. Ensuite, il libérerait le verrou et reviendrait au blocage GET_LOCK ().

Il pourrait y avoir quelques astuces pour obtenir la gestion des transactions autour de ce correct … pour garantir qu’aucune transaction n’est jamais perdue tout en minimisant le temps que la file d’attente est bloquée par le consommateur. Je suppose que vous utiliseriez une file d’attente de messages réelle, même juste une LISTE Redis, pour la file d’attente de travail réelle … et ce consommateur relayerait simplement les ID de LIGNE de la table MySQL dans la file d’attente de travail réelle.

Vous pouvez avoir les ROWID «last_processed» insérés dans une autre table avec un identifiant (IP de travail: ID de processus) de sorte que le système de mise en file d’attente global puisse récupérer de l’échec de tout nœud ou processus de travail. Dans ce modèle, la gestion des choses hors de la file d’attente se fait dans une sorte de validation en deux phases… et les lignes de travail ne sont marquées comme terminées (ou supprimées de cette table de file d’attente de travail) que lorsque le travail est terminé. Les détails sur la façon dont vous détectez le travail perdu, combien de temps vous donnez et comment vous tuez les processus bloqués / bloqués, etc. sont, bien sûr, des questions qui dépendraient profondément de votre application et de votre infrastructure.