Salut,
il me semblait que j'avais déjà posé la question (ah, retrouvé: https://www.jeuweb.org/showthread.php?tid=12249 mais c'était plus général en effet ). Sommairement, je fais les deux: je scratch tout pour reconstruire dans une DB de test, ce qui me permet de m'assurer que l'état de la BDD sera réalisable (je n'ai pas laissé d'erreur de syntaxe, de table en doublon, ou de foreign key dupliquées) puis je fais le diff avec ma BDD de jeu pour "merger" les deux structures (et les data associées).
Pour ma part, je versionne les fichiers SQL de définition des objets SQL (Dieu que je hais le versionning des scripts de "migration"... c'est tellement plus sain et pratique de se baser sur l'état de la BDD que sur les transitions pour y arriver : ) ). Donc, j'ai un script qui contient le CREATE TABLE de chaque table, un script avec le CREATE PROCEDURE de chaque procédure, etc.
J'ai également des scripts optionnels de migration de données (parce que là, ok, j'ai pas trouvé mieux: les données n'étant pas versionnées dans le projet, c'est compliqué de faire autrement; si je trouve un jour une solution, je vous dirai).
Au déploiement, je balance tout ça sur le serveur dans un dossier de release (hors du dossier web root [www] d'apache), puis je charge tous les fichiers SQL dans un DB de test (une DB vidée au préalable de tous ses objets). Cela me permet de savoir si les scripts de création des objets exécutables sont valides et donc, d'assurer que l'état de la BDD vers lequel je veux tendre est intègre.
Je mets alors le jeu en maintenance (en fait, je bascule le dossier web root d'apache [www] vers le dossier où j'ai mis les fichiers PHP de ma nouvelle version du jeu, et j'utilise la classe PHP "OvhPendingDeployConfig", qui est la configuration du jeu pendant les mises à jour; cette configuration est faite de sorte à renvoyer une page "503 Mise à jour du jeu en cours" pour toutes les pages nécessitant un accès à la BDD) puis je fais le diff entre ma BDD SQL de jeu et la BDD dans laquelle j'ai chargé les fichiers SQL déployés. J'en tire alors une liste de commandes SQL, que le script PHP de déploiement exécute. Chaque commande est loggée, et si elle plante, je le log aussi. Je recommence cette migration une dizaine de fois (en gros), car l'ordre des opérations de diff n'est pas parfait (ie: si j'ai 1 seul diff de structure de BDD autre qu'un drop de colonne, alors tous les diff "drop de colonne" ne sont pas exécutés dans cette itération, histoire de limiter les risques de perdre de data).
Si le script de migration parvient à aligner la structure des deux DB, alors le déploiement SQL est terminé, et le script de déploiement continue. Il copie la vraie config du jeu dans le dossier du jeu, et l'erreur 503 disparait pour permettre de jouer sur la nouvelle BDD.
Si jamais le script de migration n'arrive pas à exécuter tous les diff (il arrive à la 11e itération, alors que je l'ai limité à 10, et la BDD du jeu n'a toujours pas l'exacte même structure que la BDD de test), alors le jeu reste sur l'erreur 503, et j'ai l'information de ce qui chie. Charge à moi de mettre à jour les data si besoin, puis de dire au script de migration "ok, recommence 10 itérations". Ou de faire de l'opé manuelle si les choses chient vraiment. Nota que l'erreur 503 est indispensable si on veut assurer l'intégrité de sa BDD lors des déploiements...
Il me reste encore deux éléments à intégrer lè-dedans:
- Le script d'init des data, celui qui définit par exemple les informations des batiments pour ECLERD, les liens entre les recherches de VariiSpace, etc. Celui-là est actuellement un endpoint en CLI (aka comme un endpoint web [une page web] sauf qu'on ne peut l'appeler que depuis la CLI et pas depuis le web) qu'il faudrait donc que j'exécute après chaque itération du script de déploiement SQL. Ainsi, si j'ai retiré un ENUM d'un table par exemple alors que cette valeur d'ENUM est utilisée dans le jeu, l'itération de déploiement SQL va échouer ("data truncated for ENUM"), puis le script d'init de data se lancera, et après son exécution, cette valeur d'ENUM ne sera plus présente dans la DB du jeu, et l'itération de déploiement SQL suivante s'exécutera sans erreur.
- Les scripts de migration des data des joueurs, et là, je ne sais pas du tout comment je les intègrerai... exemple: j'ai une table des messages des joueurs avec les status "PUBLIC" (tout le monde peut lire le message), "PRIVE" (seuls les membres de l'alliance du joueur peuvent le lire) et "CONFIDENTIEL" (seul le joueur qui l'a écrit peut le lire). Cette table est remplie avec des data issues des joueurs (leurs messages). Je veux supprimer le statut "CONFIDENTIEL", qui ne sert à rien, mais que certains ont utilisé. Alors le script de déploiement SQL va bloquer sur "data truncated for column ENUM"... Actuellement, je n'ai pas d'autre solution que de faire l'UPDATE des data du jeu à la main (ou de préparer ces UPDATE dans des scripts dédiés aux data du jeu). Ca ne me semble pas solvable autrement au fond, puisque les data ne font pas partie du code versionné du jeu, donc, il sera toujours compliqué de gérer leur migration.
il me semblait que j'avais déjà posé la question (ah, retrouvé: https://www.jeuweb.org/showthread.php?tid=12249 mais c'était plus général en effet ). Sommairement, je fais les deux: je scratch tout pour reconstruire dans une DB de test, ce qui me permet de m'assurer que l'état de la BDD sera réalisable (je n'ai pas laissé d'erreur de syntaxe, de table en doublon, ou de foreign key dupliquées) puis je fais le diff avec ma BDD de jeu pour "merger" les deux structures (et les data associées).
Pour ma part, je versionne les fichiers SQL de définition des objets SQL (Dieu que je hais le versionning des scripts de "migration"... c'est tellement plus sain et pratique de se baser sur l'état de la BDD que sur les transitions pour y arriver : ) ). Donc, j'ai un script qui contient le CREATE TABLE de chaque table, un script avec le CREATE PROCEDURE de chaque procédure, etc.
J'ai également des scripts optionnels de migration de données (parce que là, ok, j'ai pas trouvé mieux: les données n'étant pas versionnées dans le projet, c'est compliqué de faire autrement; si je trouve un jour une solution, je vous dirai).
Au déploiement, je balance tout ça sur le serveur dans un dossier de release (hors du dossier web root [www] d'apache), puis je charge tous les fichiers SQL dans un DB de test (une DB vidée au préalable de tous ses objets). Cela me permet de savoir si les scripts de création des objets exécutables sont valides et donc, d'assurer que l'état de la BDD vers lequel je veux tendre est intègre.
Je mets alors le jeu en maintenance (en fait, je bascule le dossier web root d'apache [www] vers le dossier où j'ai mis les fichiers PHP de ma nouvelle version du jeu, et j'utilise la classe PHP "OvhPendingDeployConfig", qui est la configuration du jeu pendant les mises à jour; cette configuration est faite de sorte à renvoyer une page "503 Mise à jour du jeu en cours" pour toutes les pages nécessitant un accès à la BDD) puis je fais le diff entre ma BDD SQL de jeu et la BDD dans laquelle j'ai chargé les fichiers SQL déployés. J'en tire alors une liste de commandes SQL, que le script PHP de déploiement exécute. Chaque commande est loggée, et si elle plante, je le log aussi. Je recommence cette migration une dizaine de fois (en gros), car l'ordre des opérations de diff n'est pas parfait (ie: si j'ai 1 seul diff de structure de BDD autre qu'un drop de colonne, alors tous les diff "drop de colonne" ne sont pas exécutés dans cette itération, histoire de limiter les risques de perdre de data).
Si le script de migration parvient à aligner la structure des deux DB, alors le déploiement SQL est terminé, et le script de déploiement continue. Il copie la vraie config du jeu dans le dossier du jeu, et l'erreur 503 disparait pour permettre de jouer sur la nouvelle BDD.
Si jamais le script de migration n'arrive pas à exécuter tous les diff (il arrive à la 11e itération, alors que je l'ai limité à 10, et la BDD du jeu n'a toujours pas l'exacte même structure que la BDD de test), alors le jeu reste sur l'erreur 503, et j'ai l'information de ce qui chie. Charge à moi de mettre à jour les data si besoin, puis de dire au script de migration "ok, recommence 10 itérations". Ou de faire de l'opé manuelle si les choses chient vraiment. Nota que l'erreur 503 est indispensable si on veut assurer l'intégrité de sa BDD lors des déploiements...
Il me reste encore deux éléments à intégrer lè-dedans:
- Le script d'init des data, celui qui définit par exemple les informations des batiments pour ECLERD, les liens entre les recherches de VariiSpace, etc. Celui-là est actuellement un endpoint en CLI (aka comme un endpoint web [une page web] sauf qu'on ne peut l'appeler que depuis la CLI et pas depuis le web) qu'il faudrait donc que j'exécute après chaque itération du script de déploiement SQL. Ainsi, si j'ai retiré un ENUM d'un table par exemple alors que cette valeur d'ENUM est utilisée dans le jeu, l'itération de déploiement SQL va échouer ("data truncated for ENUM"), puis le script d'init de data se lancera, et après son exécution, cette valeur d'ENUM ne sera plus présente dans la DB du jeu, et l'itération de déploiement SQL suivante s'exécutera sans erreur.
- Les scripts de migration des data des joueurs, et là, je ne sais pas du tout comment je les intègrerai... exemple: j'ai une table des messages des joueurs avec les status "PUBLIC" (tout le monde peut lire le message), "PRIVE" (seuls les membres de l'alliance du joueur peuvent le lire) et "CONFIDENTIEL" (seul le joueur qui l'a écrit peut le lire). Cette table est remplie avec des data issues des joueurs (leurs messages). Je veux supprimer le statut "CONFIDENTIEL", qui ne sert à rien, mais que certains ont utilisé. Alors le script de déploiement SQL va bloquer sur "data truncated for column ENUM"... Actuellement, je n'ai pas d'autre solution que de faire l'UPDATE des data du jeu à la main (ou de préparer ces UPDATE dans des scripts dédiés aux data du jeu). Ca ne me semble pas solvable autrement au fond, puisque les data ne font pas partie du code versionné du jeu, donc, il sera toujours compliqué de gérer leur migration.