Ich würde wie gesagt den Ansatz fahren, dass du dir ein PowerShell Script o.ä. schreibst, in dem du lediglich deine Statements ausgibst und du diese dann einfach mittels
Code:
$ sqlite3 merge.db < merge-script.sql
importieren kannst, in der Hoffnung, dass du irgendwann an dem Punkt bist, an dem alles klappt und beides korrekt gemerged wurde.
Deine DBs
ATTACH
en kannst du mit
SQL:
ATTACH DATABASE 'path/to/your/copy/of/big/database.db' AS "big";
ATTACH DATABASE 'path/to/your/copy/of/small/database.db' as "small";
Tabellen auslesen kannst du mit
SQL:
SELECT * FROM small."sqlite_master" WHERE "type" = 'table' ORDER BY "name";
Die musst du dann in ner Schleife iterieren und auf deine DB schreiben. Also quasi was in der
sql
Spalte steht, wieder ins Script schreiben. Die Trigger sollten dort nicht enthalten sein, das sind separate Queries.
Mit
SQL:
PRAGMA FOREIGN_KEY_CHECKS = 0;
deaktivierst du die Foreign Key Checks, damit du die Daten aus der großen DB einfach rüberziehen kannst.
SQL:
INSERT INTO "merge-tabelle-x"
SELECT * FROM big."alte-tabelle-x";
Weiß nicht ob SQLite das so unterstützt, ggf. musst du die Spalten manuell auflisten... Erledigt ja sowieso das Script.
Die Spalten einer Tabelle kannst du mit
SQL:
PRAGMA big.TABLE_INFO('alte-tabelle-x');
auslesen. Und da auch einfach drüber iterieren und als Quelle für deine Queries verwenden.
FK Checks wieder aktivieren, der große Blob ist durch:
SQL:
PRAGMA FOREIGN_KEY_CHECKS = 1;
Ich weiß jetzt nicht, ob das ggf. die Sequences automatisch erhöht, aber das kannst du mit
SQL:
SELECT * FROM sqlite_sequence;
nachprüfen. Dort sollten dann entsprechende Zahlen stehen, die dem großten Datensatz in jeder Tabelle entsprechen.
Falls nicht, kannst du mit
SQL:
UPDATE sqlite_sequence SET "seq" = 123456789 WHERE "name" = 'tabelle-x';
gegensteuern.
Anschließend gehst du die aktuellen Sequences von oben durch und
UPDATE
st deine kleine DB um die Offsets zu korrigieren, damit keine Kollisionen entstehen.
Das Update sieht dann so aus:
SQL:
UPDATE small.tabelle-x
SET "pk-spalte-tabelle-x" = wert-aus-sequences-von-tabelle-x + 1 + pk-spalte-tabelle-x;
Heißt auf deutsch, die ID des "neuen" Datensatzes ist
Code:
max ID/Sequence-Wert der großen Tabelle
+ 1
+ fortlaufende ID der aktuellen Tabelle
Das dann für jede Tabelle, jeden PK. Wenn die Foreign Key Constraints gesetzt sind und FK Checks aktiviert (sollte sein, siehe oben), sollte nun alles konsistent bleiben.
Wenn alles gesetzt ist, kannst du wieder mit
SQL:
INSERT INTO "merge-tabelle-x"
SELECT * FROM small."alte-tabelle-x";
die Daten aus der kleinen DB in die Merge DB migrieren.
Hier ist jetzt die Frage das Wie. Theoretisch kannst du die FK Checks deaktivieren, da sie zumindest in der alten DB konsistent sein sollten. Theoretisch kann beim Übertragen was schief gehen, deshalb sollten sie hier auch aktiviert sein. Mit aktivierten Checks, musst du aber die Daten so übernehmen, dass FK-Checks nicht fehlschlagen.
Heißt, wenn du eine Messages-Tabelle hast und die sich auf die User-Tabelle referenziert, musst du ergo erst die User-Tabelle übernehmen, da ja sonst die Foreign Keys aus der Message-Tabelle fehlschlagen. Im Script würde man sich fix nen Baum mit Dependencies hochziehen und die Abhängigkeiten auflösen... Theoretisch kann sich die User-Tabelle ja auch noch auf weitere Tabellen referenzieren. Bspw. könnte der Status eines jeden Users irgendwo getrackt sein, d.h. du hättest ne Abhängigkeit von
Code:
Messages -> Users -> UserStates
Die richtige Reihenfolge der Übernahme wäre dann statt v.l.n.r eben v.r.n.l.
Der Einfachheit halber könntest du stattdessen die FK-Checks deaktivieren und einfach ein
SQL:
PRAGMA FOREIGN_KEY_CHECKS = 0;
INSERT INTO "merge-tabelle-x"
SELECT * FROM small."alte-tabelle-x";
PRAGMA_FOREIGN_KEY_CHECKS = 1;
absetzen. Das umgeht zwar das Problem mit den Dependencies, ruft aber eben ggf. genannte Konsistenzprobleme in der Merge DB hervor.
Zum Schluss musst du noch die Trigger in der Merge DB setzen. Auslesen kannst du die mit
SQL:
SELECT * FROM small.sqlite_master WHERE type = 'trigger';
Ich hab hier nirgends welche gesetzt, aber ggf. kannst du einfach wieder die
sql
Spalte nehmen und diese 1:1 auf die Merge DB absetzen.
So viel zur
Theorie...