MySQL के लिए SQLite3 माइग्रेट करने का त्वरित आसान तरीका? [बन्द है]


224

किसी को भी SQLite3 डेटाबेस MySQL में माइग्रेट करने का एक त्वरित आसान तरीका पता है?

जवाबों:


62

यहां कन्वर्टर्स की सूची दी गई है (2011 से अपडेट नहीं):


एक वैकल्पिक विधि जो अच्छी तरह से काम करेगी लेकिन शायद ही कभी उल्लेख किया गया है: एक ORM वर्ग का उपयोग करें जो विशिष्ट डेटाबेस अंतर को आपके लिए दूर कर देता है। जैसे आप PHP ( RedBean ), Python (Django की ORM लेयर, तूफान , SqlAlchemy ), रूबी ऑन रेल्स ( ActiveRecord ), Cocoa ( CoreData ) में इन्हें प्राप्त करते हैं।

यानी आप ऐसा कर सकते हैं:

  1. ORM वर्ग का उपयोग करके स्रोत डेटाबेस से डेटा लोड करें।
  2. मेमोरी में डेटा स्टोर करें या डिस्क पर क्रमबद्ध करें।
  3. ORM वर्ग का उपयोग करके गंतव्य डेटाबेस में डेटा संग्रहीत करें।

107

लगता है कि हर कोई कुछ क्रेप्स और पर्ल एक्सप्रेशंस के साथ शुरुआत करता है और आपको लगता है कि कुछ ऐसा है जो आपके विशेष डेटासेट के लिए काम करता है लेकिन आपको पता नहीं है कि यह डेटा सही तरीके से इम्पोर्ट किया गया है या नहीं। मुझे गंभीरता से आश्चर्य है कि किसी ने भी एक ठोस पुस्तकालय नहीं बनाया है जो दोनों के बीच परिवर्तित हो सके।

यहाँ एसक्यूएल सिंटैक्स में उन सभी अंतरों की सूची दी गई है, जिनके बारे में मुझे दो फ़ाइल स्वरूपों के बीच पता है: इन लाइनों से शुरू:

  • BEGIN परिवहन
  • COMMIT
  • sqlite_sequence
  • अद्वितीय भारत निर्माण

MySQL में उपयोग नहीं किया जाता है

  • SQLlite का उपयोग करता है CREATE TABLE/INSERT INTO "table_name"और MySQL का उपयोग करता हैCREATE TABLE/INSERT INTO table_name
  • MySQL स्कीमा परिभाषा के अंदर उद्धरणों का उपयोग नहीं करता है
  • MySQL INSERT INTOक्लॉज़ के अंदर स्ट्रिंग्स के लिए सिंगल कोट्स का उपयोग करता है
  • SQLlite और MySQL में INSERT INTOक्लॉज़ के अंदर तारों से बचने के अलग-अलग तरीके हैं
  • SQLite का उपयोग करता है 't'और 'f'बूलियन्स के लिए, MySQL का उपयोग करता है 1और 0(इसके लिए एक सरल रेगेक्स तब विफल हो सकता है जब आपके पास एक स्ट्रिंग होती है जैसे: 'मैं करता हूं, आप अपने अंदर' t 'नहीं करते हैं INSERT INTO)
  • SQLLite का उपयोग करता है AUTOINCREMENT, MySQL का उपयोग करता हैAUTO_INCREMENT

यहां एक बहुत ही मूल हैक की गई पर्ल स्क्रिप्ट है जो मेरे डेटासेट के लिए काम करती है और इन स्थितियों में से कई के लिए जांच करती है जो अन्य पर्ल स्क्रिप्ट मुझे वेब पर मिली थीं। एनयू guarentees कि यह आपके डेटा के लिए काम करेगा लेकिन यहां वापस संशोधित और पोस्ट करने के लिए स्वतंत्र महसूस करता है।

#! /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;
    }
}

8
एलेक्स मार्टेली एक महान काम अजगर के रूप में इस पुनर्लेखन से अधिक में किया था stackoverflow.com/questions/1067060/perl-to-python
Jiaaro

