Seite 1 von 1

MySQL oder SQLite

Verfasst: 3. März 2008 23:01
von pfusterschmied
Hallo,

ich habe ein Programm mit Hilfe von QT erstellt, welches mir Daten aus einer Onlinedatenbank (MySQL) darstellt. Weiters können die Daten auch modifiziert werden.

Nun möchte ich das Programm mit einer "Lokalen Datenbank" erweitern, für den Fall, dass der User vorübergehend keine Internetverbindung hat. Als übergangslösung habe ich am Client einen MySQLServer eingerichtet und spiele immer händisch die Dumps ein.

Als mögliche Lösung hätte ich folgende 2 Ideen für dieses Problem:

Lösung 1: MySQL Server bleibt und das Dumpenund einspielen wird durch das Programm erledigt (Falls dies überhaupt möglich ist?)

Lösung 2: SQLite DB am Client einrichten und Daten vom Server einspielen.

Meine Fragen an euch:
Wie kann ich eine MySQL Datenbank mit QT am Besten eine DB offline bereitstellen?

Wie könnte ich einen gegenseitige Synchronisierung realisieren? (2nd Order)

Bin für jeden innovativen Vorschlag offen.

Verfasst: 4. März 2008 09:12
von upsala
Zum einen beherrscht MySQL Replikation (auch Multi-Master).
MySQL Server bleibt und das Dumpenund einspielen wird durch das Programm erledigt (Falls dies überhaupt möglich ist?)
Warum sollte dies nicht möglich sein? Beschäftige dich doch bitte auch mit deiner Datenbank-Doku...
Wie kann ich eine MySQL Datenbank mit QT am Besten eine DB offline bereitstellen?
Datenmenge, Fremdschlüsselverwendung, Synchronisierung in beide Richtungen notwendig? Hat aber eigentlich alles nichts mehr mit Qt zu tun...

Verfasst: 4. März 2008 09:39
von pfusterschmied
Mir ist schon klar, dass dieses Thema nicht unbedingt in dieses Forum passt. Ich dachte nur, dass vielleicht ein erfahrerner Programmieren einige Ideen dazu hat bevor ich mich in ein Fass ohne Boden stürtze.

Ich habe eine Relatationale MySQL DB. Die Datenmenge ist momentan mit 1MB (mysqlDump) noch sehr gering, wird aber in den nächsten Jahren auch nicht über 15MB steigen.

Die Synchronisierung wäre in beide Richtungen toll, auch wenn das nur über den TimeStamp geht. Glaube aber, dass dieser Aufwand nicht dafür steht.

Vielmehr geht es mir darum, dass der Anwender eine fertige MSI oder EXE bekommt die er installiert oder ausführt und alles Funktioniert.

Das Problem ist, dass ich nicht auf jeden Client MySQL Server installieren und einrichten möchte -> Daher die Idee mit SQLite.

Wie funktionieren denn grundlegend, Datenbank basierende Server-Client Applikationen. Mir fehlt im Moment einfach ein Ansatz wie ich an die Sache angehe.

Verfasst: 4. März 2008 11:15
von RHBaum
Lager deinen Daten-zugriff komplett in nen Plugin aus ...
erstell ein plugin fuer mysql, wo er sich inpliziet an nem vorhandenen server anmelden kann / muss
erstell nen plugin fuer SQLite wo er statt ner anmeldung vielleicht nen db -file angeben muss

zumindest nach deiner beschreibung der am besten geeignete weg ....

ne lokale DB (SQLite) mit ner zentralen DB (mysql) abgleichen so das user teilweisse offline arbeiten koennen, ist ned trivial, und wenn ich richtig verstanden hab auch ned was du brauchst ...

Ciao ...

Verfasst: 4. März 2008 12:09
von pfusterschmied
Danke für die rasche Antwort,
du hast mein Problem richtig Verstanden!

