Quelqu'un connaît-il un moyen simple et rapide de migrer une base de données SQLite3 vers MySQL ?
Alex Martelli a fait un excellent travail de réécriture en python à l'adresse suivante stackoverflow.com/questions/1067060/perl-to-python
Quelqu'un connaît-il un moyen simple et rapide de migrer une base de données SQLite3 vers MySQL ?
Tout le monde semble commencer avec quelques expressions greps et perl et vous obtenez en quelque sorte quelque chose qui fonctionne pour votre ensemble de données particulier mais vous n'avez aucune idée si cela a importé les données correctement ou non. Je suis sérieusement surpris que personne n'ait construit une bibliothèque solide qui puisse convertir entre les deux.
Voici une liste de TOUTES les différences de syntaxe SQL que je connais entre les deux formats de fichier : Les lignes commençant par :
ne sont pas utilisés dans MySQL
CREATE TABLE/INSERT INTO "table_name"
et MySQL utilise CREATE TABLE/INSERT INTO table_name
INSERT INTO
clausesINSERT INTO
clauses't'
et 'f'
pour les booléens, MySQL utilise 1
et 0
(une simple regex pour cela peut échouer lorsque vous avez une chaîne comme : 'Je le fais, tu ne le fais pas' à l'intérieur de votre INSERT INTO
)AUTOINCREMENT
MySQL utilise AUTO_INCREMENT
Voici un script perl bidouillé très basique qui fonctionne pour mon et vérifie beaucoup plus de ces conditions que d'autres scripts perl que j'ai trouvé sur le web. Je ne garantis pas qu'il fonctionnera pour vos données mais n'hésitez pas à le modifier et à le poster ici.
#! /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;
}
}
Alex Martelli a fait un excellent travail de réécriture en python à l'adresse suivante stackoverflow.com/questions/1067060/perl-to-python
J'ai ajouté le script python complet (le script perl seul ne fonctionnait pas tout à fait pour moi... j'avais besoin d'un traitement supplémentaire pour gérer les clés étrangères et les index).
J'ai réécrit cette réponse sur l'autre question stackoverflow.com/questions/1067060/_/1070463#1070463
Voici une liste de convertisseurs (non mise à jour depuis 2011) :
Une autre méthode qui fonctionnerait bien, mais qui est rarement mentionnée, consiste à utiliser une classe ORM qui fait abstraction des différences entre les bases de données. RedBean ), Python (la couche ORM de Django, Tempête , SqlAlchemy ), Ruby on Rails ( ActiveRecord ), Cacao ( Données de base )
c'est-à-dire que vous pourriez faire ça :
Voici un python script, construit à partir de la réponse de Shalmanese et de l'aide d'Alex martelli à l'adresse suivante Traduire Perl en Python
J'en fais un wiki communautaire, alors n'hésitez pas à le modifier et à le remanier tant qu'il ne casse pas la fonctionnalité (heureusement, nous pouvons simplement revenir en arrière).
utiliser comme suit (en supposant que le script est appelé dump_for_mysql.py
:
sqlite3 sample.db .dump | python dump_for_mysql.py > dump.sql
Que vous pouvez ensuite importer dans mysql
note - vous devez ajouter les contraintes de clé étrangère manuellement car sqlite ne les supporte pas vraiment.
voici le script :
#!/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,
Bonjour Jim, sur mon jeu de données, chaque première instruction INSERT est entourée d'une apostrophe au lieu d'une simple citation : __ DROP TABLE IF EXISTS schema_migrations ; CREATE TABLE IF NOT EXISTS schema_migrations
( version
varchar(255) NOT NULL) ; INSERT INTO schema_migrations VALUES( 20100714032840
) ; INSERT INTO schema_migrations VALUES('20100714033251') ; __.
Eh bien... cela n'apparaît pas ci-dessus, mais les guillemets apparaissent à l'intérieur des VALUES ([HERE]20100714032840[/HERE])
C'est compliqué car les fichiers de vidage sont spécifiques aux fournisseurs de bases de données.
Si vous utilisez Rails, il existe un excellent plugin pour cela. Lire : http://blog.heroku.com/archives/2007/11/23/yamldb_for_databaseindependent_data_dumps/
Fourchette actuellement entretenue : https://github.com/ludicast/yaml_db
Je suis surpris que personne ne l'ait encore mentionné, mais il existe un outil spécialement conçu pour cela. Il est en perl, SQL:Translator : http://sqlfairy.sourceforge.net/
Convertit entre la plupart des formes de données tabulaires (différents formats SQL, feuille de calcul Excel), et réalise même des diagrammes de votre schéma SQL.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.