मैंने पूरी पाइथन स्क्रिप्ट जोड़ी (अकेले पर्ल स्क्रिप्ट मेरे लिए बहुत काम की नहीं थी ... फॉरेन कीज़ और इंडेक्स को संभालने के लिए कुछ अतिरिक्त प्रोसेसिंग की ज़रूरत थी
जेरो

मैंने इस प्रश्न को अन्य प्रश्न stackoverflow.com/questions/1067060/_/1070463#1070463
ब्रैड गिल्बर्ट

2
COMMIT और CREATE UNIQUE INDEX मान्य MySQL कमांड हैं, कृपया इसे ठीक करें।
न्युटेक

5
मैं समझता हूं कि आपकी स्क्रिप्ट "त्वरित और गंदी" है, लेकिन बहुत उपयोगी भी है, इसलिए यहां कुछ परिवर्धन / बगफिक्स हैं: * && ($line !~ /CREATE UNIQUE INDEX/)जोड़ने के बाद && ($line !~ /PRAGMA foreign_keys=OFF/) * टेबल-नेम-मैचिंग रेग्जेस अंकों को याद करता है, इसके बजाय उम्मीद $line =~ /INSERT INTO \"([a-z_]*)\"(.*)/होनी चाहिए $line =~ /INSERT INTO \"([a-z_1-9]*)\"(.*)/कि यह भविष्य में मदद करता है पाठक
मिशैल लियोन

50

यहाँ एक अजगर लिपि है, जिसे शाल्मनी के उत्तर से बनाया गया है और एलेक्स मार्टेली से कुछ अनुवाद करने के लिए पर्ल से पायथन में मदद की है

मैं इसे सामुदायिक विकी बना रहा हूं, इसलिए कृपया इसे संपादित करने के लिए स्वतंत्र महसूस करें, और जब तक यह कार्यक्षमता नहीं तोड़ता है तब तक रिफ्लेक्टर (शुक्र है कि हम सिर्फ वापस रोल कर सकते हैं) - यह बहुत बदसूरत है लेकिन काम करता है

इस तरह से उपयोग करना (स्क्रिप्ट को कहा जाता है dump_for_mysql.py:

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

जिसे आप mysql में आयात कर सकते हैं

नोट - आपको विदेशी कुंजी अवरोधों को मैन्युअल रूप से जोड़ने की आवश्यकता है क्योंकि sqlite वास्तव में उनका समर्थन नहीं करता है

यहाँ स्क्रिप्ट है:

#!/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,

2
हाय जिम, मेरे डेटासेट पर हर पहले INSERT स्टेटमेंट को एक उद्धरण के बजाय एक बैकक्वॉट द्वारा लपेटा गया है: __ ड्राप टेबल यदि IFIS स्कीमा_migrations; यदि आवश्यक नहीं है तो बनाएँ तालिका schema_migrations( versionvarchar (255) पूर्ण नहीं है); INSERT INTO schema_migrations VALUES ( 20100714032840); INSERT INTO schema_migrations VALUES ('20100714033251'); __
डेविड

अच्छी तरह से ... यह ऊपर नहीं दिखा है, लेकिन बैकल्यूज़ वैल्यूज़ के अंदर दिखाई देता है ([यहां] 20100714032840 [/ HERE])
डेविड

1
मैसूर में AUTOINCREMENT AUTO_INCREMENT है। स्क्रिप्ट का हिसाब नहीं है।
जिउसेप्पे

यह मीडिया विकी डेटाबेस के लिए काम नहीं करता है। कई त्रुटियां: Blobvarडेटा प्रकार,
क्रेट

1
काम नहीं करता है। सभी स्थितियों पर ध्यान नहीं दिया जा सकता है ...
हिमांशु बंसल

10

संभवतः क्विकलाइट .dump कमांड का उपयोग करते हुए त्वरित सबसे आसान तरीका है, इस मामले में नमूना डेटाबेस का एक डंप बनाएं।

sqlite3 sample.db .dump > dump.sql

आप तब (सिद्धांत में) इसे mysql डेटाबेस में आयात कर सकते हैं, इस मामले में डेटाबेस सर्वर 127.0.0.1 पर उपयोगकर्ता रूट का उपयोग करके परीक्षण डेटाबेस।

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

मैं सिद्धांत रूप में कहता हूं कि व्याकरण के बीच कुछ अंतर हैं।

Sqlite में लेनदेन शुरू होता है

BEGIN TRANSACTION;
...
COMMIT;

MySQL सिर्फ उपयोग करता है

BEGIN;
...
COMMIT;

इसी तरह की अन्य समस्याएं हैं (varchars और डबल कोट्स स्प्रिंग बैक टू माइंड) लेकिन कुछ भी नहीं मिला और इसे ठीक नहीं किया जा सका।

शायद आपको यह पूछना चाहिए कि आप क्यों माइग्रेट कर रहे हैं, यदि प्रदर्शन / डेटाबेस का आकार समस्या है तो स्कीमा को फिर से तैयार करना देखें, अगर सिस्टम अधिक शक्तिशाली उत्पाद पर जा रहा है तो यह आपके डेटा के भविष्य की योजना बनाने का आदर्श समय हो सकता है।


2
लेकिन सबसे मुश्किल काम है अंतर betweek व्याकरण
फ्रेंकोइस

9

यदि आप पायथन / Django का उपयोग कर रहे हैं तो यह बहुत आसान है:

सेटिंग्स में दो डेटाबेस बनाएँ। (जैसे https://docs.djangoproject.com/en/1.11/topics/db/multi-db/ )

तो बस इस तरह से करें:

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

for obj in objlist:
    obj.save(using='mysql')

8
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

मैं अभी इस प्रक्रिया से गुज़रा हूं, और इस क्यू / ए में बहुत अच्छी मदद और जानकारी है, लेकिन मैंने पाया कि मुझे विभिन्न तत्वों को एक साथ खींचना है (साथ ही कुछ अन्य क्यू / अस से) एक कार्य समाधान प्राप्त करने के लिए सफलतापूर्वक प्रवास करने का आदेश।

हालाँकि, मौजूदा उत्तरों के संयोजन के बाद भी, मैंने पाया कि पायथन स्क्रिप्ट मेरे लिए पूरी तरह से काम नहीं करती थी क्योंकि यह काम नहीं करती थी जहाँ एक INSERT में कई बूलियन घटनाएं होती थीं। यहाँ देखें कि ऐसा क्यों था।

इसलिए, मैंने सोचा कि मैं अपने विलय का जवाब यहां दूंगा। इसका श्रेय उन लोगों को जाता है, जिन्होंने अन्यत्र योगदान दिया है। लेकिन मैं कुछ वापस देना चाहता था, और दूसरों का समय बचाना चाहता था।

मैं नीचे स्क्रिप्ट लिखूंगा। लेकिन सबसे पहले, यहां रूपांतरण के निर्देश दिए गए हैं ...

मैंने OS X 10.7.5 लॉयन पर स्क्रिप्ट चलाई। अजगर बॉक्स से बाहर काम किया।

अपने मौजूदा SQLite3 डेटाबेस से MySQL इनपुट फ़ाइल जनरेट करने के लिए, निम्नानुसार अपनी फ़ाइलों पर स्क्रिप्ट चलाएँ,

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

मैंने तब परिणामी डंप किए गए_sql.sql फ़ाइल को Ubuntu 10.04.4 LTS पर चलने वाले लिनक्स बॉक्स पर कॉपी किया, जहां मेरा MySQL डेटाबेस निवास करने के लिए था।

MySQL फ़ाइल आयात करते समय मेरे पास एक और मुद्दा यह था कि कुछ यूनिकोड UTF-8 वर्ण (विशेष रूप से एकल उद्धरण) सही ढंग से आयात नहीं किए जा रहे थे, इसलिए मुझे UTF-8 को निर्दिष्ट करने के लिए कमांड में एक स्विच जोड़ना पड़ा।

डेटा को एक नए खाली MySQL डेटाबेस में इनपुट करने के लिए कमांड निम्नानुसार है:

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

इसे पकाने दो, और यह होना चाहिए! पहले और बाद में अपने डेटा की जांच करना न भूलें।

तो, जैसा कि ओपी ने अनुरोध किया है, यह त्वरित और आसान है, जब आप जानते हैं कि कैसे! :-)

एक तरफ के रूप में, एक चीज जो मुझे इस प्रवास में देखने से पहले निश्चित नहीं थी, वह यह थी कि क्या create_at और update_at क्षेत्र मान संरक्षित किए जाएंगे - मेरे लिए अच्छी खबर यह है कि वे हैं, इसलिए मैं अपने मौजूदा उत्पादन डेटा को स्थानांतरित कर सकता हूं।

सौभाग्य!

अपडेट करें

इस स्विच को बनाने के बाद से, मैंने एक समस्या देखी है जो मैंने पहले नहीं देखी थी। मेरे रेल एप्लिकेशन में, मेरे पाठ फ़ील्ड को 'स्ट्रिंग' के रूप में परिभाषित किया गया है, और यह डेटाबेस स्कीमा के माध्यम से किया जाता है। यहां उल्लिखित प्रक्रिया के परिणामस्वरूप MySQL डेटाबेस में VARCHAR (255) के रूप में परिभाषित किया जा रहा है। यह इन क्षेत्र आकारों पर 255 वर्ण की सीमा रखता है - और इससे परे कुछ भी आयात के दौरान चुपचाप काट दिया गया था। पाठ की लंबाई 255 से अधिक का समर्थन करने के लिए, MySQL स्कीमा को VARCHAR (255) के बजाय 'TEXT' का उपयोग करने की आवश्यकता होगी, मुझे विश्वास है। यहां परिभाषित प्रक्रिया में यह रूपांतरण शामिल नहीं है।


यहां मेरे डेटा के लिए काम करने वाले पाइथन स्क्रिप्ट को मर्ज और संशोधित किया गया है:

#!/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,

1
धन्यवाद। वर्तमान में ऊपर लिखी गई स्क्रिप्ट में एक सिंटैक्स त्रुटि है; लाइन 41 पर "और:" उचित इंडेंट स्तर पर नहीं है। यह मेरे लिए स्पष्ट नहीं है कि क्या इसके ऊपर की रेखाओं को इंडेंट किया जाना चाहिए या अगर कुछ और चल रहा है। अद्यतन करने के लिए देखभाल?
डैन तेनबाम


5

मुझे हाल ही में एक प्रोजेक्ट के लिए MySQL से JavaDB तक माइग्रेट करना पड़ा, जिस पर हमारी टीम काम कर रही है। मुझे DdlUtils नाम की अपाचे द्वारा लिखी एक जावा लाइब्रेरी मिली जिसने इसे बहुत आसान बना दिया। यह एक एपीआई प्रदान करता है जिससे आप निम्नलिखित कार्य कर सकते हैं:

  1. डेटाबेस के स्कीमा की खोज करें और इसे XML फ़ाइल के रूप में निर्यात करें।
  2. इस स्कीमा के आधार पर DB को संशोधित करें।
  3. एक DB से दूसरे में रिकॉर्ड आयात करें, यह मानते हुए कि उनके पास एक ही स्कीमा है।

हमारे द्वारा समाप्त किए गए उपकरण पूरी तरह से स्वचालित नहीं थे, लेकिन उन्होंने बहुत अच्छा काम किया। यहां तक ​​कि अगर आपका एप्लिकेशन जावा में नहीं है, तो भी एक बार के माइग्रेशन को करने के लिए कुछ छोटे टूल को व्हिप करना बहुत मुश्किल नहीं होना चाहिए। मुझे लगता है कि मैं कोड की 150 से कम लाइनों के साथ हमारे प्रवासन को खींचने में सक्षम था।


4

किसी भी स्क्रिप्ट, कमांड आदि की कोई आवश्यकता नहीं है ...

आपको केवल एक .csvफ़ाइल के रूप में अपने sqlite डेटाबेस को निर्यात करना होगा और फिर इसे phpmyadmin का उपयोग करके मैसकल में आयात करना होगा।

मैंने इसका इस्तेमाल किया और इसने कमाल का काम किया ...


के साथ संयोजन में इस , यह केवल जवाब यह है कि मेरे लिए काम किया है।
कपट

3

Jims के समाधान के आधार पर: SQLite3 को 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  

यह मेरे लिए काम करता है। मैं पहली पंक्ति को फेंकने के लिए सिर्फ sed का उपयोग करता हूं, जो कि mysql-like नहीं है, लेकिन आप इस पंक्ति को फेंकने के लिए डंपडोम स्क्रिप्ट को संशोधित कर सकते हैं।


1
मेरे पास आयातित डेटा के साथ कुछ UTF-8 एन्कोडिंग मुद्दे थे, लेकिन आयात कमांड में --default-character-set = utf8 को जोड़ने से लगता है कि यह तय हो गया है। इस क्यू / ए से लिया गया: stackoverflow.com/questions/346092/…
स्नैक्स

ठीक है, मैंने इसे जोड़ा है - क्या यह ठीक है?
एलेकविसनिया

यहीं मैं अतिरिक्त स्विच का उपयोग कर रहा हूं, हां।
स्नूज

3

एक SQL डंप प्राप्त करें

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

डंप को MySQL में आयात करें

छोटे आयात के लिए:

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

या

mysql -u root -p somedb < myTemporarySQLFile.sql

यह आपको पासवर्ड के लिए संकेत देगा। कृपया ध्यान दें: यदि आप अपना पासवर्ड सीधे दर्ज करना चाहते हैं, तो आपको इसे बिना स्पेस के, सीधे बाद में करना होगा -p:

mysql -u root -pYOURPASS somedb < myTemporarySQLFile.sql

बड़े डंप के लिए:

mysqlimport या अन्य आयात उपकरण जैसे BigDump

BigDump आपको एक प्रगति बार देता है:

यहां छवि विवरण दर्ज करें


12
Sqlite बनाम mysql में मामूली वाक्यविन्यास अंतर और झंडे के कारण यह काम नहीं करता है। आपको अभी भी इसे मैन्युअल रूप से परिवर्तित करने की आवश्यकता है।
dlite922

1

हा ... काश मुझे यह पहले मिल जाता! मेरी प्रतिक्रिया इस पोस्ट की थी ... स्क्रिप्ट को mysql डंप sql फ़ाइल को उस स्वरूप में परिवर्तित करना है जिसे sqlite3 में आयात किया जा सकता है। db

दो का संयोजन ठीक वैसा ही होगा जैसा मुझे चाहिए था:


जब sqlite3 डेटाबेस माणिक के साथ उपयोग किया जा रहा है, जिसे आप बदलना चाहते हैं:

tinyint([0-9]*) 

सेवा:

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

अफसोस, यह केवल आधा काम करता है क्योंकि भले ही आप बूलियन के रूप में चिह्नित क्षेत्र में 1 और 0 का सम्मिलित कर रहे हों, लेकिन sqlite3 उन्हें 1 और 0 के रूप में संग्रहीत करता है, इसलिए आपको कुछ करना होगा और ऐसा करना होगा:

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)

लेकिन सभी बूलियनों को खोजने के लिए एसक्यूएल फ़ाइल का होना मददगार था।


1

मैंने पायथन 3 में यह सरल स्क्रिप्ट लिखी थी। यह एक टर्मिनल शेल के माध्यम से आह्वान किए गए शामिल वर्ग या स्टैंडअलोन स्क्रिप्ट के रूप में उपयोग किया जा सकता है। डिफ़ॉल्ट रूप से यह सभी पूर्णांकों को आयात करता है int(11)और जैसा कि तार करता हैvarchar(300) , लेकिन सभी को क्रमशः निर्माता या स्क्रिप्ट तर्क में समायोजित किया जा सकता है।

नोट: इसके लिए MySQL कनेक्टर / पायथन 2.0.4 या उच्चतर की आवश्यकता है

यदि आप पढ़ने के लिए कठिन कोड नीचे पाते हैं, तो GitHub पर स्रोत का लिंक यहां दिया गया है: 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()

0

यह स्क्रिप्ट ठीक है इस मामले को छोड़कर, बेशक, मैं मिला हूं:

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

स्क्रिप्ट को यह आउटपुट देना चाहिए:

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

लेकिन इसके बजाय वह आउटपुट देता है:

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

अंतिम 0 और 1 के आस-पास कुछ अजीब गैर-असि अक्षर के साथ।

जब मैंने कोड (43-46) की निम्न पंक्तियों पर टिप्पणी की तो यह और नहीं दिखा, लेकिन अन्य समस्याएं सामने आईं:


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

यह सिर्फ एक विशेष मामला है, जब हम 'एफ' या 'टी' होने के लिए एक मूल्य जोड़ना चाहते हैं, लेकिन मैं नियमित रूप से अभिव्यक्ति के साथ सहज नहीं हूं, मैं सिर्फ इस मामले को किसी के द्वारा सुधारा जाना चाहता था।

वैसे भी उस आसान स्क्रिप्ट के लिए बहुत बहुत धन्यवाद !!!


0

इस सरल समाधान ने मेरे लिए काम किया:

<?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 ) );
    }
}

-5
echo ".dump" | sqlite3 /tmp/db.sqlite > db.sql

बनाएँ बयान के लिए बाहर देखो

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.