Mir geht es nur darum, dass die Anwender Offline Arbeiten (Daten ansehen können). Bearbeiten wird einfach deaktiviert, da ein Abgleich zurück in die OnlineDatenbank (MySQL) meine beschränkten Fähigkeiten übersteigt ...

Ich habe auch soweit schon beide PlugIns bereit. Mit dem Mysql PlugIn verbinde ich mich zur Online Datenbank und lasse mir die Daten über QSqlTableModel in einer QTableView anzeigen.

Auch das SQLite PlugIn funktioniert soweit. Ich habe eine lokale *.db3 Datei erstellt und bereits das Schema angelegt.

Nur wie bekomme ich nun die Daten in die lokale SQLite Datei???

Soll ich die QTableView einfach in die SQLite Datei speichern oder kann ich das auch im Hintergrund erledigen? Vielleicht die Daten in einem

Verfasst: 4. März 2008 12:24
von RHBaum
Mir geht es nur darum, dass die Anwender Offline Arbeiten (Daten ansehen können).
Dann langt dir doch nen tool , das nur du hasst.
Was ne verbindung zu deiner mysql datenbank oeffnet, und die daten in die sqlite db spult ... das sqlite file mit den statischen daten verteilst dann einfach mit.

Deine user muessen doch ned in die db schreiben ...
Irgendwo pflegst dann noch ne aktuelle version deiner statischen sqlite datei, die sich die user bei bedarf updaten koennen ....

wo ist das problem ?

Ciao ...

Verfasst: 4. März 2008 12:45
von pfusterschmied
Die Benutzer können in der Online - Version Daten bearbeiten
In der Offline Version dürfen nur angesehen werden...

Soweit so gut.

Das Programm entscheidet zu beginn ob eine Verbindung mit der Online DB besteht, wenn nicht wird die lokale SQLite Datei verwendet.

Soweit so gut.

Mein Problem ist folgendes:
Wie bekomme ich in einem QT Programm Daten von einer MySQL Datenbank in eine SQLite Datei?

Ich habe ein wenig gegoogelt und festgestellt, dass dies nicht so einfach ist. Meistens ist hier ein umweg über ein Perl Script notwendig.

Meine Idee war es die MySQL Daten in eine QTableView zu packen und dann die Daten einfach von der QTable in das SQLite File zu schreiben. Beides über die QSqlDatabase Klasse. Zum erstellen der Daten im QTabelView würde ich die QMYSQL Treiber verwenden und zum schreiben von der QTableView in das *.db3 File würde ich die QSQLITE Treiber verwenden.

Geht das so? oder gibts einen einfacheren Weg?

Verfasst: 4. März 2008 13:42
von RHBaum
Also willst du doch online abgleichen .... ?

Warum dann der weg ueber das view ?

einfach daten von der einen connection (mysql) holen, und mit den daten in der anderen connection(sqlite) vergleichen, und bei bedarf updaten ...

Dazu kann man gut die sqlklassen von qt verwenden ...
aber programmieren musst die logic schon selber, wobei man da viel recht generisch halten könnte ...

Ciao ...

Verfasst: 4. März 2008 16:38
von pfusterschmied
Tut mir leid wenn ich mich undeutlich ausdrücke.

Ich habe mir nun folgende Lösung ausgedacht:
  • - Die Daten der SQLite können nicht verändert werden.
    - Sobald eine Verbindung aufgebaut werden kann sollen die Daten abgeholt werden.
    - Ich erstelle dazu zwei Verbindungen.
    - Lese die Daten von der MySQL DB mit QSQLQUERY (SELECT) aus
    - Schreibe die Daten in das SQLite File mit QSQLQUERY (INSERT)
Habe das Ganze nun getestet, leider:
QSqlDatabasePrivate::addDatabase: duplicate connection name 'qt_sql_default_connection', old connection removed.

Wie kann ich zwei Connections aufbauen und dann jeweils ansprechen? Ich habe gegooglet und festgestellt, dass dies mit dem ConnectionName zusammenhängt.

Aber warum funktioniert dies nicht:

