Szybki łatwy sposób na migrację SQLite3 do MySQL? [zamknięte]

zamknięte . To pytanie musi być bardziej skoncentrowane . Obecnie nie przyjmuje odpowiedzi.

chcesz poprawić to pytanie? Update the question so it edytując ten post.

Zamknięte 12 miesięcy temu .

Popraw to pytanie

Ktoś zna szybki, łatwy sposób na migrację bazy danych SQLite3 do MySQL?

Author: Stephen Cox, 2008-08-20

17 answers

Oto lista konwerterów (nie aktualizowana od 2011 roku):


Alternatywną metodą, która działa ładnie, ale rzadko jest wymieniana, jest: Użyj klasy ORM, która abstrakuje określone różnice w bazie danych. np. dostajesz je w PHP (RedBean ), Python (warstwa ORM Django, Storm, SqlAlchemy ), Ruby on Rails (ActiveRecord ), Cocoa ( CoreData )

Czyli możesz to zrobić:

  1. załaduj dane ze źródłowej bazy danych za pomocą klasy ORM.
  2. Przechowuj dane w pamięci lub serializuj na dysk.
  3. przechowuje dane do docelowej bazy danych przy użyciu klasy ORM.
 63
Author: David d C e Freitas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-08-15 15:35:40

Wydaje się, że każdy zaczyna od kilku grepów i wyrażeń Perla, a ty dostajesz coś, co działa dla Twojego konkretnego zbioru danych, ale nie masz pojęcia, czy dane zostały zaimportowane poprawnie, czy nie. Jestem poważnie zaskoczony, że nikt nie zbudował solidnej biblioteki, która może konwertować między nimi.

Oto lista wszystkich różnic w składni SQL, które Wiem o między dwoma formatami plików: Linie zaczynające się od:

  • BEGIN Transakcja
  • COMMIT
  • sqlite_sequence
  • UTWÓRZ UNIKALNY INDEKS

Nie są używane w MySQL

  • SQLite używa CREATE TABLE/INSERT INTO "table_name" i MySQL używa CREATE TABLE/INSERT INTO table_name
  • MySQL nie używa cudzysłowów wewnątrz definicji schematu
  • MySQL używa pojedynczych cudzysłowów do ciągów wewnątrz INSERT INTO klauzul
  • SQLite i MySQL mają różne sposoby ucieczki ciągów wewnątrz INSERT INTO klauzul
  • SQLite używa 't' i 'f' dla booleanów, MySQL używa 1 i 0 (prosty regex do tego może się nie udać, gdy masz ciąg znaków typu: 'I do, you don' inside your INSERT INTO)
  • SQL używa AUTOINCREMENT, MySQL używa AUTO_INCREMENT

Oto bardzo podstawowy, zhakowany skrypt Perla, który działa dla mojego zbioru danych i sprawdza wiele innych warunków, które Inne skrypty Perla znalazłem w sieci. Nu gwarantuje, że będzie działać na Twoje dane, ale nie krępuj się modyfikować i publikować tutaj.

#! /usr/bin/perl

