Comparaison de plusieurs tables avec plusieurs base de donnée

Résolu
rasielblas Messages postés 135 Date d'inscription   Statut Membre Dernière intervention   -  
jee pee Messages postés 41501 Date d'inscription   Statut Modérateur Dernière intervention   -
Bonjour,

J'ai un code qui permet de relié plusieurs base de donnée et de faire la comparaison de tous ces bases.
Mon problème c'est que chaque base ne contient qu'un seul table fournisseurs chacun, et j'aimerais insérer un autre table client. Alors comment modifier la requête sql de façons à ce qu'elle puissent faire la comparaison de plusieurs tables et non un seul table.
Voici mon code:
import sqlite3

def create_table(db_name, values):
    con = sqlite3.connect("./databases/%s.db" % db_name)
    cur = con.cursor()
    cur.execute(
        '''CREATE TABLE fournisseurs(
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            nom TEXT
        )'''
    )
    s = ','.join(('(?)',) * len(values))
    cur.execute('INSERT INTO fournisseurs(nom) VALUES %s' % s, values)
    con.commit()
    con.close()


def tables_dif(main_db_name, *db_names):
    con = sqlite3.connect(":memory:")
    con.execute("ATTACH DATABASE './databases/%s.db' AS main_db" % main_db_name)
    cur = con.cursor()
    res = {}
    for db_name in db_names:
        con.execute("ATTACH DATABASE './databases/%s.db' AS db" % db_name)
        sql = '''
        SELECT t2.id, t2.nom
        FROM db.fournisseurs as t2
        LEFT JOIN main_db.fournisseurs as t
        USING(nom)
        WHERE t.nom IS NULL
        '''
        cur.execute(sql)
        res[db_name] = cur.fetchall()
        con.execute("DETACH DATABASE db")
    con.close()
    return res


try:
    create_table('main', ('jojo', 'mimi', 'riri'))
    create_table('base1', ('jojo', 'riri', 'vévé'))
    create_table('base2', ('riri', 'lulu'))
except:
    pass

print(tables_dif('main', 'base1', 'base2'))


Cordialement!
A voir également:

1 réponse

yg_be Messages postés 23541 Date d'inscription   Statut Contributeur Dernière intervention   Ambassadeur 1 584
 
bonjour,
tu pourrais par exemple modifier la requête SQL ainsi:
SELECT "fournisseurs", t2.id, t2.nom
        FROM db.fournisseurs as t2
        LEFT JOIN main_db.fournisseurs as t
        USING(nom)
        WHERE t.nom IS NULL
UNION
SELECT "client", t2.id, t2.nom
        FROM db.client as t2
        LEFT JOIN main_db.client as t
        USING(nom)
        WHERE t.nom IS NULL
1
rasielblas Messages postés 135 Date d'inscription   Statut Membre Dernière intervention   9
 
Merci de votre réponse, ça marche bien, mais le problème c'est qu'avec UNION si le nombre de champ sélectionné de la premier table est différent de la deuxième table alors ça ne marche pas!
Par exemple si je fais quelque chose du genre:
SELECT *
        FROM db.fournisseurs as t2
        LEFT JOIN main_db.fournisseurs as t
        USING(nom)
        WHERE t.nom IS NULL
UNION
SELECT*
        FROM db.client as t2
        LEFT JOIN main_db.client as t
        USING(nom)
        WHERE t.nom IS NULL


Est que dans le table client il y a 3 champs mais que dans la table fournisseur il n'y a que deux champs alors cela ne fonctionne pas avec UNION.
En plus si je possède plusieurs tables par exemple 20 alors le requête devient très long, y a t'il d'autre option à part l'utilisation de "UNION"?
Cordialement!
0
yg_be Messages postés 23541 Date d'inscription   Statut Contributeur Dernière intervention   1 584 > rasielblas Messages postés 135 Date d'inscription   Statut Membre Dernière intervention  
 
peux-tu essayer de donner toutes les informations dés le départ, plutôt que d'en rajouter quand nous te proposons une solution?
0
rasielblas Messages postés 135 Date d'inscription   Statut Membre Dernière intervention   9
 
Ok! je résume, j'ai trois base de donnée, base1 qui contient l'ensemble d'enregistrement de la base 2 et base3, mon code permet de comparer l'enregistrement de ses bases.

Si le contenu de la base 2 et 3 ne se trouve pas dans base 1 alors on affiche le contenu manquant.

Le problème c'est que j'ai plusieurs tables dans chacun des bases et avec la requete UNION je peut fusionner les tables.

Mais le problème c'est qu'avec la requête UNION pour que ça fonctionne il faut que le champ de la table soit le même alors que le nombre de chacun des tables est différent.

En plus si j'ai plusieurs tables 20 par exemple je suis obligé de faire UNION pour chaque tables et la requête de vient très long, et j'aimerais savoir s'il existe un autre moyen de sélectionner les tables d'une autre manière. Voici mon code:

import sqlite3

def create_table(db_name, values):
    con = sqlite3.connect("./databases/%s.db" % db_name)
    cur = con.cursor()
    cur.execute(
        '''CREATE TABLE fournisseurs(
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            nom TEXT
        )'''
    )
    s = ','.join(('(?)',) * len(values))
    cur.execute('INSERT INTO fournisseurs(nom) VALUES %s' % s, values)
    con.commit()
    con.close()


def tables_dif(main_db_name, *db_names):
    con = sqlite3.connect(":memory:")
    con.execute("ATTACH DATABASE './databases/%s.db' AS main_db" % main_db_name)
    cur = con.cursor()
    res = {}
    for db_name in db_names:
        con.execute("ATTACH DATABASE './databases/%s.db' AS db" % db_name)
        sql = '''
        SELECT "fournisseurs", t2.id, t2.nom
        FROM db.fournisseurs as t2
        LEFT JOIN main_db.fournisseurs as t
        USING(nom)
        WHERE t.nom IS NULL
UNION
SELECT "client", t2.id, t2.nom
        FROM db.client as t2
        LEFT JOIN main_db.client as t
        USING(nom)
        WHERE t.nom IS NULL
        '''
        cur.execute(sql)
        res[db_name] = cur.fetchall()
        con.execute("DETACH DATABASE db")
    con.close()
    return res


try:
    create_table('main', ('jojo', 'mimi', 'riri'))
    create_table('base1', ('jojo', 'riri', 'vévé'))
    create_table('base2', ('riri', 'lulu'))
except:
    pass

print(tables_dif('main', 'base1', 'base2'))
0
yg_be Messages postés 23541 Date d'inscription   Statut Contributeur Dernière intervention   1 584 > rasielblas Messages postés 135 Date d'inscription   Statut Membre Dernière intervention  
 
une autre possibilité serait d'appeler plusieurs fois la fonction tables_dif, en lui passant des paramètres supplémentaires, le nom de la table et les noms des champs.
qu'en penses-tu?
0
jee pee Messages postés 41501 Date d'inscription   Statut Modérateur Dernière intervention   9 712 > rasielblas Messages postés 135 Date d'inscription   Statut Membre Dernière intervention  
 
Bonjour,

La logique serait alors que tu rajoutes un niveau au dessus de ton code où tu paramètres les tables à traiter, du style
FOR T in ('client','fournisseur','commande', ....)


ou même générer la boucle à partir du dictionnaire de données de la base, je ne sais pas si cela existe dans sqlite, comme
"select table_name from dictionnary"
0