QT DOKU :
QSqlDatabase QSqlDatabase::addDatabase ( const QString & type, const QString & connectionName = QLatin1String( defaultConnection ) )

ANGEWENDET:
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL",QLatin1String("test"));

Folgende Fehlermeldung:
QSqlQuery::exec: database not open

Code: Alles auswählen

static bool createConnection()
{
    QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");

	db.setHostName("HOST");
	db.setDatabaseName("DBNAME");
	db.setUserName("USER");
	db.setPassword("PW");

    if (!db.open()) {
        QMessageBox::critical(0, qApp->tr("Verbindung zur Onlinedatenbank fehlgeschlagen!"),
            qApp->trUtf8("Es ist nicht möglich eine Verbindung zur Onlinedatenbank  aufzubauen.\n");
        return false;
    }
	return 1;

}

static bool createConnectionSQLite()
{
     QSqlDatabase db1 = QSqlDatabase::addDatabase("QSQLITE");
     db1.setDatabaseName("emp.db3");
	if (!db1.open()) {
		QMessageBox::warning(0, QObject::tr("Database Error"),
				db1.lastError().text());
		return false;
	}
	return true;

}


Verfasst: 4. März 2008 17:01
von upsala
Und warum funktioniert dies auch nicht:
Weil du es in deinen Code nicht eingebaut hast?

Verfasst: 4. März 2008 17:07
von pfusterschmied
Sorry, steh heute total neben mir:

Dies ist der ursprüngliche Code, hab es so getestet:

Code: Alles auswählen

static bool createConnection() 
{ 
    QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL",QLatin1String("online")); 

   db.setHostName("HOST"); 
   db.setDatabaseName("DBNAME"); 
   db.setUserName("USER"); 
   db.setPassword("PW"); 

    if (!db.open()) { 
        QMessageBox::critical(0, qApp->tr("Verbindung zur Onlinedatenbank fehlgeschlagen!"), 
            qApp->trUtf8("Es ist nicht möglich eine Verbindung zur Onlinedatenbank  aufzubauen.\n"); 
        return false; 
    } 
   return 1; 

} 

static bool createConnectionSQLite() 
{ 
     QSqlDatabase db1 = QSqlDatabase::addDatabase("QSQLITE",QLatin1String("offline")); 
     db1.setDatabaseName("emp.db3"); 
   if (!db1.open()) { 
      QMessageBox::warning(0, QObject::tr("Database Error"), 
            db1.lastError().text()); 
      return false; 
   } 
   return true; 

}

Verfasst: 4. März 2008 17:49
von upsala
Ok, dann raten wir halt weiter:
QSqlQuery::exec: database not open
Welche Datenbank ist nicht geöffnet. Welche Verbindung verwendet deine Query?

Verfasst: 4. März 2008 17:56
von pfusterschmied
Ich habe beide DB Connections getrennt angesehen.
Bei beiden kommt es zu dieser Fehlermeldung, wenn:

Code: Alles auswählen

 QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL",QLatin1String("online"));  // funktioniert nicht

 QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL"); // funktioniert
Aber der ConnectionName hat ja nichts mit der db.setDatabaseName("DBNAME"); zu tun, oder?

Verfasst: 4. März 2008 19:08
von upsala
Wenn du willst, daß man dir hilft, dann mußt du etwas mehr mitarbeiten. (Auch ein tiefer Blick in die Doku würde mal nicht schaden) Das erstellen einer Datenbankverbindung haben wir schon hinter uns, ich habe dich nach deiner QSqlQuery gefragt...

Verfasst: 4. März 2008 20:34
von pfusterschmied
Ahhh...
Jetzt bin ich ja extrem lange auf dem Schlauch gestanden.
Danke upsala für den Tip mit der QSqlQuery.

Nun habe ich es:

Code: Alles auswählen

QSqlDatabase db1 = QSqlDatabase::addDatabase("QSQLITE","offline1");
QSqlQuery myEPTermQuery = QSqlQuery(db1);