hawkmaster: Shellscript anpassen

Hallo zusammen,

Auf Github habe ich ein Shellscript gefunden das eine MySQL DB nach SQLite migriert.

https://gist.github.com/esperlu/943776

Es funktioniert recht gut. Was mir jedoch aufgefallen ist:
Meine DB hat ein paar Unique Constraints. Diese werden nicht richtig umgewandelt.
Es wird nur ein normnaler Index angelegt.

Ich bin jetzt leider kein Shellscript Guru und blicke nur bedingt durch was da passiert.
Ich denke diese Sektion am Ende sucht im exportierten MySQL dump nach dem Vorkommern eines KEY und macht dann ganz unten später ein CREATE INDEX ...

Jetzt wäre es toll, wenn das Script noch unterscheiden könnte zwischen KEY und UNIQUE KEY
Ich blicks leider nicht wie man das IF und match anpassen muss.

Gibt es hier vielleicht einen Experten der das kann?

----------------------------------------------

KEY lines are extracted from the CREATE block and stored in array for later print

in a separate CREATE KEY command. The index name is prefixed by the table name to

avoid a sqlite error for duplicate index name.

/^( KEY|);)/ {
if (prev) print prev
prev=""
if ($0 == ");"){
print
} else {
if ( match( $0, /"[^"]+/ ) ) indexName = substr( $0, RSTART+1, RLENGTH-1 )
if ( match( $0, /([^()]+/ ) ) indexKey = substr( $0, RSTART+1, RLENGTH-1 )
key[tableName]=key[tableName] "CREATE INDEX "" tableName "_" indexName "" ON "" tableName "" (" indexKey ");\n"
}
}

Print all KEY creation lines.

END {
for (table in key) printf key[table]
print "END TRANSACTION;"
}
'
----------------------------------------------

