IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

QxOrm Discussion :

[QxOrm 1.2.2] Bogue avec les relations OneToMany


Sujet :

QxOrm

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    151
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 151
    Points : 49
    Points
    49
    Par défaut [QxOrm 1.2.2] Bogue avec les relations OneToMany
    Hello !

    Je ne sais pas si ça vient de mon côté, mais j'ai un bug avec les relations. Je soupçonne mon script de création de BDD d'être à l'origine de cela, mais je n'en suis pas certain.

    Voici ci-joint, un exemple qui montre que l'id de la relation n'est pas inséré quand on fait appel à insert_with_all_relations.
    Fichiers attachés Fichiers attachés

  2. #2
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    151
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 151
    Points : 49
    Points
    49
    Par défaut
    Note: j'ai du tronquer mon script, du coup, bien penser à effacer la base de donnée à chaque test.

  3. #3
    Expert confirmé

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    481
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 481
    Points : 4 238
    Points
    4 238
    Par défaut
    J'ai regardé (très) vite fait ton code, j'ai juste une remarque comme ça :
    - Dans ta classe Person, tu as une relation one-to-many vers Pizza ;
    - Il manque côté Pizza une relation many-to-one vers Person.

    Un truc que tu peux essayer, c'est le tutoriel qxBlog qui est présent dans le dossier ./test/ du package QxOrm.
    Il contient ce type de relation : http://marty-lionel.developpez.com/t...el-qxblog/#LVI
    Ce serait bien que tu essayes de reproduire ton soucis avec le tutoriel qxBlog :
    - si ça marche dans qxBlog => c'est que ça vient de ton code ;
    - si ça ne marche pas dans qxBlog => alors c'est un bug de la bibliothèque.
    Le site de la bibliothèque QxOrm : bibliothèque C++ de gestion de données (Mapping Objet Relationnel ou ORM) basée sur les frameworks Qt et boost.
    QxEntityEditor : éditeur graphique pour la bibliothèque QxOrm (application multi-plateforme pour gérer graphiquement le modèle d'entités).

    Tutoriel : installer un environnement de développement avec QxOrm sous Windows.
    Tutoriel qxBlog : gestion de blogs en C++/Qt.
    Tutoriel qxClientServer : création d'un serveur d'applications en C++/Qt.

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    151
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 151
    Points : 49
    Points
    49
    Par défaut
    Citation Envoyé par QxOrm Voir le message
    J'ai regardé (très) vite fait ton code, j'ai juste une remarque comme ça :
    - Dans ta classe Person, tu as une relation one-to-many vers Pizza ;
    - Il manque côté Pizza une relation many-to-one vers Person.
    Ah ! C'est obligatoire la symétrie ?

    C'est également valable pour les relations n-n ?

  5. #5
    Expert confirmé

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    481
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 481
    Points : 4 238
    Points
    4 238
    Par défaut
    C'est important oui, même pour les relations n-n.
    Regarde le tutoriel qxBlog, c'est exactement comme ça qu'il est construit...
    Le site de la bibliothèque QxOrm : bibliothèque C++ de gestion de données (Mapping Objet Relationnel ou ORM) basée sur les frameworks Qt et boost.
    QxEntityEditor : éditeur graphique pour la bibliothèque QxOrm (application multi-plateforme pour gérer graphiquement le modèle d'entités).

    Tutoriel : installer un environnement de développement avec QxOrm sous Windows.
    Tutoriel qxBlog : gestion de blogs en C++/Qt.
    Tutoriel qxClientServer : création d'un serveur d'applications en C++/Qt.

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    151
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 151
    Points : 49
    Points
    49
    Par défaut
    Bonjour à nouveau,

    J'ai simplifié et corrigé mon exemple, je fais de mon mieux pour montrer ce bogue.
    En fait, je suis maintenant presque certain que ça ne vient pas de mon script de création de la BDD.
    Je peux essayer de le reproduire dans qxblog, mais je ne pense pas que ça va simplifier la résolution du bug: l'exemple que je met en pièce jointe est minimal et simple à comprendre.
    Je vais quand même essayer...

    En fait, je pense que ça marche côté qxblog car l'insert est fait côté ManyToOne de la relation.

    J'espère que tu pourras m'éclairer, c'est assez critique...
    Fichiers attachés Fichiers attachés

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    151
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 151
    Points : 49
    Points
    49
    Par défaut
    Mmmh... Je crois que j'ai compris: c'est à cause de l'id auto-généré !!

    Dans qxBlog, d'après mes tests, ça ne peut que fonctionner car l'id d'un auteur n'est pas auto-généré

    Quel est ton avis là dessus ?

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    151
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 151
    Points : 49
    Points
    49
    Par défaut
    Ah non, en fait, je crois que c'est plus compliqué que ça, je vérifie.

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    151
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 151
    Points : 49
    Points
    49
    Par défaut
    Ok, fausse alerte, j'avais omis ceci dans mon script:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if ( p && p->getDao() && !p->hasSqlRelation() )
    Je pense que tu devrais proposer un script bien fait pour générer la base de donnée, mais après, n'étant pas un expert en la matière, je ne sais pas si c'est une bonne idée. Après tout, tu donnes déjà le dumpSqlSchema, qui aide bien.

    Désolé

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    151
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 151
    Points : 49
    Points
    49
    Par défaut
    Citation Envoyé par djarBoy Voir le message
    Ok, fausse alerte, j'avais omis ceci dans mon script:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if ( p && p->getDao() && !p->hasSqlRelation() )
    Je pense que tu devrais proposer un script bien fait pour générer la base de donnée, mais après, n'étant pas un expert en la matière, je ne sais pas si c'est une bonne idée. Après tout, tu donnes déjà le dumpSqlSchema, qui aide bien.

    Désolé
    Mmmh... C'est dur en fait, si je vire ceci, les id des relations ManyToOne ne sont plus ajoutés dans les tables...

    En fait, j'explique un peu, mon script (donné ci-après) m'ajoute des colonnes pour les relations OneToMany, et je ne sais pas comment éviter ça...

    Si par exemple, je crée une relation avec:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    t.relationOneToMany( &Form::pages, "list_pages", "doc_id" );
    Ca va me créer une colonne pour list_pages...

    Je vais essayer de trouver une solution, si jamais tu as une idée, je suis preneur.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
     
    void updateDatabaseVersion( const EDatabaseStatus status )
    {
        try {
            int domainVersion = qApp->property( "DomainVersion" ).toInt();
     
            // We connect to the database with an user that has rights for the database creation
            QSqlDatabase db = qx::QxSqlDatabase::getSingleton()->getDatabaseCloned();
            db.setUserName( "root" );
            db.setPassword( "" );
            const bool isSQLite = db.driverName().contains( "SQLITE" );
     
            // Create a transaction that will throw exception on errors
            qx::QxSession session( db, true, true );
     
            // Fetch database version that will lock concurrent access (when multiple users starts the application at the same time)
            DatabaseVersion dbVersion;
     
            if ( status == eDatabaseStatusNotUpTodate )
            {
                QSqlError err = session.fetchByQuery( qx_query( QString( "WHERE name='") + kAppName + ( isSQLite ? "'" : QString("' FOR UPDATE") ) ), dbVersion );
                if ( !err.isValid() )
                {
                    // For other users, when the locking will be over, we check if the update is still needed
                    if ( dbVersion.version >= domainVersion ) { return; }
                }
                else
                {
                    dbVersion.name = kAppName;
                    dbVersion.version = -1;     // Create tables
                }
            }
            else
            {
                dbVersion.name = kAppName;
                dbVersion.version = -1;     // Create tables
            }
            // Execute each query with this object
            QSqlQuery query( db );
     
            // On récupère toutes les classes persistantes C++ enregistrées dans le contexte QxOrm
            qx::QxCollection<QString, qx::IxClass *> * pAllClasses = qx::QxClassX::getAllClasses();
            if ( !pAllClasses ) { qAssert(false); return; }
     
            // Get database tables
            QStringList tables = db.tables();
            for ( long k = 0; k < pAllClasses->count(); k++ )
            {
                qx::IxClass * pClass = pAllClasses->getByIndex( k );
                if ( !pClass ) { continue; }
     
                // Filter non persistant classes
                if ( pClass->isKindOf( "qx::service::IxParameter" ) || pClass->isKindOf( "qx::service::IxService" ) ) { continue; }
     
                if (pClass->getVersion() <= dbVersion.version) { continue; }
     
                // We create tables if not already existing, and we define its owner
                if ( !tables.contains( pClass->getName() ) )
                {
                    // Create attribute query query section
                    QStringList attributes;
                    qx::IxDataMemberX * pDataMemberX = pClass->getDataMemberX();
                    for ( long l = 0; (pDataMemberX && (l < pDataMemberX->count_WithDaoStrategy())); l++ )
                    {
                        QString sql;
                        qx::IxDataMember * p = pDataMemberX->get_WithDaoStrategy(l);
                        if ( p && p->getDao() && !p->hasSqlRelation() )
                        {
                            sql += p->getName() + " " + p->getSqlType();
                            if ( p->getNotNull() ) // NOT NULL
                            {
                                sql += " NOT NULL";
                            }
                            if ( p->getIsPrimaryKey() ) // PRIMARY KEY
                            {
                                sql += " PRIMARY KEY";
                            }
                            if ( p->getAutoIncrement() ) // AUTO INCREMENT
                            {
                                sql += " AUTOINCREMENT";
                            }
                            attributes.push_back( sql );
                        }
                    }
     
                    QString attributeSql;
                    if ( attributes.size() )
                    {
                        for( int i = 0; i < attributes.size() - 1; ++i )
                        {
                            attributeSql += attributes[i] + ", ";
                        }
                        attributeSql = QString( " (" ) + attributeSql + attributes[attributes.size() - 1] + ")";
                        if ( !isSQLite )
                        {
                            attributeSql += "  WITH ( OIDS = FALSE )";
                        }
                    }
                    query.exec( "CREATE TABLE " + pClass->getName() + attributeSql + ";" );
                    session += query.lastError();
                    if ( !isSQLite )
                    {
                        query.exec( "ALTER TABLE " + pClass->getName() + " OWNER TO \"root\";" );
                        session += query.lastError();
                    }
                    // Create sequences & index
                    for ( long l = 0; (pDataMemberX && ( l < pDataMemberX->count_WithDaoStrategy() ) ); l++ )
                    {
                        qx::IxDataMember * p = pDataMemberX->get_WithDaoStrategy(l);
                        if ( p && p->getDao() && !p->hasSqlRelation() )
                        {
     
                            if ( p->getAllPropertyBagKeys().contains( "INDEX" ) ) // INDEX
                            {
                                query.exec( "CREATE INDEX " + pClass->getName() + "_" + p->getName() + "_idx" + 
                                            " ON " + pClass->getName() + " USING " + p->getPropertyBag("INDEX").toString() + " (" + p->getName() + ");" );
                                session += query.lastError();
                            }
     
                            if (p->getAutoIncrement() && !isSQLite ) // AUTO INCREMENT
                            {
                                query.exec( "CREATE SEQUENCE " + pClass->getName() + "_" + p->getName() + "_seq" + "; " );
                                session += query.lastError();
                                if ( !isSQLite )
                                {
                                    query.exec( "ALTER TABLE " + pClass->getName() + "_" + p->getName() + "_seq" + " OWNER TO \"root\"; " );
                                    session += query.lastError();
                                }
                                query.exec( "ALTER TABLE " + pClass->getName() + " ALTER COLUMN " + p->getName() + " " +
                                            "SET DEFAULT nextval('" + pClass->getName() + "_" + p->getName() + "_seq" + "'::regclass);" );
                                session += query.lastError();
                            }
                        }
                    }
     
                    // Insert all relations to SQL schema
                    for (long l = 0; ( pDataMemberX && ( l < pDataMemberX->count_WithDaoStrategy() ) ); l++)
                    {
                        qx::IxDataMember * p = pDataMemberX->get_WithDaoStrategy( l );
                        if ( p && p->hasSqlRelation() && p->getVersion() >= dbVersion.version )
                        {
                            p->getSqlRelation()->init();
                            QString sql = p->getSqlRelation()->createExtraTable();
                            query.exec( sql );
                            session += query.lastError();
                        }
                    }
                }
                else
                {
                    // We add columns to table if they don't exists
                    qx::IxDataMemberX * pDataMemberX = pClass->getDataMemberX();
                    for ( long l = 0; (pDataMemberX && (l < pDataMemberX->count_WithDaoStrategy())); l++ )
                    {
                        qx::IxDataMember * p = pDataMemberX->get_WithDaoStrategy(l);
                        if ( !p || ( p->getVersion() <= dbVersion.version ) ) { continue; }
     
                        query.exec( "ALTER TABLE " + pClass->getName() + " ADD COLUMN " + p->getName() + " " + p->getSqlType() + ";" );
                        session += query.lastError();
     
                        if ( p->getIsPrimaryKey() ) // PRIMARY KEY
                        {
                            query.exec( "ALTER TABLE " + pClass->getName() + " ADD PRIMARY KEY (" + p->getName() + ");" );
                            session += query.lastError();
                        }
     
                        if ( p->getAllPropertyBagKeys().contains("INDEX") ) // INDEX
                        {
                            query.exec("CREATE INDEX " + pClass->getName() + "_" + p->getName() + "_idx" + 
                                        " ON " + pClass->getName() + " USING " + p->getPropertyBag("INDEX").toString() + " (" + p->getName() + ");");
                            session += query.lastError();
                        }
     
                        if ( p->getNotNull() ) // NOT NULL
                        {
                            query.exec("ALTER TABLE " + pClass->getName() + " ALTER COLUMN " + p->getName() + " SET NOT NULL;");
                            session += query.lastError();
                        }
     
                        if ( p->getAutoIncrement() && !isSQLite ) // AUTO INCREMENT
                        {
                            query.exec( "CREATE SEQUENCE " + pClass->getName() + "_" + p->getName() + "_seq" + "; " );
                            session += query.lastError();
                            if ( !isSQLite )
                            {
                                query.exec( "ALTER TABLE " + pClass->getName() + "_" + p->getName() + "_seq" + " OWNER TO \"root\"; " );
                                session += query.lastError();
                            }
                            query.exec( "ALTER TABLE " + pClass->getName() + " ALTER COLUMN " + p->getName() + " " +
                                        "SET DEFAULT nextval('" + pClass->getName() + "_" + p->getName() + "_seq" + "'::regclass);" );
                            session += query.lastError();
                        }
     
                        if ( p->getDescription() != "" ) // DESCRIPTION
                        {
                            query.exec("COMMENT ON COLUMN " + pClass->getName() + "." + p->getName() + " IS $$" + p->getDescription() + "$$ ;");
                            session += query.lastError();
                        }
                    }
                }
            }
     
            // Update database version
            dbVersion.version = domainVersion;
            try
            {
                session.save( dbVersion );
            }
            catch (const qx::dao::sql_error &)
            {
                session.insert( dbVersion );
            }
            // End of "try" : Session is destroyed => automatic commit or rollback
            // commit or rollback will unlock locked table (not for SQLite)
       }
        catch (const qx::dao::sql_error & err)
        {
            QSqlError sqlError = err.get();
            qDebug() << sqlError.databaseText();
            qDebug() << sqlError.driverText();
            qDebug() << sqlError.number();
            qDebug() << sqlError.type();
        }
    }

  11. #11
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    151
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 151
    Points : 49
    Points
    49
    Par défaut
    Bon, cette fois-ci, je pense avoir résolu le problème; j'ai ajouté cette ligne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    if (  p->hasSqlRelation() && p->getSqlRelation()->getDescription() == "relation one-to-many" )
                                    continue;
    J'espère ne pas me tromper en enlevant cet attribut...
    Au passage, je pense que tu devrais mettre un enum ou des constantes au lieu de "relation one-to-many", parce que rien ne me dit que ceci ne va pas changer dans de futures versions de QxOrm...

  12. #12
    Expert confirmé

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    481
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 481
    Points : 4 238
    Points
    4 238
    Par défaut
    Cool, un problème qui se résout tout seul

    Pense juste à utiliser le bouton "Éditer" du forum, ça évite d'empiler 4 ou 5 messages de la même personne à la suite, et ce sera plus clair pour lire (un truc du style : EDIT1, EDIT2, EDIT3, etc.).

    Je pense que tu devrais proposer un script bien fait pour générer la base de donnée, mais après, n'étant pas un expert en la matière, je ne sais pas si c'est une bonne idée. Après tout, tu donnes déjà le dumpSqlSchema, qui aide bien.
    Oui normalement, la fonction qx::QxClassX::dumpSqlSchema() te fourni un schéma SQL fonctionnel pour une base SQLite.
    +++ ce sujet sur la FAQ pour apporter des notions en plus : Comment générer le schéma SQL (création et mise à jour des tables) en fonction des classes persistantes C++ définies dans le contexte QxOrm ?

    Dans tous les cas, je le répète, mais je conseille de créer soi-même sa BDD avec un outil spécifique à chaque SGBD (même si je comprends l'utilité d'un script).

    je pense que tu devrais mettre un enum ou des constantes au lieu de "relation one-to-many"
    Ça ne changera pas dans les prochaines versions, promis

    J'espère ne pas me tromper en enlevant cet attribut...
    Je ne sais pas, c'est bizarre ton truc quand même !

    Je pense que le plus gros problème que tu as, c'est que tu ne sais pas quelles sont les colonnes que tu dois avoir dans tes tables pour que tout fonctionne correctement.
    Peut-être que tu devrais avoir un schéma sur papier avec toutes tes tables et tes colonnes pour que tout fonctionne correctement (avant de commencer à créer tes classes C++).
    Par exemple, le coup de la table avec comme seule colonne celle de l'ID auto-généré => pour moi ça ce n'est pas bon (cf. ton précédent message).

    Je le répète, mais comprendre le tutoriel qxBlog est très important si tu veux utiliser la notion de relations. Il y a peut-être des bugs dans le projet qxBlog, mais dans ce cas, je préfère déboguer sur ce projet-là car je sais qu'il est designé correctement.
    Après il suffit juste de transposer à ton contexte d'utilisation (je sais, des fois c'est pas évident), mais je pense que dès que tu as un problème, il faudrait que ce soit presque un réflexe :
    - pb avec relation one-to-many : ici
    - pb avec relation many-to-one : ici
    - pb avec relation many-to-many : ici
    Le site de la bibliothèque QxOrm : bibliothèque C++ de gestion de données (Mapping Objet Relationnel ou ORM) basée sur les frameworks Qt et boost.
    QxEntityEditor : éditeur graphique pour la bibliothèque QxOrm (application multi-plateforme pour gérer graphiquement le modèle d'entités).

    Tutoriel : installer un environnement de développement avec QxOrm sous Windows.
    Tutoriel qxBlog : gestion de blogs en C++/Qt.
    Tutoriel qxClientServer : création d'un serveur d'applications en C++/Qt.

  13. #13
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    151
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 151
    Points : 49
    Points
    49
    Par défaut
    Citation Envoyé par QxOrm Voir le message

    Je ne sais pas, c'est bizarre ton truc quand même !
    Ben, c'est à dire que, lors d'une relation, OneToMany de ce type:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    t.relationOneToMany( &Form::pages, "list_pages", "doc_id" );
    je ne comprends pas pourquoi j'ai un attribut list_pages, on est bien d'accord qu'il n'a rien à faire dans les colonnes de la table Form ? Peut être qu'en interne ça a une utilité, mais dans le schéma physique, je n'en vois pas l'utilité.

    Citation Envoyé par QxOrm Voir le message
    Je pense que le plus gros problème que tu as, c'est que tu ne sais pas quelles sont les colonnes que tu dois avoir dans tes tables pour que tout fonctionne correctement.
    Peut-être que tu devrais avoir un schéma sur papier avec toutes tes tables et tes colonnes pour que tout fonctionne correctement (avant de commencer à créer tes classes C++).

    Le problème c'est que ça fait longtemps que je n'ai pas fait de gestion de base de donnée !

    Citation Envoyé par QxOrm Voir le message
    Par exemple, le coup de la table avec comme seule colonne celle de l'ID auto-généré => pour moi ça ce n'est pas bon (cf. ton précédent message).
    Je ne sais pas trop si c'est bon ou pas, en fait, c'est un cas très particulier où j'ai besoin de stocker une structure plutôt que des données (la structure d'un formulaire avec des pages, des sections de pages, et des composants dans les sections).

  14. #14
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    151
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 151
    Points : 49
    Points
    49
    Par défaut
    Citation Envoyé par QxOrm Voir le message
    Je le répète, mais comprendre le tutoriel qxBlog est très important si tu veux utiliser la notion de relations. Il y a peut-être des bugs dans le projet qxBlog, mais dans ce cas, je préfère déboguer sur ce projet-là car je sais qu'il est designé correctement.
    Après il suffit juste de transposer à ton contexte d'utilisation (je sais, des fois c'est pas évident), mais je pense que dès que tu as un problème, il faudrait que ce soit presque un réflexe :
    - pb avec relation one-to-many : ici
    - pb avec relation many-to-one : ici
    - pb avec relation many-to-many : ici
    Je comprends tout à fait, mais hélas, qxblog ne couvre pas tous les cas d'utilisation possibles...

  15. #15
    Expert confirmé

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    481
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 481
    Points : 4 238
    Points
    4 238
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    t.relationOneToMany( &Form::pages, "list_pages", "doc_id" );
    je ne comprends pas pourquoi j'ai un attribut list_pages, on est bien d'accord qu'il n'a rien à faire dans les colonnes de la table Form ? Peut être qu'en interne ça a une utilité, mais dans le schéma physique, je n'en vois pas l'utilité.
    En effet, la colonne "list_pages" n'a aucune utilité et ne doit pas être créée !

    Maintenant, regarde le même exemple côté qxBlog (je sais j'insiste mais ça couvre tout ce que la bibliothèque est capable de faire en terme de relations), ça correspond exactement à la table author : t.relationOneToMany(& author::m_blogX, "list_blog", "author_id"); (un author est une personne qui peut rédiger plusieurs blog).
    Maintenant quand tu exécutes le projet, regarde comment est généré la table author :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    CREATE TABLE author (author_id TEXT NOT NULL PRIMARY KEY, name TEXT, birthdate DATE, sex INTEGER)
    Tu vois, il n'y a pas "list_blog" dans le schéma généré (c'est équivalent à ton "list_pages" qui ne doit pas apparaître non plus).
    Tu retrouveras la même chose si tu exécutes la fonction "qx::QxClassX::dumpSqlSchema();", tu obtiens alors :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    [QxOrm] start dump SQL schema (4)
    CREATE TABLE author (author_id TEXT NOT NULL PRIMARY KEY, name TEXT, birthdate DATE, sex INTEGER)
    CREATE TABLE blog (blog_id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, blog_text TEXT, date_creation TIMESTAMP, author_id TEXT)
    CREATE TABLE IF NOT EXISTS category_blog (blog_id INTEGER NOT NULL, category_id INTEGER NOT NULL)
    CREATE TABLE comment (comment_id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, comment_text TEXT, date_creation TIMESTAMP, blog_id INTEGER)
    CREATE TABLE category (category_id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, name TEXT, description TEXT)
    CREATE TABLE IF NOT EXISTS category_blog (category_id INTEGER NOT NULL, blog_id INTEGER NOT NULL)
     
    [QxOrm] end dump SQL schema
    Conclusion : le problème vient de ta fonction de génération du script SQL.
    Peut-être que tu devrais la réécrire en partant de qx::QxClassX::dumpSqlSchema(); (en faisant un copier-coller au départ puis la modifier pour tes propres besoin).

    qxblog ne couvre pas tous les cas d'utilisation possibles...
    Il montre tout ce qu'il est possible de faire avec la bibliothèque QxOrm et la notion de relations, pas plus, pas moins.
    Pour créer une structure d'un formulaire avec des pages, des sections de pages, et des composants dans les sections, je pense qu'il est largement suffisant.
    Le site de la bibliothèque QxOrm : bibliothèque C++ de gestion de données (Mapping Objet Relationnel ou ORM) basée sur les frameworks Qt et boost.
    QxEntityEditor : éditeur graphique pour la bibliothèque QxOrm (application multi-plateforme pour gérer graphiquement le modèle d'entités).

    Tutoriel : installer un environnement de développement avec QxOrm sous Windows.
    Tutoriel qxBlog : gestion de blogs en C++/Qt.
    Tutoriel qxClientServer : création d'un serveur d'applications en C++/Qt.

  16. #16
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    151
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 151
    Points : 49
    Points
    49
    Par défaut
    Ok, merci de ton aide.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Besoin de précision avec les relations entre Tables
    Par johnvox dans le forum Outils
    Réponses: 10
    Dernier message: 17/12/2008, 17h45
  2. Problème avec les relations dans mon modèle
    Par wam35 dans le forum Schéma
    Réponses: 3
    Dernier message: 21/01/2008, 20h22
  3. Pb avec les relations
    Par altair8080 dans le forum Ruby on Rails
    Réponses: 1
    Dernier message: 10/12/2007, 14h25
  4. importer des tables avec les relations
    Par guigui5931 dans le forum Access
    Réponses: 5
    Dernier message: 23/06/2006, 12h14
  5. enregistrement, probleme avec les relations
    Par Nelmo dans le forum SQL Procédural
    Réponses: 6
    Dernier message: 27/04/2006, 17h23

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo