Uma forma rápida e fácil de migrar o SQLite3 para o MySQL?

Alguém sabe uma forma rápida e fácil de migrar uma base de dados SQLite3 para o MySQL?

Author: Stephen Cox, 2008-08-20

25 answers

Aqui está uma lista de conversores (não atualizados desde 2011):


Um método alternativo que funcionaria bem, mas raramente é mencionado é: use uma classe ORM que abstrai diferenças específicas de banco de dados para você. por exemplo, obtém-se isto em PHP ([14]}RedBean ), Python( camada ORM do Django, Storm, SQLAlchemy ), Ruby on Rails (ActiveRecord), Cacau (CoreData) Ou seja, podias fazer isto.
  1. Carregar dados a partir da base de dados de origem usando a classe ORM.
  2. armazenar dados na memória ou serializar para o disco.
  3. armazenar dados na base de dados de destino usando a classe ORM.
 52
Author: David d C e Freitas, 2016-08-27 04:49:54

Todos parecem começar com alguns greps e expressões perl e você meio que obter algo que funciona para o seu conjunto de dados em particular, mas você não tem idéia se é importado os dados corretamente ou não. Surpreende-me que ninguém tenha construído uma biblioteca sólida que se converta entre os dois.

Aqui uma lista de todas as diferenças na sintaxe SQL que eu conheço entre os dois formatos de arquivo: As linhas que começam por:

    Comecem. Transacção
  • compromisso
  • sqlite_sequence
  • CRIAR UM ÍNDICE ÚNICO

Não são utilizados no MySQL

  • O SQLlite usa Criar Tabela/Inserir em "table_name" e o MySQL usa Criar Tabela / Inserir em table_name
  • o MySQL não usa aspas dentro da definição do esquema
  • o MySQL usa aspas únicas para cadeias de caracteres dentro da inserção nas cláusulas
  • O SQLlite e o MySQL têm diferentes formas de escapar de cadeias de caracteres dentro das cláusulas
  • SQLlite Usa ' t 'E' f ' para booleanos, o MySQL usa 1 e 0 (uma simples expressão para isto pode falhar quando você tem um texto como: 'eu faço, você não faz' T ' dentro do seu item em)
  • O SQLLite usa AUTOINCREMENT, o MySQL usa AUTO_INCREMENT

Aqui está um script muito básico hackeado perl que funciona para o meu conjunto de dados e verifica muitas mais destas condições que outros scripts perl que encontrei na web. Nu guarentees que vai funcionar para os seus dados, mas sinta-se à vontade para modificar e postar de volta aqui.

#! /usr/bin/perl

while ($line = <>){
    if (($line !~  /BEGIN TRANSACTION/) && ($line !~ /COMMIT/) && ($line !~ /sqlite_sequence/) && ($line !~ /CREATE UNIQUE INDEX/)){

        if ($line =~ /CREATE TABLE \"([a-z_]*)\"(.*)/){
            $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_]*)\"(.*)/){
            $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;
    }
}
 96
Author: Shalmanese, 2008-09-17 20:49:49
Aqui está um script em python, construído a partir da resposta de Shalmanese e alguma ajuda de Alex martelli na tradução de Perl para Python

Estou a torná-lo wiki comunitário, por isso, por favor, sinta - se livre para editar, e refactor, desde que não quebre a funcionalidade (felizmente podemos apenas voltar para trás) - é muito feio, mas funciona

Usar assim (assumindo que o programa se chama dump_for_mysql.py:

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

Que depois podes importar para o mysql

As restrições de teclas são feitas manualmente, dado que o sqlite não as Suporta de facto

Aqui está o guião:

#!/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,
 46
Author: Jiaaro, 2017-05-23 11:47:28
É confuso porque os ficheiros de lixo são específicos do Fornecedor de bases de dados.

Se estiver a usar Carris, existe um grande plugin para isto. Deve ler-se: http://blog.heroku.com/archives/2007/11/23/yamldb_for_databaseindependent_data_dumps/

Actualizar

Garfo actualmente mantido: https://github.com/ludicast/yaml_db

 22
Author: ryw, 2013-06-17 20:47:05
Surpreende-me que ainda ninguém tenha mencionado isto, mas há uma ferramenta explícita para isto. Está em perl, SQL:Tradutor: http://sqlfairy.sourceforge.net/

Converte entre a maioria das formas de dados tabulares (diferentes formatos de SQL, planilha de Excel), e até faz diagramas do seu esquema de SQL.

 7
Author: pdxleif, 2011-01-19 11:32:17
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
 7
Author: Dashamir Hoxha, 2011-10-12 22:07:08

Acabei de passar por este processo, e há muita ajuda e informação muito boa neste Q/A, Mas eu descobri que tive que reunir vários elementos (mais alguns de outros Q/As) para obter uma solução de trabalho, a fim de migrar com sucesso.

No entanto, mesmo depois de combinar as respostas existentes, descobri que o script de Python não funcionava totalmente para mim, pois não funcionava onde havia múltiplas ocorrências booleanas numa sequência inserida. Veja aqui por que isso foi o caso.

Então, pensei em Publicar a minha resposta fundida aqui. O crédito vai para aqueles que contribuíram em outros lugares, é claro. Mas eu queria dar algo de volta, e poupar tempo aos outros que se seguem. Vou pôr o guião em baixo. Mas primeiro, Aqui estão as instruções para uma conversão... Passei o guião no OS X 10.7.5 Lion. O Python trabalhou na caixa.

Para gerar o ficheiro de entrada do MySQL a partir da sua base de dados SQLite3 existente, execute o programa nos seus próprios ficheiros como segue,

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

Depois copiei o resultado do dumped_ SQL.o ficheiro sql passou para uma caixa Linux a correr o Ubuntu 10.04.4 LTS, onde a minha base de dados MySQL deveria residir.

Outro problema que tive ao importar o ficheiro MySQL foi que alguns caracteres Unicode UTF-8 (especificamente aspas simples) não estavam a ser importados correctamente, por isso tive de adicionar uma mudança ao comando para indicar UTF-8.

O comando resultante para introduzir os dados numa nova base de dados MySQL vazia é como

Snips$ mysql -p -u root -h 127.0.0.1 test_import --default-character-set=utf8 < dumped_data.sql
Que cozinhe, e deve ser isso! Não se esqueça de examinar os seus dados, antes e depois. Então, como a operação pediu, é rápido e fácil, quando você sabe como! :-)

Como um aparte, uma coisa que eu não tinha certeza antes de olhar para esta migração, era se os valores de campo created_at e updated_at seriam preservados-a boa notícia para mim é que eles são, para que eu pudesse migrar meus dados de produção existentes.

Ainda bem. sorte!

actualizar

Desde que fiz esta troca, notei um problema que não tinha reparado antes. Na minha aplicação de Rails, os meus campos de texto são definidos como' string', e isto passa para o esquema de base de dados. O processo descrito aqui resulta em que estes são definidos como VARCHAR (255) no banco de dados MySQL. Isso coloca um limite de 255 caracteres nestes tamanhos de campo-e qualquer coisa além disso foi silenciosamente truncada durante a importação. Para suportar maior tamanho do texto ao invés de 255, o esquema MySQL precisaria usar 'texto' ao invés de VARCHAR(255), eu acredito. O processo aqui definido não inclui esta conversão.

Aqui está o script de Python mesclado e revisto que funcionou para os meus dados:

#!/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,
 7
Author: Snips, 2017-05-23 12:02:48
Recentemente tive de migrar de MySQL para JavaDB para um projecto em que a nossa equipa está a trabalhar. Encontrei uma biblioteca Java escrita pelo Apache chamada DdlUtils que tornou isto muito fácil. Ele fornece uma API que lhe permite fazer o seguinte:
  1. Descubra o esquema de uma base de dados e exporte-o como um ficheiro XML.
  2. modificar um DB com base neste esquema.
  3. importar registos de um DB para outro, assumindo que têm o mesmo esquema.
As ferramentas que acabámos não eram completamente automatizados, mas funcionavam muito bem. Mesmo que sua aplicação não esteja em Java, não deve ser muito difícil criar algumas pequenas ferramentas para fazer uma migração única. Acho que consegui retirar a nossa migração com menos de 150 linhas de código.
 5
Author: Outlaw Programmer, 2008-08-21 03:12:51

Provavelmente a maneira mais fácil é usar o sqlite .comando dump, neste caso crie um dump da base de dados de amostras.

sqlite3 sample.db .dump > dump.sql

Você pode então (em teoria) importar isto para a base de dados mysql, neste caso a base de dados de teste no servidor de base de dados 127.0.0.1, usando a raiz do utilizador.

mysql -p -u root -h 127.0.0.1 test < dump.sql
Em teoria, digo que existem algumas diferenças entre as gramáticas.

Nas transacções sqlite começam

BEGIN TRANSACTION;
...
COMMIT;

O MySQL usa apenas

BEGIN;
...
COMMIT;

Existem outros semelhantes problemas (varchars e aspas duplas vêm de volta à mente), mas nada encontrar e substituir não poderia corrigir.

Talvez você deva perguntar Por que você está migrando, se o desempenho/ tamanho da base de dados é o problema talvez olhe para reoginar o esquema, se o sistema está se movendo para um produto mais poderoso este pode ser o momento ideal para planejar para o futuro de seus dados.

 5
Author: Richard Gourlay, 2008-08-25 11:10:04

Obter uma lixeira SQL

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

Importar o 'dump' para o MySQL

Para pequenas importações:

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

Ou

mysql -u root -p somedb < myTemporarySQLFile.sql
Isto vai pedir-lhe uma senha. Por favor, note: Se você quiser digitar sua senha diretamente, você tem que fazê-lo sem espaço, logo após -p:
mysql -u root -pYOURPASS somedb < myTemporarySQLFile.sql

Para lixeiras maiores:

Mysqlimport ou outras ferramentas de importação comoBigDump .

O BigDump dá-te uma barra de progresso:

enter image description here

 5
Author: Martin Thoma, 2013-06-22 11:36:51

Se está a usar Python / Django é muito fácil:

Criar duas bases de dados em settings.py (como aqui https://docs.djangoproject.com/en/1.11/topics/db/multi-db/) Então faz assim:
objlist = ModelObject.objects.using('sqlite').all()

for obj in objlist:
    obj.save(using='mysql')
 5
Author: Mihkorz, 2017-07-12 15:32:34

O MySQL Workbench (licença GPL) migra muito facilmente do SQLite através do Assistente de migração de bases de dados . Installs on Windows, Ubuntu, RHEL,Fedora e OS X .

 4
Author: Patrick Garner, 2017-05-15 15:21:11

O programa em python funcionou após algumas modificações como se segue:

# Remove "PRAGMA foreign_keys=OFF; from beginning of script
# Double quotes were not removed from INSERT INTO "BaselineInfo" table, check if removed from subsequent tables.  Regex needed A-Z added.
# Removed backticks from CREATE TABLE
# Added replace AUTOINCREMENT with AUTO_INCREMENT
# Removed replacement,
#line = line.replace('"', '`').replace("'", '`')

...

useless_es = [
    'BEGIN TRANSACTION',
    'COMMIT',
    'sqlite_sequence',
    'CREATE UNIQUE INDEX',
    'PRAGMA foreign_keys=OFF',
    ]

...

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('"', "'")

...

 3
Author: Doreen Yen, 2015-05-07 12:16:18

Eu uso o carregador de dados para migrar quase todos os dados, ele me ajuda a converter MSSQL para MYSQL, MS access para MSSQL, mysql, csv loader, foxpro e MSSQL para MS access, MYSQl, CSV, foxpro etc. Na minha opinião, esta é a melhor ferramenta de migração de dados

Telecarregamento gratuito: http://www.dbload.com

 2
Author: , 2009-08-25 09:12:31
Baseado na solução do Jims: Uma forma rápida e fácil de migrar o SQLite3 para o 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  
Isto funciona comigo. Eu uso sed apenas para lançar a primeira linha, que não é mysql-like, mas você pode muito bem modificar dump.py um guião para deitar esta linha fora.
 2
Author: alekwisnia, 2017-05-23 12:02:48
Ha... Quem me dera ter encontrado isto primeiro! A minha resposta foi a este post... programa para converter o ficheiro sql dump do mysql num formato que pode ser importado para o sqlite3 db Combinar os dois seria exactamente o que eu precisava.

Quando a base de dados sqlite3 for usada com o ruby, poderá querer alterar:

tinyint([0-9]*) 

To:

sed 's/ tinyint(1*) / boolean/g ' |
sed 's/ tinyint([0|2-9]*) / integer /g' |
Infelizmente, esta só metade funciona porque mesmo que estejas a inserir 1 e 0 num campo marcado booleano, o sqlite3 armazena eles como 1 e 0, então você tem que passar e fazer algo como:
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)
Mas foi útil ter o ficheiro sql para procurar todos os booleanos.
 1
Author: daicoden, 2017-05-23 12:26:27

O Fallino identificou correctamente a localização do erro no script. Eu tenho a solução. O problema são as seguintes linhas:

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')

O padrão de substituição (segundo parâmetro)no re.sub calls é uma string" regular", então em vez de \1 expandindo para a primeira correspondência regexp, expande-se para um 0x01 literal. Da mesma forma, \2 expande para 0x02. Por exemplo, uma linha contendo: , "t", "f", seria substituído por: 10
(Primeira alteração de substituição, "t", para 1 Segundas variações de substituição "f", para 0)

A solução é alterar as sequências de substituição adicionando um prefixo 'r', ou escapando ao \1 e \2 na cadeia existente. Uma vez que a manipulação fácil das cadeias de expressão regular é para que servem as cadeias de caracteres raw, aqui está a correcção usando as seguintes:

line = re.sub(r"([^'])'t'(.)", r"\1THIS_IS_TRUE\2", line)
line = line.replace('THIS_IS_TRUE', '1')
line = re.sub(r"([^'])'f'(.)", r"\1THIS_IS_FALSE\2", line)
line = line.replace('THIS_IS_FALSE', '0')
 1
Author: mxbraun, 2012-11-13 12:17:57
Este software da caixa funciona para mim. tenta e avisa os outros.

Https://dbconvert.com/sqlite/mysql/

Além disso:

Tive de fazer uma pequena alteração: de alguma forma, a auto_increment de um campo (um campo encontrado a partir da mensagem de erro) não estava activa. Então em phpmyadmin eu verifico a propriedade A_I deste campo e ele funciona completamente. Espero que ajude.

Dunn.
 1
Author: Dung, 2015-07-23 04:12:23

Não há necessidade de nenhum script,comando,etc...

Só tem de exportar a sua base de dados sqlite como um ficheiro .csv e depois importá-la no Mysql usando o phpmyadmin.

Usei-o e funcionou lindamente...
 1
Author: NavidIvanian, 2016-07-16 18:54:15
Este guião está bem, excepto neste caso que, claro, já conheci.
INSERT INTO "requestcomparison_stopword" VALUES(149,'f');
INSERT INTO "requestcomparison_stopword" VALUES(420,'t');

O programa deve dar este resultado:

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

Mas em vez disso dá essa saída:

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

Com alguns estranhos caracteres não-ascii em torno dos últimos 0 e 1.

Isto já não apareceu quando comentei as seguintes linhas do Código (43-46), mas outros problemas apareceram:


    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')
Este é apenas um caso especial, quando queremos adicionar um valor sendo " f " ou " t " mas Não me sinto confortável com expressões regulares, só queria que este caso fosse corrigido por alguém. De qualquer forma, muito obrigado por esse guião prático !!!
 0
Author: , 2009-09-30 14:50:54
Esta solução simples funcionou comigo.
<?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, 2015-11-19 06:41:00

Tirei o script Python de https://stackoverflow.com/a/32243979/746459 (acima) e corrigi-lo para lidar com os nossos próprios esquemas sqlite. Havia alguns problemas para resolver.

Você pode encontrá-lo no controle de origem aqui: https://bitbucket.org/mjogltd/sqlite3mysql

Também está disponível a mesma coisa embrulhada como uma imagem do acoplador, aqui: https://hub.docker.com/r/mjog/sqlite3mysql/ - é totalmente utilizável mesmo sob um ambiente de trabalho do Windows.

 0
Author: jmkgreen, 2017-05-23 11:54:59

Escrevi este guião simples em Python3. Ele pode ser usado como uma classe incluída ou script autônomo invocado através de uma consola terminal. Por padrão, importa todos os inteiros como int(11) e strings como varchar(300), mas tudo o que pode ser ajustado nos argumentos do construtor ou script, respectivamente.

Nota: necessita do conector MySQL / Python 2.0.4 ou superior

Aqui está um link para a fonte no GitHub se você encontrar o código abaixo difícil de ler: https://github.com/techouse/sqlite3-to-mysql/blob/master/sqlite3mysql.py

#!/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()
 0
Author: techouse, 2018-06-08 18:18:50

Eu verifiquei cuidadosamente todas as respostas neste post, assim como as respostas em outro post relacionado traduzindo Perl para Python . No entanto, nenhum conseguiu resolver completamente o meu problema.

O meu cenário é que preciso de migrar uma base de dados de Trac do SQLite para o MySQL, e a base de dados contém muitos conteúdos wiki baseados em tecnologia. Portanto, dentro dos valores de INSERT INTO, pode haver declarações SQL como CREATE TABLE e AUTOINCREMENT. Mas a substituição linha a linha pode ter substituições erradas. la. Finalmente escrevi a minha própria ferramenta para este fim.

Https://github.com/motherapp/sqlite_sql_parser

A utilização é relativamente simples:

python parse_sqlite_sql.py export.sql

Dois ficheiros seriam gerados: export.sql.schema.sql e export.sql.data.sql. Um para o esquema DB actualizado e o outro para os dados DB actualizados.

Pode-se fazer mais modificações manuais no ficheiro DB schema usando qualquer editor de texto, sem se preocupar em Alterar o conteúdo.

Espero que sim. ajuda os outros no futuro.
 -1
Author: Walty Yeung, 2017-05-23 11:47:28
echo ".dump" | sqlite3 /tmp/db.sqlite > db.sql

Cuidado para criar declarações

 -5
Author: mgribov, 2012-10-26 10:12:06