while ($line = <>){
    if (($line !~  /BEGIN TRANSACTION/) && ($line !~ /COMMIT/) && ($line !~ /sqlite_sequence/) && ($line !~ /CREATE UNIQUE INDEX/)){
        
        if ($line =~ /CREATE TABLE \"([a-z_]*)\"(.*)/i){
            $name = $1;
            $sub = $2;
            $sub =~ s/\"//g;
            $line = "DROP TABLE IF EXISTS $name;\nCREATE TABLE IF NOT EXISTS $name$sub\n";
        }
        elsif ($line =~ /INSERT INTO \"([a-z_]*)\"(.*)/i){
            $line = "INSERT INTO $1$2\n";
            $line =~ s/\"/\\\"/g;
            $line =~ s/\"/\'/g;
        }else{
            $line =~ s/\'\'/\\\'/g;
        }
        $line =~ s/([^\\'])\'t\'(.)/$1THIS_IS_TRUE$2/g;
        $line =~ s/THIS_IS_TRUE/1/g;
        $line =~ s/([^\\'])\'f\'(.)/$1THIS_IS_FALSE$2/g;
        $line =~ s/THIS_IS_FALSE/0/g;
        $line =~ s/AUTOINCREMENT/AUTO_INCREMENT/g;
        print $line;
    }
}
 113
Author: Shalmanese,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-08-25 08:15:42

Oto skrypt Pythona, zbudowany na podstawie odpowiedzi Shalmanese ' a i pomocy Alexa martellego z tłumaczącego Perla na Python

Robię to wiki społeczności, więc proszę, nie krępuj się edytować, i refactor tak długo, jak to nie łamie funkcjonalności (na szczęście możemy po prostu cofnąć) - jest dość brzydki, ale działa

Użyj Tak (Zakładając, że skrypt nazywa się dump_for_mysql.py:

sqlite3 sample.db .dump | python dump_for_mysql.py > dump.sql

Które można następnie zaimportować do mysql

Uwaga-musisz dodać klucz obcy constrains manually as SQLite doesn ' t actually support them

Oto skrypt:

#!/usr/bin/env python

import re
import fileinput

def this_line_is_useless(line):
    useless_es = [
        'BEGIN TRANSACTION',
        'COMMIT',
        'sqlite_sequence',
        'CREATE UNIQUE INDEX',
        'PRAGMA foreign_keys=OFF',
    ]
    for useless in useless_es:
        if re.search(useless, line):
            return True

def has_primary_key(line):
    return bool(re.search(r'PRIMARY KEY', line))

searching_for_end = False
for line in fileinput.input():
    if this_line_is_useless(line):
        continue

    # this line was necessary because '');
    # would be converted to \'); which isn't appropriate
    if re.match(r".*, ''\);", line):
        line = re.sub(r"''\);", r'``);', line)

    if re.match(r'^CREATE TABLE.*', line):
        searching_for_end = True

    m = re.search('CREATE TABLE "?(\w*)"?(.*)', line)
    if m:
        name, sub = m.groups()
        line = "DROP TABLE IF EXISTS %(name)s;\nCREATE TABLE IF NOT EXISTS `%(name)s`%(sub)s\n"
        line = line % dict(name=name, sub=sub)
    else:
        m = re.search('INSERT INTO "(\w*)"(.*)', line)
        if m:
            line = 'INSERT INTO %s%s\n' % m.groups()
            line = line.replace('"', r'\"')
            line = line.replace('"', "'")
    line = re.sub(r"([^'])'t'(.)", "\1THIS_IS_TRUE\2", line)
    line = line.replace('THIS_IS_TRUE', '1')
    line = re.sub(r"([^'])'f'(.)", "\1THIS_IS_FALSE\2", line)
    line = line.replace('THIS_IS_FALSE', '0')

    # Add auto_increment if it is not there since sqlite auto_increments ALL
    # primary keys
    if searching_for_end:
        if re.search(r"integer(?:\s+\w+)*\s*PRIMARY KEY(?:\s+\w+)*\s*,", line):
            line = line.replace("PRIMARY KEY", "PRIMARY KEY AUTO_INCREMENT")
        # replace " and ' with ` because mysql doesn't like quotes in CREATE commands 
        if line.find('DEFAULT') == -1:
            line = line.replace(r'"', r'`').replace(r"'", r'`')
        else:
            parts = line.split('DEFAULT')
            parts[0] = parts[0].replace(r'"', r'`').replace(r"'", r'`')
            line = 'DEFAULT'.join(parts)

    # And now we convert it back (see above)
    if re.match(r".*, ``\);", line):
        line = re.sub(r'``\);', r"'');", line)

    if searching_for_end and re.match(r'.*\);', line):
        searching_for_end = False

    if re.match(r"CREATE INDEX", line):
        line = re.sub('"', '`', line)

    if re.match(r"AUTOINCREMENT", line):
        line = re.sub("AUTOINCREMENT", "AUTO_INCREMENT", line)

    print line,
 51
Author: Jiaaro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:47:28

Jeśli używasz Pythona / Django to jest całkiem proste:

Tworzenie dwóch baz danych w settings.py (jak tutaj https://docs.djangoproject.com/en/1.11/topics/db/multi-db/)

Więc zrób tak:

objlist = ModelObject.objects.using('sqlite').all()

for obj in objlist:
    obj.save(using='mysql')
 13
Author: Mihkorz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-12 15:32:34

Zazwyczaj używam tabele eksportu/importu funkcji IntelliJ DataGrip .

Krok 1Krok 2Krok 3

Możesz zobaczyć postęp w prawym dolnym rogu.

[Tutaj wpisz opis obrazka]

 13
Author: Vincent Sit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-16 16:33:01

Prawdopodobnie najprostszym sposobem jest użycie sqlite .polecenie dump, w tym przypadku utwórz zrzut przykładowej bazy danych.

sqlite3 sample.db .dump > dump.sql

Można następnie (teoretycznie) zaimportować to do bazy danych mysql, w tym przypadku testowej bazy danych na serwerze bazy danych 127.0.0.1, używając user root.

mysql -p -u root -h 127.0.0.1 test < dump.sql

Mówię teoretycznie, ponieważ istnieje kilka różnic między gramatykami.

In SQLite transactions begin

BEGIN TRANSACTION;
...
COMMIT;

MySQL używa tylko

BEGIN;
...
COMMIT;

Istnieją inne podobne problemy (varchary i podwójne cudzysłowy wracają do głowy) ale nic nie można znaleźć i zastąpić.

Być może powinieneś zapytać, dlaczego migrujesz, jeśli wydajność / rozmiar bazy danych jest problemem, być może spójrz na reoginizację schematu, jeśli system przenosi się do bardziej wydajnego produktu, może to być idealny czas, aby zaplanować przyszłość Twoich danych.

 11
Author: Richard Gourlay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-25 11:10:04

Właśnie przeszedłem przez ten proces i jest wiele bardzo dobrej pomocy i informacji w tym Q/ A, ale okazało się, że musiałem połączyć różne elementy (plus niektóre z innych Q/A), aby uzyskać działające rozwiązanie w celu pomyślnej migracji.

Jednak, nawet po połączeniu istniejących odpowiedzi, okazało się, że skrypt Pythona nie działa w pełni dla mnie, ponieważ nie działa tam, gdzie było wiele wystąpień logicznych w INSERT. Zobacz tutaj Dlaczego to było case.

Więc pomyślałem, że zamieszczę tutaj moją połączoną odpowiedź. Uznanie należy się oczywiście tym, którzy przyczynili się gdzie indziej. Ale chciałem dać coś z powrotem, i zaoszczędzić innym czas, który nastąpi.

Zamieszczę skrypt poniżej. Ale po pierwsze, oto instrukcje dotyczące konwersji...

Uruchomiłem skrypt na OS X 10.7.5 Lion. Python pracował po wyjęciu z pudełka.

Aby wygenerować plik wejściowy MySQL z istniejącej bazy danych SQLite3, uruchom skrypt na własnych plikach jako follows,

Snips$ sqlite3 original_database.sqlite3 .dump | python ~/scripts/dump_for_mysql.py > dumped_data.sql

Skopiowałem wynikowy dumped_sql.plik sql do Linuksa z systemem Ubuntu 10.04.4 LTS, w którym miała znajdować się moja baza danych MySQL.

Innym problemem, który miałem podczas importowania pliku MySQL było to, że niektóre znaki UTF-8 unicode (konkretnie pojedyncze cudzysłowy) nie były importowane poprawnie, więc musiałem dodać przełącznik do polecenia, aby określić UTF-8.

Wynikowe polecenie wprowadzania danych do nowej pustej bazy danych MySQL jest jak "follows": {]}

Snips$ mysql -p -u root -h 127.0.0.1 test_import --default-character-set=utf8 < dumped_data.sql

Niech gotuje, i to powinno być to! Nie zapomnij sprawdzić swoich danych, przed i po.

Więc, jak zażądał OP, to jest szybkie i łatwe, kiedy wiesz jak! :-)

Na marginesie, jedną rzeczą, której nie byłem pewien, zanim przyjrzałem się tej migracji, było to, czy wartości pól created_at i updated_at zostaną zachowane - dobra wiadomość dla mnie jest taka, że tak jest, więc mogę przenieść moje istniejące dane produkcyjne.

Dobrze szczęście!

UPDATE

Odkąd zrobiłem ten przełącznik, zauważyłem problem, którego wcześniej nie zauważyłem. W mojej aplikacji Rails moje pola tekstowe są zdefiniowane jako 'string', co przenosi się do schematu bazy danych. Opisane tu procesy powodują, że są one definiowane jako VARCHAR (255) w bazie danych MySQL. Oznacza to limit 255 znaków dla tych rozmiarów pól - a wszystko, co poza tym było cicho obcinane podczas importu. Obsługa długości tekstu większa niż 255, schemat MySQL musiałby używać 'TEXT' , a nie VARCHAR(255), jak sądzę. Proces zdefiniowany tutaj nie obejmuje tej konwersji.


Oto scalony i Poprawiony skrypt Pythona, który działał na moje dane:

#!/usr/bin/env python

import re
import fileinput

def this_line_is_useless(line):
    useless_es = [
        'BEGIN TRANSACTION',
        'COMMIT',
        'sqlite_sequence',
        'CREATE UNIQUE INDEX',        
        'PRAGMA foreign_keys=OFF'
        ]
    for useless in useless_es:
        if re.search(useless, line):
            return True

def has_primary_key(line):
    return bool(re.search(r'PRIMARY KEY', line))

searching_for_end = False
for line in fileinput.input():
    if this_line_is_useless(line): continue

    # this line was necessary because ''); was getting
    # converted (inappropriately) to \');
    if re.match(r".*, ''\);", line):
        line = re.sub(r"''\);", r'``);', line)

    if re.match(r'^CREATE TABLE.*', line):
        searching_for_end = True

    m = re.search('CREATE TABLE "?([A-Za-z_]*)"?(.*)', line)
    if m:
        name, sub = m.groups()
        line = "DROP TABLE IF EXISTS %(name)s;\nCREATE TABLE IF NOT EXISTS `%(name)s`%(sub)s\n"
        line = line % dict(name=name, sub=sub)
        line = line.replace('AUTOINCREMENT','AUTO_INCREMENT')
        line = line.replace('UNIQUE','')
        line = line.replace('"','')
    else:
        m = re.search('INSERT INTO "([A-Za-z_]*)"(.*)', line)
        if m:
            line = 'INSERT INTO %s%s\n' % m.groups()
            line = line.replace('"', r'\"')
            line = line.replace('"', "'")
            line = re.sub(r"(?<!')'t'(?=.)", r"1", line)
            line = re.sub(r"(?<!')'f'(?=.)", r"0", line)

    # Add auto_increment if it's not there since sqlite auto_increments ALL
    # primary keys
    if searching_for_end:
        if re.search(r"integer(?:\s+\w+)*\s*PRIMARY KEY(?:\s+\w+)*\s*,", line):
            line = line.replace("PRIMARY KEY", "PRIMARY KEY AUTO_INCREMENT")
        # replace " and ' with ` because mysql doesn't like quotes in CREATE commands

    # And now we convert it back (see above)
    if re.match(r".*, ``\);", line):
        line = re.sub(r'``\);', r"'');", line)

    if searching_for_end and re.match(r'.*\);', line):
        searching_for_end = False

    if re.match(r"CREATE INDEX", line):
        line = re.sub('"', '`', line)

    print line,
 9
Author: Snips,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:02:48
aptitude install sqlfairy libdbd-sqlite3-perl

sqlt -f DBI --dsn dbi:SQLite:../.open-tran/ten-sq.db -t MySQL --add-drop-table > mysql-ten-sq.sql
sqlt -f DBI --dsn dbi:SQLite:../.open-tran/ten-sq.db -t Dumper --use-same-auth > sqlite2mysql-dumper.pl
chmod +x sqlite2mysql-dumper.pl
./sqlite2mysql-dumper.pl --help
./sqlite2mysql-dumper.pl --add-truncate --mysql-loadfile > mysql-dump.sql
sed -e 's/LOAD DATA INFILE/LOAD DATA LOCAL INFILE/' -i mysql-dump.sql

echo 'drop database `ten-sq`' | mysql -p -u root
echo 'create database `ten-sq` charset utf8' | mysql -p -u root
mysql -p -u root -D ten-sq < mysql-ten-sq.sql
mysql -p -u root -D ten-sq < mysql-dump.sql
 8
Author: Dashamir Hoxha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-12 22:07:08

Ostatnio musiałem przeprowadzić migrację z MySQL do JavaDB dla projektu, nad którym pracuje nasz zespół. Znalazłem bibliotekę Javy napisaną przez Apache o nazwie DdlUtils, która bardzo to ułatwiła. Dostarcza API, które pozwala wykonać następujące czynności:

  1. Odkryj schemat bazy danych i wyeksportuj go jako plik XML.
  2. zmodyfikuj DB na podstawie tego schematu.
  3. Importuj rekordy z jednego DB do drugiego, zakładając, że mają ten sam schemat.

The tools that we ended up z nie były całkowicie zautomatyzowane, ale działały całkiem dobrze. Nawet jeśli Twoja aplikacja nie jest w Javie, nie powinno być zbyt trudne przygotowanie kilku małych narzędzi do jednorazowej migracji. Myślę, że udało mi się wykonać naszą migrację z mniej niż 150 linijkami kodu.

 5
Author: Outlaw Programmer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-21 03:12:51

Pobierz zrzut SQL

moose@pc08$ sqlite3 mySqliteDatabase.db .dump > myTemporarySQLFile.sql

Import dump do MySQL

Dla małego przywozu:

moose@pc08$ mysql -u <username> -p
Enter password:
....
mysql> use somedb;
Database changed
mysql> source myTemporarySQLFile.sql;

Lub

mysql -u root -p somedb < myTemporarySQLFile.sql

Wyświetli monit o podanie hasła. Uwaga: jeśli chcesz wprowadzić swoje hasło bezpośrednio, musisz zrobić to bez spacji, bezpośrednio po -p:

mysql -u root -pYOURPASS somedb < myTemporarySQLFile.sql

Dla większych wysypisk:

Mysqlimport lub inne narzędzia importu, takie jak BigDump.

BigDump daje Ci pasek postępu:

Tutaj wpisz opis obrazka

 4
Author: Martin Thoma,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-22 11:36:51

Nie ma potrzeby stosowania żadnego skryptu, polecenia itp...

Musisz tylko wyeksportować bazę danych sqlite jako plik .csv, a następnie zaimportować ją do Mysql za pomocą phpmyadmin.

Użyłem go i zadziałało niesamowicie...

 4
Author: NavidIvanian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-16 18:54:15

Na podstawie rozwiązania Jimsa: Szybki łatwy sposób na migrację SQLite3 do MySQL?

sqlite3 your_sql3_database.db .dump | python ./dump.py > your_dump_name.sql
cat your_dump_name.sql | sed '1d' | mysql --user=your_mysql_user --default-character-set=utf8 your_mysql_db -p  
To mi pasuje. Ja używam sed tylko do wrzucenia pierwszej linijki, która nie jest mysql-owska, ale równie dobrze można zmodyfikować dump.py scenariusz do wyrzucenia tej linii.
 3
Author: alekwisnia,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:02:48

Napisałem ten prosty skrypt w Python3. Może być używany jako dołączona klasa lub samodzielny skrypt wywoływany przez powłokę terminala. Domyślnie importuje wszystkie liczby całkowite jako int(11)i łańcuchy jako varchar(300), ale wszystko, co można zmienić odpowiednio w konstruktorze lub argumentach skryptu.

Uwaga: wymaga Złącza MySQL / Python 2.0.4 lub nowszego

Oto link do źródła na Githubie, jeśli znajdziesz poniższy kod trudny do odczytania: https://github.com/techouse/sqlite3-to-mysql

#!/usr/bin/env python3

__author__ = "Klemen Tušar"
__email__ = "[email protected]"
__copyright__ = "GPL"
__version__ = "1.0.1"
__date__ = "2015-09-12"
__status__ = "Production"

import os.path, sqlite3, mysql.connector
from mysql.connector import errorcode


class SQLite3toMySQL:
    """
    Use this class to transfer an SQLite 3 database to MySQL.

    NOTE: Requires MySQL Connector/Python 2.0.4 or higher (https://dev.mysql.com/downloads/connector/python/)
    """
    def __init__(self, **kwargs):
        self._properties = kwargs
        self._sqlite_file = self._properties.get('sqlite_file', None)
        if not os.path.isfile(self._sqlite_file):
            print('SQLite file does not exist!')
            exit(1)
        self._mysql_user = self._properties.get('mysql_user', None)
        if self._mysql_user is None:
            print('Please provide a MySQL user!')
            exit(1)
        self._mysql_password = self._properties.get('mysql_password', None)
        if self._mysql_password is None:
            print('Please provide a MySQL password')
            exit(1)
        self._mysql_database = self._properties.get('mysql_database', 'transfer')
        self._mysql_host = self._properties.get('mysql_host', 'localhost')

        self._mysql_integer_type = self._properties.get('mysql_integer_type', 'int(11)')
        self._mysql_string_type = self._properties.get('mysql_string_type', 'varchar(300)')

        self._sqlite = sqlite3.connect(self._sqlite_file)
        self._sqlite.row_factory = sqlite3.Row
        self._sqlite_cur = self._sqlite.cursor()

        self._mysql = mysql.connector.connect(
            user=self._mysql_user,
            password=self._mysql_password,
            host=self._mysql_host
        )
        self._mysql_cur = self._mysql.cursor(prepared=True)
        try:
            self._mysql.database = self._mysql_database
        except mysql.connector.Error as err:
            if err.errno == errorcode.ER_BAD_DB_ERROR:
                self._create_database()
            else:
                print(err)
                exit(1)

    def _create_database(self):
        try:
            self._mysql_cur.execute("CREATE DATABASE IF NOT EXISTS `{}` DEFAULT CHARACTER SET 'utf8'".format(self._mysql_database))
            self._mysql_cur.close()
            self._mysql.commit()
            self._mysql.database = self._mysql_database
            self._mysql_cur = self._mysql.cursor(prepared=True)
        except mysql.connector.Error as err:
            print('_create_database failed creating databse {}: {}'.format(self._mysql_database, err))
            exit(1)

    def _create_table(self, table_name):
        primary_key = ''
        sql = 'CREATE TABLE IF NOT EXISTS `{}` ( '.format(table_name)
        self._sqlite_cur.execute('PRAGMA table_info("{}")'.format(table_name))
        for row in self._sqlite_cur.fetchall():
            column = dict(row)
            sql += ' `{name}` {type} {notnull} {auto_increment}, '.format(
                name=column['name'],
                type=self._mysql_string_type if column['type'].upper() == 'TEXT' else self._mysql_integer_type,
                notnull='NOT NULL' if column['notnull'] else 'NULL',
                auto_increment='AUTO_INCREMENT' if column['pk'] else ''
            )
            if column['pk']:
                primary_key = column['name']
        sql += ' PRIMARY KEY (`{}`) ) ENGINE = InnoDB CHARACTER SET utf8'.format(primary_key)
        try:
            self._mysql_cur.execute(sql)
            self._mysql.commit()
        except mysql.connector.Error as err:
            print('_create_table failed creating table {}: {}'.format(table_name, err))
            exit(1)

    def transfer(self):
        self._sqlite_cur.execute("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'")
        for row in self._sqlite_cur.fetchall():
            table = dict(row)
            # create the table
            self._create_table(table['name'])
            # populate it
            print('Transferring table {}'.format(table['name']))
            self._sqlite_cur.execute('SELECT * FROM "{}"'.format(table['name']))
            columns = [column[0] for column in self._sqlite_cur.description]
            try:
                self._mysql_cur.executemany("INSERT IGNORE INTO `{table}` ({fields}) VALUES ({placeholders})".format(
                    table=table['name'],
                    fields=('`{}`, ' * len(columns)).rstrip(' ,').format(*columns),
                    placeholders=('%s, ' * len(columns)).rstrip(' ,')
                ), (tuple(data) for data in self._sqlite_cur.fetchall()))
                self._mysql.commit()
            except mysql.connector.Error as err:
                print('_insert_table_data failed inserting data into table {}: {}'.format(table['name'], err))
                exit(1)
        print('Done!')


def main():
    """ For use in standalone terminal form """
    import sys, argparse
    parser = argparse.ArgumentParser()
    parser.add_argument('--sqlite-file', dest='sqlite_file', default=None, help='SQLite3 db file')
    parser.add_argument('--mysql-user', dest='mysql_user', default=None, help='MySQL user')
    parser.add_argument('--mysql-password', dest='mysql_password', default=None, help='MySQL password')
    parser.add_argument('--mysql-database', dest='mysql_database', default=None, help='MySQL host')
    parser.add_argument('--mysql-host', dest='mysql_host', default='localhost', help='MySQL host')
    parser.add_argument('--mysql-integer-type', dest='mysql_integer_type', default='int(11)', help='MySQL default integer field type')
    parser.add_argument('--mysql-string-type', dest='mysql_string_type', default='varchar(300)', help='MySQL default string field type')
    args = parser.parse_args()

    if len(sys.argv) == 1:
        parser.print_help()
        exit(1)

    converter = SQLite3toMySQL(
        sqlite_file=args.sqlite_file,
        mysql_user=args.mysql_user,
        mysql_password=args.mysql_password,
        mysql_database=args.mysql_database,
        mysql_host=args.mysql_host,
        mysql_integer_type=args.mysql_integer_type,
        mysql_string_type=args.mysql_string_type
    )
    converter.transfer()

if __name__ == '__main__':
    main()
 2
Author: Klemen Tusar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-12-21 07:28:58

Ha... Żałuję, że nie znalazłem tego pierwszego! Moja odpowiedź była na ten post... skrypt do konwersji pliku mysql dump sql do formatu, który można zaimportować do sqlite3 db

Połączenie tych dwóch byłoby dokładnie tym, czego potrzebowałem:


Gdy baza danych sqlite3 będzie używana z Rubim, możesz zmienić:

tinyint([0-9]*) 

Do:

sed 's/ tinyint(1*) / boolean/g ' |
sed 's/ tinyint([0|2-9]*) / integer /g' |

Niestety, to tylko połowa działa, ponieważ nawet jeśli wstawiasz 1 i 0 do pola oznaczonego logicznie, sqlite3 przechowuje je jako 1 i 0 więc musisz przejść i zrobić coś w stylu:

Table.find(:all, :conditions => {:column => 1 }).each { |t| t.column = true }.each(&:save)
Table.find(:all, :conditions => {:column => 0 }).each { |t| t.column = false}.each(&:save)

Ale dobrze było mieć plik sql, aby znaleźć wszystkie booleany.

 1
Author: daicoden,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:27

Ten skrypt jest ok z wyjątkiem tego przypadku, który oczywiście spotkałem:

INSERT INTO "requestcomparison_stopword" VALUES(149,'f');
INSERT INTO "requestcomparison_stopword" VALUES(420,'t');

Skrypt powinien dać takie wyjście:

INSERT INTO requestcomparison_stopword VALUES(149,'f');
INSERT INTO requestcomparison_stopword VALUES(420,'t');

Ale daje zamiast tego wyjście:

INSERT INTO requestcomparison_stopword VALUES(1490;
INSERT INTO requestcomparison_stopword VALUES(4201;

Z dziwnymi znakami spoza ascii wokół ostatnich 0 i 1.

To już się nie pojawiło, gdy skomentowałem następujące linijki kodu (43-46), ale pojawiły się inne problemy:


    line = re.sub(r"([^'])'t'(.)", "\1THIS_IS_TRUE\2", line)
    line = line.replace('THIS_IS_TRUE', '1')
    line = re.sub(r"([^'])'f'(.)", "\1THIS_IS_FALSE\2", line)
    line = line.replace('THIS_IS_FALSE', '0')

To tylko szczególny przypadek, kiedy chcemy dodać wartość " f " lub "t", ale jestem niezbyt wygodne z wyrażeniami regularnymi, chciałem tylko zauważyć, że ten przypadek może być przez kogoś poprawiony.

W każdym razie Wielkie dzięki za ten poręczny scenariusz !!!

 0
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-30 14:50:54

To proste rozwiązanie zadziałało dla mnie:

<?php
$sq = new SQLite3( 'sqlite3.db' );

$tables = $sq->query( 'SELECT name FROM sqlite_master WHERE type="table"' );

while ( $table = $tables->fetchArray() ) {
    $table = current( $table );
    $result = $sq->query( sprintf( 'SELECT * FROM %s', $table ) );

    if ( strpos( $table, 'sqlite' ) !== false )
        continue;

    printf( "-- %s\n", $table );
    while ( $row = $result->fetchArray( SQLITE3_ASSOC ) ) {
        $values = array_map( function( $value ) {
            return sprintf( "'%s'", mysql_real_escape_string( $value ) );
        }, array_values( $row ) );
        printf( "INSERT INTO `%s` VALUES( %s );\n", $table, implode( ', ', $values ) );
    }
}
 0
Author: soulseekah,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-19 06:41:00
echo ".dump" | sqlite3 /tmp/db.sqlite > db.sql

Uważaj na Utwórz instrukcje

 -5
Author: mgribov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-26 10:12:06