Comment identifies-tu tes tuples ?
Version imprimable
Comment identifies-tu tes tuples ?
Je pensais parcourir tout les champs d'une base et les comparait avec l'autre base
En ce cas, tu ne détecteras pas les mises à jour qui ont été effectuées sur les tuples.
that's it's a problem...
Je veux dire : si tu n'identifies pas la clef primaire et que tu compares le tuple entier, jamais tu ne repèreras les modifications. Tout tuple ayant été modifié sera repéré comme nouvel enregistrement...
Si, en revanche, tu peux identifier la clef primaire (c'est ce que j'ai fait dans le script dont je t'ai parlé, par exemple), alors tu compareras les tuples en utilisant cet identifiant et ce sera du gâteau.
bah si les tuples ont une clé primaire identique dans les deux bases, sauf si c'est un tuple qui a été ajouté...Citation:
Envoyé par Kirkis
il faut que je synchronise la structure et les données je m'en sors pas là...
est-ce que le début est bon ?
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 <?php //compare les deux bases et renvoye une chaine contenant le dump de la base synchronisée function synchronisation($base,$base_compare){ $liste_tables_base = mysql_list_tables($base); $liste_tables_base_compare = mysql_list_tables($base_compare); //traitement des tables if(mysql_num_rows($liste_tables_base) != mysql_num_rows($liste_tables_base_compare)){ //si il n'y a pas le meme nombre de tables dans les deux bases je parcours la liste des tables et fait les mises a jour dans $base en n'oubliant pas de vérifier les champs } else{ //si il y en a le meme nombre je parcours les listes et vérifie que ce sont les memes for($i=0;$i<mysql_num_rows($liste_tables_base);$i++){ for($j=0;$j<mysql_num_rows($liste_tables_base_compare);$j++){ if(mysql_tablename($liste_tables_base, $i) == mysql_tablename($liste_tables_base_compare , $j)){ //si ce sont les memes je vérifie le nombre de colonne de chaque table //si c'est le meme nombre je vérifie que ce sont les memes //si c'est pas le meem nombre je parcours les deux listes et fait les mises à jour dans $base } else{ //si c'est pas les memes je fais les mises à jour dans $base } } } } } ?>
Comment puis je récupérer le nombre de champs d'une table ainsi que leur noms sachant que je connais le nom de la table ?
Code:
1
2
3
4
5
6
7
8
9
10 $result = mysql_query("SHOW COLUMNS FROM tatable"); //récupération du nom des champs while($row = mysql_fetch_array($result)) { $champ[] = $row['Field']; } //récupération nombre count($champ);
merci....
j'avance petit a petit mais j'avance...
Un petit apercu, hésitez pas à la compléter ou donner votre avis
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53 <?php //compare les deux bases et renvoye une chaine contenant le dump de la base synchronisée function synchronisation($base,$base_compare){ $liste_tables_base = mysql_list_tables($base); $liste_tables_base_compare = mysql_list_tables($base_compare); //traitement des structure de tables if(mysql_num_rows($liste_tables_base) != mysql_num_rows($liste_tables_base_compare)){ //TODO si il n'y a pas le meme nombre de tables dans les deux bases je parcours la liste des tables et fait les mises a jour dans $base en n'oubliant pas de vérifier les champs } else{ //si il y en a le meme nombre je parcours les listes et vérifie que ce sont les memes noms de tables for($i=0;$i<mysql_num_rows($liste_tables_base);$i++){ for($j=0;$j<mysql_num_rows($liste_tables_base_compare);$j++){ if(mysql_tablename($liste_tables_base, $i) == mysql_tablename($liste_tables_base_compare , $j)){ //si ce sont les memes je vérifie le nombre de champs de chaque table //récupération du nom des champs $result_base = mysql_query('SHOW COLUMNS FROM '.mysql_tablename($liste_tables_base, $i) while($row = mysql_fetch_array($result_base)) { $champ_base[] = $row['Field']; } $result_base_compare = mysql_query('SHOW COLUMNS FROM '.mysql_tablename($liste_tables_base_compare, $j) while($row = mysql_fetch_array($result_base_compare)) { $champ_base_compare[] = $row['Field']; } if(count($champ_base) == count($champ_base_compare)){ //si c'est le meme nombre je vérifie que ce sont les memes champs for($k=0;$k<count($champ_base);$k++){ for($l=0;$l<count($champ_base_compare);$l++){ if($champ[$k] != $champ[$l]){ //TODO les noms des champs sont différents donc je mets à jour $base } } } } else{ //TODO si c'est pas le meem nombre de champs je parcours les deux listes et fait les mises à jour dans $base } } else{ //TODO si c'est pas les memes noms de tables je fais les mises à jour dans $base } } } } //traitement des données des tables } ?>
allez c'est lundi, on s'y remet de bonne heure et de bonne humeur :)
Salut
Tu sais, il y a moyen de déterminer quels champs sont clef primaire d'une table, si tant est qu'il y ait une clef primaire. Dans le script dont je t'ai parlé plus haut, je me suis creusé la tête à déterminer quelle est la clef primaire même lorsqu'elle n'est pas définie.
Sans cette clef, je t'assure que tu vas rapidement avoir des incohérences.
J'ai deeja répondu a ta qustion, j'ai une clef primaire a chaque table ;)
pour l'instant je me bats avec la synchronisation de la structure...
Je voudrais vérifier que l'élément de la premiere liste est dans la deuxieme, si non je l'ajoute a la base si oui je passe au second élément de la premiere liste.
avec ce que j'ai fait j'ai un probleme je parcour toutes ma deuxieme liste avaant d'incrementer la premier donc evidemment a un moment je rentre dans le if et souleve une erreur car j'essaye d'ajouter une table qui existe déjà.
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14 for($i=0;$i<mysql_num_rows($liste_tables_base_compare);$i++){ for($j=0;$j<mysql_num_rows($liste_tables_base);$j++){ echo '<br> Table de base_compare : '.mysql_tablename($liste_tables_base_compare, $i); echo '<br> Table de base : '.mysql_tablename($liste_tables_base , $j); if(mysql_tablename($liste_tables_base_compare, $i) != mysql_tablename($liste_tables_base , $j)){ echo '<br>differentes<br>'; $create= mysql_query("SHOW CREATE TABLE ".mysql_tablename($liste_tables_base_compare, $i)) or die('ERREUR : '.mysql_error()); $tableau = mysql_fetch_array($create); $tableau[1] .= ";"; mysql_selectdb($base);//selectionne la base mysql_query($tableau[1]) or die('ERREUR 2 : '.mysql_error()); } } }
Probleme résolu
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 liste_tables_base = mysql_list_tables($base); $liste_tables_base_compare = mysql_list_tables($base_compare); //traitement des structure de tables if(mysql_num_rows($liste_tables_base) != mysql_num_rows($liste_tables_base_compare)){ //si il n'y a pas le meme nombre de tables dans les deux bases je parcours la liste des tables et fait les mises a jour dans $base for($i=0;$i<mysql_num_rows($liste_tables_base_compare);$i++){ $egale = false; for($j=0;$j<mysql_num_rows($liste_tables_base);$j++){ if(mysql_tablename($liste_tables_base_compare, $i) == mysql_tablename($liste_tables_base , $j)){ $egale = true; break; } } if($egale == false){ mysql_selectdb($base_compare);//selectionne la base $create= mysql_query("SHOW CREATE TABLE ".mysql_tablename($liste_tables_base_compare, $i)) or die('<br>ERREUR : '.mysql_error()); $tableau = mysql_fetch_array($create); $tableau[1] .= ";"; mysql_selectdb($base);//selectionne la base mysql_query($tableau[1]) or die('<br>ERREUR 2 : '.mysql_error()); } }
Ah tiens, je t'avais mal compris ici :
J'avais compris "au cas où" et non "puisque"... Je suis parfois très borné :/Citation:
Envoyé par schlough
Si je puis me permettre un conseil : appelle mysql_num_rows() avant chaque boucles et enregistre chaque valeur dans une variable, car tu demandes actuellement à PHP de retrouver chaque valeur à chaque fois. Ce n'est pas très coûteux en temps d'exécution mais bon...
J'imagine qu'il ne te reste plus qu'à parcourir les tuples de chaque base et, à chacun d'eux, de comparer son existence dans l'une et l'autre table en utilisant la clef.
Bonne chance pour déterminer si un tuple a été mis à jour et nécessite une modification...
Voila j'ai un peu optimisé la fonction synchronisation.php faut que je la continue maintenant
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41 <?php //compare les deux bases et renvoye une chaine contenant le dump de la base synchronisée //on choisit si on veut synchronisé la structure et si on veut synchroniser les données function synchronisation($base,$base_compare, $donnees = false,$structure = false){ $liste_tables_base = mysql_list_tables($base); $liste_tables_base_compare = mysql_list_tables($base_compare); if($structure == true){ //traitement des structure de tables //je prends l'élément de la premiere base et je regarde si il est dans la deuxième for($i=0;$i<mysql_num_rows($liste_tables_base);$i++){ $egale = false; for($j=0;$j<mysql_num_rows($liste_tables_base_compare);$j++){ if(mysql_tablename($liste_tables_base, $i) == mysql_tablename($liste_tables_base_compare, $j)){ $egale = true; break; } } if($egale == false){ //la table n'existe pas dans les deux bases, je la crée donc dans $base_compare mysql_selectdb($base);//selectionne la base $create= mysql_query("SHOW CREATE TABLE ".mysql_tablename($liste_tables_base, $i)) or die('<br>ERREUR : '.mysql_error()); $tableau = mysql_fetch_array($create); $tableau[1] .= ";"; mysql_selectdb($base_compare);//selectionne la base mysql_query($tableau[1]) or die('<br>ERREUR 2 : '.mysql_error()); } else{ //la table existe dans les deux bases, je vérifie si elle a la meme structure } } } if($structure == true){ //traitement des données de tables } } ?>
Pour l'instant je suis toujours dans les structures, il faut que quand une table existe dans les deux bases je vérifie si elle a la meme structure, je pense voir bien optimisé la non, qu'en penses tu ?Citation:
Envoyé par Kirkis
Je veux faire un truc qui tourne nickel sur les structures et apres je m'attaquerais aux données, mais je veux vraiment faire quelque chose de bien fait et réutilisable facilement.
Perso, j'aurais plutôt adopté un truc genre :
[/list:u:139dc044fd][*]parcours des tables de la BDD2
- parcours des tables de la BDD1
[list:139dc044fd]- recherche du nom de la table dans la BDD2
[list:139dc044fd]- si inexistant : créer puis insérer les données
- si existant : comparer la structure puis les tuples dans les 2 BDD
[/list:u:139dc044fd]
- comparer les tuples de la table dans les 2 BDD (les structures de tables sont déjà synchronisées)
En effet je n'ai pas adopté ce système et je vais expliquer pourquoi :Citation:
Envoyé par Kirkis
- - on choisit si on synchronise la structure ou non, cela n'est pas obligatoire
- si bdd1 est la locale, si les champs sont différents sur une table c'est toujours bdd2 qui aura raison
Avec ma proposition, tu n'es pas obligé de comparer la structure. Tu peux mettre cette comparaison dans une conditionnelle (qui dépend du choix utilisateur).
Si BDD1 a toujours raison, alors il te suffit de le prendre en compte dans la comparaison de structure (si elle a lieu).
Rien ne t'empêche d'adopter ce que je t'ai proposé ^_^
en fait je vais garder ma solution meme si la tienne est bonne...
je compare bdd1 et bdd2 j'ajoute les modifications dans bdd2, je fais un dump de bdd2, je drop bdd1 et je recrée bdd1 avec le dump de bdd2
Là pour le coup, ce n'est pas super optimisé :/
Mais bon, c'est efficace et pas prise de tête ^^
Bien pour ca que je l'ai mis en place :pCitation:
Envoyé par Kirkis
Ca commence a prendre forme
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82 <?php //compare les deux bases et renvoye une chaine contenant le dump de la base synchronisée //on choisit si on veut synchronisé la structure et si on veut synchroniser les données function synchronisation($base,$base_compare, $donnees = false,$structure = false){ $dump = null; if($structure == true){ //traitement des structure de tables $liste_tables_base = mysql_list_tables($base); $liste_tables_base_compare = mysql_list_tables($base_compare); //je prends l'élément de la premiere base et je regarde si il est dans la deuxième for($i=0;$i<mysql_num_rows($liste_tables_base);$i++){ $egale = false; for($j=0;$j<mysql_num_rows($liste_tables_base_compare);$j++){ if(mysql_tablename($liste_tables_base, $i) == mysql_tablename($liste_tables_base_compare, $j)){ $egale = true; $num = $j; break; } } if($egale == false){ //la table n'existe pas dans les deux bases, je la crée donc dans $base_compare mysql_selectdb($base);//selectionne la base $create= mysql_query("SHOW CREATE TABLE ".mysql_tablename($liste_tables_base, $i)) or die('ERREUR : '.mysql_error()); $tableau = mysql_fetch_array($create); $tableau[1] .= ";"; mysql_selectdb($base_compare);//selectionne la base mysql_query($tableau[1]) or die('ERREUR : '.mysql_error()); } } } if($structure == true){ //traitement des données de tables $liste_tables_base = mysql_list_tables($base); for($i=0;$i<mysql_num_rows($liste_tables_base);$i++){ $table_name = mysql_tablename($liste_tables_base, $i); mysql_selectdb($base);//selectionne la base $query = "SELECT * FROM ".$table_name; $result = mysql_query($query) or die('ERREUR : '.mysql_error()); mysql_selectdb($base_compare);//selectionne la base $query1 = "SHOW COLUMNS FROM ".$table_name; $result1 = mysql_query($query1); $nbr_champ = mysql_num_rows($result1); unset($champ); while($row = mysql_fetch_array($result1)) { $champ[] = $row['Field']; } while($data = mysql_fetch_array($result)){ $query2 = "SELECT * FROM ".$table_name." WHERE ".$champ[0]." = ".$data[0]; $result2 = mysql_query($query2) or die('ERREUR : '.mysql_error()); if(mysql_num_rows($result2) == 0){ //si ca ne renvoye rien c'est que la ligne n'est pas dans $base_compare $query3 = "INSERT INTO ".$table_name." VALUES ('".addslashes($data[0])."'"; for($j=1;$j<$nbr_champ;$j++){ $query3 .= ",'".addslashes($data[$j])."'"; } $query3 .= ")"; echo $query3.'<br>'; mysql_query($query3) or die('ERREUR : '.mysql_error()); } else{ //TODO //si ca renvoye quelque chose c'est que l'enregistrement est déjà dans $base_compare, il faut vérifier que c'est le même. } } } } return $dump; } ?>
Je ne sais pas trop comment vérifier si les champs sont égaux au cas ou le tuple est dans les deux bases (c'est la dernière partie du code de la fonction ci-dessous).
Si quelqu'un peut m'aider à compléter mon code ou me donner quelques pistes, parce que je commence à être un peu perdu dans mes boucles là...même si c'est moi qui ai développé la fonction dans son intégralité...ca sent la fin de journée, mon cerveau s'embrouille...
Faites un copier-coler du code dans votre éditeur favori celà sera plus lisible et en couleur :P parce que là j'avoue que même dans des balises code ca commence a devenir illisible...
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94 <?php require('librairie/dump.php'); //compare les deux bases et renvoye une chaine contenant le dump de la base synchronisée //on choisit si on veut synchronisé la structure et si on veut synchroniser les données function synchronisation($server,$login,$password,$base,$base_compare, $donnees = false,$structure = false){ $dump = null; if($structure == true){ //traitement des structure de tables $liste_tables_base = mysql_list_tables($base); $liste_tables_base_compare = mysql_list_tables($base_compare); //je prends l'élément de la premiere base et je regarde si il est dans la deuxième for($i=0;$i<mysql_num_rows($liste_tables_base);$i++){ $egale = false; for($j=0;$j<mysql_num_rows($liste_tables_base_compare);$j++){ if(mysql_tablename($liste_tables_base, $i) == mysql_tablename($liste_tables_base_compare, $j)){ $egale = true; $num = $j; break; } } if($egale == false){ //la table n'existe pas dans les deux bases, je la crée donc dans $base_compare mysql_selectdb($base);//selectionne la base $create= mysql_query("SHOW CREATE TABLE ".mysql_tablename($liste_tables_base, $i)) or die('ERREUR : '.mysql_error());//recupere la requete de création de la table $tableau = mysql_fetch_array($create); $tableau[1] .= ";"; mysql_selectdb($base_compare);//selectionne la base mysql_query($tableau[1]) or die('ERREUR : '.mysql_error()); } } } if($structure == true){ //traitement des données de tables $liste_tables_base = mysql_list_tables($base); for($i=0;$i<mysql_num_rows($liste_tables_base);$i++){ $table_name = mysql_tablename($liste_tables_base, $i); mysql_selectdb($base);//selectionne la base $query = "SELECT * FROM ".$table_name;//recupere les données dans $base $result = mysql_query($query) or die('ERREUR : '.mysql_error()); mysql_selectdb($base_compare);//selectionne la base $query1 = "SHOW COLUMNS FROM ".$table_name; $result1 = mysql_query($query1); $nbr_champ = mysql_num_rows($result1); unset($champ); while($row = mysql_fetch_array($result1)) { $champ[] = $row['Field'];//recupere le nom des champs } while($data = mysql_fetch_array($result)){ $query2 = "SELECT * FROM ".$table_name." WHERE ".$champ[0]." = ".$data[0];//cherche la ligne de $base dans $base_compare $result2 = mysql_query($query2) or die('ERREUR : '.mysql_error()); if(mysql_num_rows($result2) == 0){ //si ca ne renvoye rien c'est que la ligne n'est pas dans $base_compare //création de la requete d'insertion $query3 = "INSERT INTO ".$table_name." VALUES ('".addslashes($data[0])."'"; for($j=1;$j<$nbr_champ;$j++){ $query3 .= ",'".addslashes($data[$j])."'"; } $query3 .= ")"; //fin de création de la requete mysql_query($query3) or die('ERREUR : '.mysql_error()); } //si ca renvoye quelque chose c'est que l'enregistrement est déjà dans $base_compare, il faut vérifier que c'est le même. //les tables ou la base local a raison en cas de modification elseif($table_name == 'address_book' || $table_name == 'customers' || $table_name == 'customers_info' || $table_name == 'orders' || $table_name == 'orders_products' || $table_name == 'orders_products_attribute' || $table_name == 'products_groups'){ //comparer si les valeurs des champs sont égales //si oui on fait rien //si non on fait un update sur $bdd_compare } } } } $dump = mysql_sauv($server,$login,$password,$base_compare); return $dump; } ?>
Ma fonction en découragerait-il plus d'un ? :lol: :lol:
remarquaot, je le comprends tout a fait, moi aussi elle me décourage par moment :lol: :lol:
ce qui me décourage, c'est que je vais devoir faire un programme de synchronisation de 2 bases de données (MYSQL et ACCESS).... Je me dis que j'ai de la chance de pas avoir à synchroniser les structures etant données qu'elles sont différentes d'une base a l'autre :roll:
Ca me fait peur tout ca :?
dans ton cas regarde si tu gagnerais pas tu temps a faire un dump en xml ou en csv et a comparer les deux fichiers textes que tu obtient en les parcourant...
Une approche serait de concaténer tous les champs du tuple et de comparer comme une brute, non ?
tu parles pour qui kirkis la ?
À toi vu qu'il n'y a que nous ici ^_^
Sion_Sempai n'était que de passage pour te plaindre, du haut de sa grande empathie :roll:
Pour ma part j'ai terminé et celà fonctionne je vous metterais tout mon code dès que j'aurais le temps...
:lol:Citation:
Envoyé par Kirkis
Je suis pas venu LE plaindre, mais ME plaindre :P
d'autant que ce que je vais devoir faire ne sera peut-etre pas faisable en PHP puisque ca devra tourner comme un service windows :?
salut,
je suis interessé par ton script, mais j'ai quelques questions :
1)
tu fais appelle a dump.php, que contient t'il ? tes login pass et nom de bdd ?
2)
ce script tu le met sur le serveur distant ?
3) pour te connectersur le le serveur "local" tu es obligé d'ouvrir le port 3306 ?
4) tu mets en parametre jsute un login et pass, ce st les memes sur les 2 serveurs alors c ca ?
merci d'avance
le fichier dump je l'ai mis un peu avant regarde
je n'ouvre aucun port
le pass et login que je passe au dump.php (qui est sur le distant) n'est pas le meme que le serveur, c'est juste pour éviter que quelqu'un tape cette url dans son navigateur et récupére le dump de la base...
Des que j'aurais le temps j'essayerais de détailler cela...
salut, désolé mais j'ai pas lu les 6 pages :roll:
simplement, si j'ai bien suivi, tu veux importer ton fichier sql local dans la base distante?
alors il existe un script php que j'ai utilisé pour remplir une base avec un ficher sql de 250Mo, donc qui marche très bien: tu le trouverra ici
Il te suffit de mettre ce fichier sur ton serveur par ftp, après lui avoir donné les renseignements de connexion à la base, puis mettere ton fichier .sql à coté (de préférence les 2 dans un meme répertoire)
Ensuite tu lance et il importe tout (en exécutant les requetes par paquets pour ne pas surcharger le serveur)