Czy ktoś zna szybki i łatwy sposób migracji bazy danych SQLite3 do MySQL?
Czy ktoś zna szybki i łatwy sposób migracji bazy danych SQLite3 do MySQL?
Odpowiedzi:
Oto lista konwerterów (nie aktualizowana od 2011 roku):
tzn. możesz to zrobić:
Wygląda na to, że wszyscy zaczynają od kilku wyrażeń greps i perl, a ty dostajesz coś, co działa dla twojego konkretnego zestawu danych, ale nie masz pojęcia, czy dane zostały poprawnie zaimportowane, czy nie. Jestem naprawdę zaskoczony, że nikt nie zbudował solidnej biblioteki, która może konwertować między nimi.
Oto lista WSZYSTKICH różnic w składni SQL, o których wiem między dwoma formatami plików: Linie zaczynające się od:
nie są używane w MySQL
CREATE TABLE/INSERT INTO "table_name"
i MySQLCREATE TABLE/INSERT INTO table_name
INSERT INTO
klauzulINSERT INTO
klauzul't'
a 'f'
dla logicznych, MySQL używa 1
i 0
(prosty regex dla tego może się nie powieść, gdy masz ciąg taki jak: „Ja robię, ty nie” wewnątrz INSERT INTO
)AUTOINCREMENT
, MySQLAUTO_INCREMENT
Oto bardzo prosty, zhakowany skrypt perla, który działa dla mojego zbioru danych i sprawdza, czy nie ma wielu innych warunków, które inne skrypty perla znalazłem w Internecie. Nu gwarantuje, że będzie działać na Twoje dane, ale możesz je zmodyfikować i opublikować 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;
}
}
&& ($line !~ /CREATE UNIQUE INDEX/)
dodaniu && ($line !~ /PRAGMA foreign_keys=OFF/)
* wyrażenie regularne pasujące do tabeli pomija cyfry, czyli zamiast tego $line =~ /INSERT INTO \"([a-z_]*)\"(.*)/
musi być $line =~ /INSERT INTO \"([a-z_1-9]*)\"(.*)/
Nadzieja, że to pomaga w przyszłości czytelnicy
Oto skrypt w języku Python, zbudowany na podstawie odpowiedzi Shalmanese i pomocy Alexa Martelliego z Translating Perl to Python
Tworzę wiki społeczności, więc prosimy o edycję i refaktoryzację, pod warunkiem, że nie psuje funkcji (na szczęście możemy po prostu wycofać) - To jest brzydkie, 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żesz następnie zaimportować do mysql
Uwaga - należy ręcznie dodać ograniczenia klucza obcego, ponieważ narzędzie sqlite ich nie obsługuje
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,
schema_migrations
( version
varchar (255) NOT NULL); INSERT INTO schema_migrations VALUES ( 20100714032840
); INSERT INTO schema_migrations VALUES ('20100714033251'); __
Blobvar
typ danych, znaczniki wsteczne w instrukcji CREATE ...
Prawdopodobnie najszybszym najłatwiejszym sposobem jest użycie polecenia sqlite .dump, w tym przypadku utwórz zrzut przykładowej bazy danych.
sqlite3 sample.db .dump > dump.sql
Następnie możesz (teoretycznie) zaimportować to do bazy danych mysql, w tym przypadku testowej bazy danych na serwerze bazy danych 127.0.0.1, używając root użytkownika.
mysql -p -u root -h 127.0.0.1 test < dump.sql
Mówię teoretycznie, ponieważ istnieje kilka różnic między gramatykami.
W sqlite rozpoczynają się transakcje
BEGIN TRANSACTION;
...
COMMIT;
MySQL używa tylko
BEGIN;
...
COMMIT;
Istnieją inne podobne problemy (wracają do mnie varchary i podwójne cudzysłowy), ale nic nie można znaleźć i zastąpić.
Być może powinieneś zapytać, dlaczego przeprowadzasz migrację, jeśli problemem jest wydajność / rozmiar bazy danych, być może przyjrzyj się ponownemu uruchomieniu schematu, jeśli system przechodzi na bardziej wydajny produkt, może to być idealny czas na planowanie przyszłości twoich danych.
Jeśli używasz Python / Django, jest to dość proste:
utwórz dwie bazy danych w settings.py (jak tutaj https://docs.djangoproject.com/en/1.11/topics/db/multi-db/ )
to po prostu zrób tak:
objlist = ModelObject.objects.using('sqlite').all()
for obj in objlist:
obj.save(using='mysql')
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
Właśnie przeszedłem ten proces i w tym pytaniu jest dużo bardzo dobrej pomocy i informacji, ale odkryłem, że musiałem zebrać różne elementy (plus niektóre z innych pytań / odpowiedzi), aby uzyskać działające rozwiązanie aby pomyślnie migrować.
Jednak nawet po połączeniu istniejących odpowiedzi stwierdziłem, że skrypt Pythona nie działał dla mnie w pełni, ponieważ nie działał tam, gdzie wystąpiło wiele wystąpień boolowskich w INSERT. Zobacz tutaj, dlaczego tak było.
Pomyślałem więc, że opublikuję tutaj scaloną odpowiedź. Uznanie należy się oczywiście tym, którzy przyczynili się gdzie indziej. Ale chciałem coś oddać i zaoszczędzić innym czas.
Skrypt opublikuję poniżej. Ale po pierwsze, oto instrukcje dotyczące konwersji ...
Uruchomiłem skrypt na OS X 10.7.5 Lion. Python działał od razu po wyjęciu z pudełka.
Aby wygenerować plik wejściowy MySQL z istniejącej bazy danych SQLite3, uruchom skrypt na własnych plikach w następujący sposób:
Snips$ sqlite3 original_database.sqlite3 .dump | python ~/scripts/dump_for_mysql.py > dumped_data.sql
Następnie skopiowałem wynikowy plik dumped_sql.sql do systemu Linux 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 w standardzie Unicode (konkretnie pojedyncze cudzysłowy) nie były importowane poprawnie, więc musiałem dodać przełącznik do polecenia, aby określić UTF-8.
Wynikowa komenda wprowadzania danych do nowej, pustej bazy danych MySQL jest następująca:
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 przeanalizować swoich danych przed i po.
Tak, jak wymagał PO, jest to szybkie i łatwe, gdy wiesz jak! :-)
Nawiasem mówiąc, jedną rzeczą, o której nie byłem pewien, zanim przejrzałem tę migrację, było to, czy wartości pola create_at i updated_at zostaną zachowane - dobra wiadomość dla mnie jest taka, że mogę migrować istniejące dane produkcyjne.
Powodzenia!
AKTUALIZACJA
Po dokonaniu tej zmiany zauważyłem problem, którego wcześniej nie zauważyłem. W mojej aplikacji Rails moje pola tekstowe są zdefiniowane jako „ciąg”, co prowadzi do schematu bazy danych. Proces opisany tutaj powoduje, że są one zdefiniowane jako VARCHAR (255) w bazie danych MySQL. Powoduje to ograniczenie liczby znaków do 255 znaków - a wszystko poza tym zostało po cichu obcięte podczas importu. Wydaje mi się, że do obsługi tekstu o długości większej niż 255 schemat MySQL musiałby używać „TEKST” zamiast VARCHAR (255). Zdefiniowany tutaj proces nie obejmuje tej konwersji.
Oto scalony i poprawiony skrypt Pythona, który zadziałał dla moich danych:
#!/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,
Zwykle używam tabel eksport / import cechą IntelliJ DataGrip .
Postęp możesz zobaczyć w prawym dolnym rogu.
[ ]
Niedawno musiałem przeprowadzić migrację z MySQL do JavaDB dla projektu, nad którym pracuje nasz zespół. Znalazłem bibliotekę Java napisaną przez Apache'a o nazwie DdlUtils, która ułatwiła to. Zapewnia interfejs API, który pozwala wykonać następujące czynności:
Narzędzia, z którymi wylądowaliśmy, 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 uruchomienie kilku małych narzędzi do jednorazowej migracji. Myślę, że udało mi się przeprowadzić migrację z mniej niż 150 liniami kodu.
Nie ma potrzeby żadnego skryptu, polecenia itp.
musisz tylko wyeksportować bazę danych sqlite jako .csv
plik, a następnie zaimportować ją do Mysql przy użyciu phpmyadmin.
Użyłem go i zadziałało niesamowicie ...
Oparty na rozwiązaniu Jimsa: Szybki i łatwy sposób migracji SQLite3 na 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 działa dla mnie. Używam sed tylko do rzucenia pierwszej linii, która nie jest podobna do mysql, ale równie dobrze możesz zmodyfikować skrypt dump.py, aby wyrzucić tę linię.
moose@pc08$ sqlite3 mySqliteDatabase.db .dump > myTemporarySQLFile.sql
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
Spowoduje to monit o podanie hasła. Uwaga: jeśli chcesz wprowadzić hasło bezpośrednio, musisz to zrobić BEZ spacji, bezpośrednio po -p
:
mysql -u root -pYOURPASS somedb < myTemporarySQLFile.sql
mysqlimport lub inne narzędzia do importowania, takie jak BigDump .
BigDump daje pasek postępu:
Ha ... Szkoda, że nie znalazłem tego pierwszego! Moja odpowiedź była na ten post ... skrypt do konwersji pliku zrzutu mysql sql do formatu, który można zaimportować do pliku sqlite3 db
Połączenie tych dwóch byłoby dokładnie tym, czego potrzebowałem:
Kiedy baza danych sqlite3 będzie używana z ruby, możesz chcieć to zmienić:
tinyint([0-9]*)
do:
sed 's/ tinyint(1*) / boolean/g ' |
sed 's/ tinyint([0|2-9]*) / integer /g' |
niestety, ta tylko połowa działa, ponieważ chociaż wstawiasz 1 i 0 do pola oznaczonego logicznie, sqlite3 przechowuje je jako 1 i 0, więc musisz przejść przez i zrobić coś takiego:
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 warto było sprawdzić plik sql, aby znaleźć wszystkie wartości logiczne.
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 ciągi jako varchar(300)
, ale wszystko to można dostosować odpowiednio w argumentach konstruktora lub skryptu.
UWAGA: Wymaga MySQL Connector / Python 2.0.4 lub nowszego
Oto link do źródła na GitHub, jeśli poniższy kod jest trudny do odczytania: https://github.com/techouse/sqlite3-to-mysql
#!/usr/bin/env python3
__author__ = "Klemen Tušar"
__email__ = "techouse@gmail.com"
__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()
Ten skrypt jest w porządku, z wyjątkiem tego przypadku, który oczywiście spotkałem:
INSERT INTO „requestcomparison_stopword” VALUES (149, „f”); WSTAWIĆ WARTOŚCI „requestcomparison_stopword” (420, „t”);
Skrypt powinien dać następujące dane wyjściowe:
INSERT INTO requestcomparison_stopword VALUES (149, „f”); WSTAW DO WARTOŚCI requestcomparison_stopword WARTOŚCI (420, „t”);
Ale zamiast tego daje ten wynik:
WSTAW DO WARTOŚCI requestcomparison_stopword WARTOŚCI (1490; WSTAW DO WARTOŚCI requestcomparison_stopword WARTOŚCI (4201;
z niektórymi dziwnymi nie-asciowskimi postaciami w ostatnich 0 i 1.
Nie pojawiło się to już, gdy skomentowałem następujące wiersze 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, gdy chcemy dodać wartość „f” lub „t”, ale nie bardzo mi się podoba wyrażenia regularne, chciałem tylko zauważyć, że ktoś może to poprawić.
W każdym razie wielkie dzięki za ten przydatny skrypt !!!
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 ) );
}
}