vielen Dank und viele Grüße
hawk

  1. Tach!

    Auf Github habe ich ein Shellscript gefunden das eine MySQL DB nach SQLite migriert.
    https://gist.github.com/esperlu/943776

    Der größte Teil davon ist jedoch awk-Syntax. Dein Problem hat also sehr wenig mit der Shell zu tun.

    Es funktioniert recht gut. Was mir jedoch aufgefallen ist:
    Meine DB hat ein paar Unique Constraints. Diese werden nicht richtig umgewandelt.

    Ich entnehme deinen dortigen Kommentaren, dass du die Erweiterung von multigl bereits gefunden hat. Und die erzeugt bei mir Unique-Indexe, allerdings nicht über CREATE INDEX sondern gleich in der Tabellendefinition, hinter den Feldern.

    dedlfix.

    1. Hallo

      danke dir für deine Hilfe.
      Ja ich habe erst versucht die Version multigl auszuführen aber das läuft bei mir überhaupt nicht durch. Vielleicht liegt es an meiner DB und meinen BigInts?

      Ich bekomme viele dieser Fehler:
      AUTOINCREMENT is only allowed on an INTEGER PRIMARY KEY

      Wenn ich den Output in eine log.txt Datei umleite sehe ich z.b.

      CREATE TABLE "myaccount" (
        "accountid" int(10) NOT NULL PRIMARY KEY AUTOINCREMENT
      ,  "accountno" varchar(255) NOT NULL
      ,  "accountname" varchar(250) DEFAULT NULL
      ,  "accountdescription" varchar(250) DEFAULT NULL
      ,  UNIQUE KEY "account" ("accountno")
      );

      Es wurde also warum auch immer das int(10) nicht nach INTEGER ersetzt. Das UNIQUE KEY am Schluss dürfte ja vermutlich auch nicht mehr drin stehen?

      Und ganz am Schluss sind alle CREATE INDEX so:

      CREATE INDEX "" ON "" ("configdir");
      CREATE INDEX "" ON "" ("departmentid");
      CREATE INDEX "" ON "" ("tabsid");

      Ich verwende daher momentan noch das Ursprungs Script ganz oben das bei mir komischerweise durchläuft ohne Fehler bei der gleichen DB, nur halt ohne die Unique Indexes.

      vielen Dank und viele Grüße
      hawk

      1. Tach!

        Ja ich habe erst versucht die Version multigl auszuführen aber das läuft bei mir überhaupt nicht durch. Vielleicht liegt es an meiner DB und meinen BigInts?

        SQLite akzeptiert BIGINT und andere Integer-Typen-Schreibweisen, setzt das aber für sich selbst alles nach INTEGER um. Es ist also kein generelles Problem, wenn BIGINT oder INT(10) als Typ geschrieben steht.

        Ich bekomme viele dieser Fehler:
        AUTOINCREMENT is only allowed on an INTEGER PRIMARY KEY

        Und das scheint eine Ausnahme in SQLite zu sein. Mit PRIMARY KEY kann das Feld nicht mehr int(10) heißen.

        Wenn ich den Output in eine log.txt Datei umleite sehe ich z.b.
        CREATE TABLE "myaccount" (
        ,  UNIQUE KEY "account" ("accountno")

        Die UNIQUE-Syntax ist auch etwas anders, beispielsweise ohne KEY und einen Namen (hier account) gibt es auch nicht.

        Es wurde also warum auch immer das int(10) nicht nach INTEGER ersetzt. Das UNIQUE KEY am Schluss dürfte ja vermutlich auch nicht mehr drin stehen?

        Ersteres ja. Zweiteres, das UNIQUE darf zwar dort stehen, muss aber anders aussehen.

        Ich verwende daher momentan noch das Ursprungs Script ganz oben das bei mir komischerweise durchläuft ohne Fehler bei der gleichen DB, nur halt ohne die Unique Indexes.

        Weiterhelfen kann ich dir nun nicht weiter, weil ich awk auch nicht kann.

        dedlfix.

        1. Hallo dedlfix,

          Danke dir für die Hilfe.

          Weiterhelfen kann ich dir nun nicht weiter, weil ich awk auch nicht kann.

          Kein Problem. Ich habe es aber glaube ich gefunden.
          in meiner .sh Datei stand der mysqldump mit zusätzlich "--default-character-set=utf8 --compatible=ansi" drin.
          Sobald ich dies rausnehme, rennt das Script und die Erstellung einwandfrei :-)

          Warum dies in diesem Script stört und beim Ursprungs-Script nicht, kann ich auch nicht sagen.

          Danke nochmals.

          vielen Dank und viele Grüße
          hawk

          1. Hallo

            ich bins nochmals.
            Ich habe mir jetzt die erstellte Sqlite DB in einem DB Browser angeschaut. Habe aber doch keine UNIQUE Index festgestellt.

            Wenn ich in der Log Datei nachschaue steht da z.b.:

            CREATE TABLE myaccount (
              accountid integer NOT NULL PRIMARY KEY AUTOINCREMENT
            ,  accountno varchar(255) NOT NULL
            ,  accountname varchar(250) DEFAULT NULL
            ,  accountdescription varchar(250) DEFAULT NULL
            ,  UNIQUE (accountno)
            );

            ist das denn richtig?
            Müsste es denn nicht so aussehen?

            CREATE TABLE myaccount (
              accountid integer NOT NULL PRIMARY KEY AUTOINCREMENT
            ,  accountno varchar(255) UNIQUE NOT NULL
            ,  accountname varchar(250) DEFAULT NULL
            ,  accountdescription varchar(250) DEFAULT NULL
            );

            vielen Dank und viele Grüße
            hawk

            1. Tach!

              in meiner .sh Datei stand der mysqldump mit zusätzlich "--default-character-set=utf8 --compatible=ansi" drin.
              Sobald ich dies rausnehme, rennt das Script und die Erstellung einwandfrei :-)

              Am --default-character-set=utf8 kann es nicht liegen, und das würde ich auch drinlassen. Oder besser gesagt, auf einen für deinen Anwendungsfall passende Kodierung umstellen, wenn du auch Daten ex- und importieren möchtest. Für die Feldnamen ist es egal, die werden ASCII-kompatibel sein.

              Ich habe mir jetzt die erstellte Sqlite DB in einem DB Browser angeschaut. Habe aber doch keine UNIQUE Index festgestellt.

              Ist aber da, in Form der UNIQUE-Zeile:

              ,  UNIQUE (accountno)

              Und so stimmt er auch syntaktisch.

              dedlfix.

              1. Hallo

                Ist aber da, in Form der UNIQUE-Zeile:

                ,  UNIQUE (accountno)

                Und so stimmt er auch syntaktisch.

                ok, dann liegt es vielleicht an meinem SQLite DB Browser das er das nicht richtig darstellen kann. Ich dachte nur es müsste vielleicht unbedingt so heissen:

                accountno varchar(255) NOT NULL UNIQUE

                vielen Dank und viele Grüße
                hawk