এসকিউএলটি 3 মাইএসকিউএলে স্থানান্তরিত করার দ্রুত উপায়? [বন্ধ]


224

এসকিউএলআইটি 3 ডাটাবেসকে মাইএসকিউএলে স্থানান্তরিত করার দ্রুত উপায় সহজেই কেউ জানেন?

উত্তর:


62

এখানে রূপান্তরকারীদের একটি তালিকা রয়েছে (২০১১ সাল থেকে আপডেট হয়নি):


একটি বিকল্প পদ্ধতি যা দুর্দান্তভাবে কাজ করবে তবে খুব কমই উল্লেখ করা হয়েছে: একটি ORM বর্গ ব্যবহার করুন যা নির্দিষ্ট ডাটাবেসের পার্থক্যগুলি আপনার জন্য দূরে রাখে। উদাহরণস্বরূপ, আপনি এইগুলি পিএইচপি ( রেডবিয়ান ), পাইথন (জ্যাঙ্গোর ওআরএম স্তর, ঝড় , স্ক্যালএলচেমি ), রুবি অন রেলস ( অ্যাক্টিভেকর্ড ), কোকো ( কোরডেটা ) এ পাবেন

যেমন আপনি এটি করতে পারে:

  1. ORM বর্গ ব্যবহার করে উত্স ডাটাবেস থেকে ডেটা লোড করুন।
  2. মেমরিতে ডেটা সঞ্চয় করুন বা ডিস্কে ক্রমিক করুন।
  3. ORM বর্গ ব্যবহার করে গন্তব্য ডাটাবেসে ডেটা সঞ্চয় করুন।

107

প্রত্যেকের মনে হয় কয়েকটা গ্রেপস এবং পার্ল এক্সপ্রেশন দিয়ে শুরু হয়েছে এবং আপনি আপনার নির্দিষ্ট ডেটাসেটের জন্য কাজ করে এমন কিছু পেয়ে যাচ্ছেন তবে ডেটাটি সঠিকভাবে আমদানি করা হয়েছে কিনা তা আপনার কোনও ধারণা নেই। আমি গুরুতরভাবে অবাক হয়েছি যে কেউই একটি শক্ত লাইব্রেরি তৈরি করেনি যা এই দুজনের মধ্যে রূপান্তর করতে পারে।

এখানে দুটি ফাইল ফরম্যাটের মধ্যে আমি জানতে পারি এসকিউএল সিনট্যাক্সের সমস্ত পার্থক্যের একটি তালিকা: লাইনগুলি শুরু করে:

  • শুরু করুন ট্রান্সেকশন
  • সমর্পণ করা
  • sqlite_sequence
  • অনন্য সূচক তৈরি করুন

মাইএসকিউএল ব্যবহার করা হয় না

  • এসকিউএলাইট ব্যবহার করে CREATE TABLE/INSERT INTO "table_name"এবং মাইএসকিউএল ব্যবহার করেCREATE TABLE/INSERT INTO table_name
  • মাইএসকিউএল স্কিমা সংজ্ঞার ভিতরে কোট ব্যবহার করে না
  • মাইএসকিউএল ভিতরে স্ট্রিং জন্য একক উদ্ধৃতি ব্যবহার INSERT INTOক্লজ
  • SQLlite এবং মাইএসকিউএল ভিতরে স্ট্রিং পলায়নের বিভিন্ন উপায় আছে INSERT INTOক্লজ
  • এসকিউএলাইট ব্যবহার করে 't'এবং 'f'বুলিয়ানগুলির জন্য, মাইএসকিউএল ব্যবহার করে 1এবং 0(যখন আপনার স্ট্রিং থাকে তখন এর জন্য একটি সরল রেজেক্স ব্যর্থ হতে পারে: 'আমি করি, আপনি আপনার ভিতরে থাকবেন না' INSERT INTO)
  • এসকিউএলসাইট ব্যবহার করে AUTOINCREMENT, মাইএসকিউএল ব্যবহার করেAUTO_INCREMENT

এখানে একটি খুব বেসিক হ্যাক আপ পার্ল স্ক্রিপ্ট যা আমার ডেটাসেটের জন্য কাজ করে এবং ওয়েবে পাওয়া অন্যান্য পার্ল স্ক্রিপ্টগুলি এই শর্তগুলির অনেক বেশি পরীক্ষা করে। এখন গ্যারান্টি রয়েছে যে এটি আপনার ডেটার জন্য কাজ করবে তবে সংশোধন করতে এবং এখানে ফিরে পোস্ট করতে নির্দ্বিধায়।

#! /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
অ্যালেক্স martelli একটি মহান পেশা পাইথন হিসাবে এই rewriting উপর এ করেনি stackoverflow.com/questions/1067060/perl-to-python
Jiaaro

আমি সম্পূর্ণ পাইথন স্ক্রিপ্টটি যুক্ত করেছি (পার্ল স্ক্রিপ্টটি একাই আমার পক্ষে বেশিরভাগ ক্ষেত্রে কার্যকর হয়নি ... বিদেশী কীগুলি এবং সূচীগুলি পরিচালনা করতে কিছু অতিরিক্ত প্রক্রিয়াজাতকরণ প্রয়োজন ছিল)
জিয়ারো

আমি এই প্রশ্নের উত্তরটি অন্য প্রশ্নে পুনরায় লিখেছি স্ট্যাকওভারফ্লো. com
ব্র্যাড গিলবার্ট

2
কমিট এবং ক্রিয়েট ইউনিক ইন্ডেক্স হল বৈধ মাইএসকিউএল কমান্ড, দয়া করে এটি ঠিক করুন।
নিউটেচ

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 এ আমদানি করতে পারেন

দ্রষ্টব্য - আপনার স্কেলাইট প্রকৃতপক্ষে সমর্থন করে না বলে আপনাকে ম্যানুয়ালি বিদেশী কী বাধা যুক্ত করতে হবে

লিপিটি এখানে:

#!/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 বিবৃতিটি একটি একক উদ্ধৃতির পরিবর্তে ব্যাককোট দ্বারা মোড়ানো হয়: __ টেবিলটি ড্রপ করুন যদি স্কিমা_মিজারেশন উপস্থিত থাকে; টেবিল তৈরি করুন যদি উপস্থিত না থাকে schema_migrations( বর্ণচর version(255) নকল নয়); অন্তর্নিহিত স্কিমা_মিজারেশন ভ্যালু ( 20100714032840); ইনসার্ট ইন স্কো_মাইগ্রেশন ভ্যালুস ('20100714033251'); __
ডেভিড

ভাল ... এটি উপরে প্রদর্শিত হয় না, তবে ব্যাককোটগুলি ভ্যালুসের ভিতরে উপস্থিত হয় ([এখানে] 20100714032840 [/ এখানে])
ডেভিড

1
মাইএসকিএল-এ স্বতঃসংশ্লিষ্ট হ'ল স্বয়ংক্রিয় নাম। স্ক্রিপ্ট এটির জন্য অ্যাকাউন্ট করে না।
জিউসেপে

এটি মিডিয়া উইকি ডাটাবেসের জন্য কাজ করে না। অনেক ত্রুটি: Blobvarডেটা টাইপ,
ক্রেট

1
কাজ করে না সমস্ত শর্ত বিবেচনায় নেওয়া হবে না ...
হিমাংশু বানসাল

10

সম্ভবত দ্রুততম সহজ উপায় স্ক্লাইট .ডাম্প কমান্ডটি ব্যবহার করা হচ্ছে, সেক্ষেত্রে নমুনা ডাটাবেসের একটি ডাম্প তৈরি করুন।

sqlite3 sample.db .dump > dump.sql

এরপরে আপনি (তত্ত্বের ভিত্তিতে) এটি mysql ডাটাবেসে আমদানি করতে পারেন, এই ক্ষেত্রে ব্যবহারকারী রুট ব্যবহার করে ডাটাবেস সার্ভারে 127.0.0.1 পরীক্ষা ডাটাবেস।

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

আমি তত্ত্বে বলি কারণ ব্যাকরণের মধ্যে কয়েকটি পার্থক্য রয়েছে।

স্ক্লাইট লেনদেন শুরু হয়

BEGIN TRANSACTION;
...
COMMIT;

মাইএসকিউএল স্রেফ ব্যবহার করে

BEGIN;
...
COMMIT;

অন্যান্য অনুরূপ সমস্যা রয়েছে (ভ্যাচার এবং ডাবল কোটগুলি মনে পড়বে) তবে কিছুই খুঁজে পাওয়া যায় না এবং প্রতিস্থাপনও ঠিক করতে পারেনি।

সম্ভবত আপনি কেন স্থানান্তর করছেন তা জিজ্ঞাসা করা উচিত, পারফরম্যান্স / ডাটাবেস আকার যদি সমস্যাটি হয় তবে স্কিমাকে আবার নতুন করে বিবেচনা করা উচিত, যদি সিস্টেমটি আরও শক্তিশালী পণ্যের দিকে চলে যায় তবে এটি আপনার ডেটার ভবিষ্যতের পরিকল্পনা করার জন্য আদর্শ সময় হতে পারে।


2
কিন্তু অধিকাংশ কঠিন কাজ পার্থক্য betweek ব্যাকরণ হল
ফ্রাঁসোয়া

9

আপনি যদি পাইথন / জ্যাঙ্গো ব্যবহার করেন তবে এটি বেশ সহজ:

সেটিংস.পি-তে দুটি ডাটাবেস তৈরি করুন (এখানে https://docs.djangoproject.com/en/1.11/topics/db/m 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

আমি এই প্রক্রিয়াটি সবেমাত্র পেরিয়ে এসেছি এবং এই প্রশ্নোত্তরে অনেকগুলি ভাল সহায়তা এবং তথ্য রয়েছে তবে আমি খুঁজে পেলাম যে একটি কার্যনির্বাহী সমাধান পেতে আমাকে বিভিন্ন উপাদান (আরও কিছু Q / As থেকে কিছু) একসাথে টানতে হয়েছিল I সফলভাবে স্থানান্তর করার আদেশ।

তবে বিদ্যমান উত্তরগুলির সংমিশ্রণের পরেও আমি দেখতে পেলাম পাইথন স্ক্রিপ্টটি পুরোপুরি আমার জন্য কাজ করে নি কারণ এটি যেখানে কাজ করে সেখানে কোনও ইনসার্টে একাধিক বুলিয়ান সংঘটন সেখানে কাজ করে না। কেন ঘটনাটি ছিল তা এখানে দেখুন ।

সুতরাং, আমি ভেবেছিলাম আমি আমার একীভূত উত্তর এখানে পোস্ট করব। অবশ্যই ক্রেডিট যারা অন্য কোথাও অবদান রেখেছে। তবে আমি কিছু ফিরিয়ে দিতে চেয়েছিলাম এবং অন্যদের সেই সময় বাঁচাতে চাই।

আমি নীচে স্ক্রিপ্ট পোস্ট করব। তবে প্রথমত, রূপান্তরকরণের জন্য এখানে নির্দেশাবলী ...

আমি ওএস এক্স 10.7.5 সিংহটিতে স্ক্রিপ্টটি চালিয়েছি। পাইথন বাক্সের বাইরে কাজ করেছিল।

আপনার বিদ্যমান এসকিউএলটি 3 ডাটাবেস থেকে মাইএসকিউএল ইনপুট ফাইলটি তৈরি করতে, নিম্নলিখিত ফাইলগুলিতে আপনার নিজের ফাইলগুলিতে স্ক্রিপ্টটি চালান,

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

তারপরে আমি ডাবডড_এসকিএল.এসকিএল ফাইলটি উবুন্টু 10.04.4 এলটিএস চালিত একটি লিনাক্স বাক্সে অনুলিপি করেছিলাম যেখানে আমার মাইএসকিউএল ডাটাবেসটি থাকবে।

মাইএসকিউএল ফাইলটি আমদানির সময় আমার আরও একটি সমস্যা ছিল যেটি ছিল কিছু ইউনিকোড ইউটিএফ -8 অক্ষর (বিশেষত একক উদ্ধৃতি) সঠিকভাবে আমদানি করা হচ্ছে না, তাই ইউটিএফ -8 নির্দিষ্ট করার জন্য আমাকে কমান্ডটিতে একটি স্যুইচ যুক্ত করতে হয়েছিল।

চমকপ্রদ নতুন খালি মাইএসকিউএল ডাটাবেসে ডেটা ইনপুট করার ফলে প্রাপ্ত কমান্ডটি নিম্নরূপ:

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

এটি রান্না করতে দিন, এবং এটি হওয়া উচিত! আগে এবং পরে আপনার ডেটা যাচাই করতে ভুলবেন না।

সুতরাং, ওপি যেমন অনুরোধ করেছে, এটি দ্রুত এবং সহজ, যখন আপনি কীভাবে জানেন! :-)

একদিকে যেমন, আমি এই স্থানান্তরের দিকে নজর দেওয়ার আগে আমি নিশ্চিত ছিলাম না যে এটি তৈরি_আউট এবং আপডেটেড_এই ক্ষেত্রের মানগুলি সংরক্ষণ করা হবে কিনা - আমার জন্য সুসংবাদটি হ'ল সেগুলি, তাই আমি আমার বিদ্যমান উত্পাদন ডেটা স্থানান্তর করতে পারি could

শুভকামনা!

হালনাগাদ

এই স্যুইচটি তৈরি করার পরে, আমি এমন একটি সমস্যা লক্ষ্য করেছি যা আমি এর আগে লক্ষ্য করি নি। আমার রেল অ্যাপ্লিকেশনটিতে, আমার পাঠ্য ক্ষেত্রগুলিকে 'স্ট্রিং' হিসাবে সংজ্ঞায়িত করা হয়েছে এবং এটি ডাটাবেস স্কিমাতে বহন করে। এখানে বর্ণিত প্রক্রিয়াটির ফলাফল মাইএসকিউএল ডেটাবেজে ভ্রচার (255) হিসাবে সংজ্ঞায়িত হচ্ছে। এটি এই ক্ষেত্রের আকারগুলিতে 255 টি চরিত্রের সীমা রাখে - এবং এর বাইরে যে কোনও কিছুই আমদানির সময় নিঃশব্দে কাটা হয়েছিল। আমি 255 এর চেয়ে বেশি পাঠ্যের দৈর্ঘ্য সমর্থন করতে, মাইএসকিউএল স্কিমাটিতে ভিচারআর (255) এর পরিবর্তে 'পাঠ্য' ব্যবহার করা দরকার, আমি বিশ্বাস করি। এখানে সংজ্ঞায়িত প্রক্রিয়াটিতে এই রূপান্তরটি অন্তর্ভুক্ত নয়।


এখানে একীভূত এবং সংশোধিত পাইথন স্ক্রিপ্টটি আমার ডেটার জন্য কাজ করেছে:

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

আমাদের টিম কাজ করছে এমন একটি প্রকল্পের জন্য আমাকে সম্প্রতি মাইএসকিউএল থেকে জাভাডিবিতে মাইগ্রেট করতে হয়েছিল। আমি DdlUtils নামে অ্যাপাচি লিখিত একটি জাভা গ্রন্থাগার পেয়েছি যা এটি বেশ সহজ করে তুলেছে। এটি এমন একটি এপিআই সরবরাহ করে যা আপনাকে নিম্নলিখিতগুলি করতে দেয়:

  1. একটি ডাটাবেসের স্কিমা আবিষ্কার করুন এবং এটি এক্সএমএল ফাইল হিসাবে রফতানি করুন।
  2. এই স্কিমা উপর ভিত্তি করে একটি ডিবি পরিবর্তন করুন।
  3. একি ডিবি থেকে অন্যকে রেকর্ড আমদানি করুন, ধরে নিবেন তাদের একই স্কিমা রয়েছে।

আমরা যে সরঞ্জামগুলি দিয়ে শেষ করেছি সেগুলি সম্পূর্ণ স্বয়ংক্রিয়ভাবে তৈরি হয়নি, তবে তারা বেশ ভাল কাজ করেছে। এমনকি আপনার অ্যাপ্লিকেশন জাভাতে না থাকলেও এককালীন স্থানান্তরিত করতে কয়েকটি ছোট ছোট সরঞ্জামকে হুইপ করা খুব কঠিন হওয়া উচিত নয়। আমি মনে করি যে আমি 150 টিরও কম লাইনের কোড সহ আমাদের স্থানান্তর টানতে সক্ষম হয়েছি।


4

কোনও স্ক্রিপ্ট, কমান্ড ইত্যাদির দরকার নেই ...

আপনাকে কেবল নিজের স্ক্লাইট ডাটাবেস .csvফাইল হিসাবে রফতানি করতে হবে এবং তারপরে phpmyadmin ব্যবহার করে এটি MySQL এ আমদানি করতে হবে।

আমি এটি ব্যবহার করেছি এবং এটি আশ্চর্যজনকভাবে কাজ করেছে ...


সঙ্গে একযোগে এই , এই শুধুমাত্র উত্তর যে আমার জন্য কাজ করা হয়।
সিডিউথ

3

জিমসের সমাধানের ভিত্তিতে: এসকিউএলটি 3 মাইএসকিউএলে স্থানান্তরিত করার দ্রুত উপায়?

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  

এটি আমার পক্ষে কাজ করে। আমি কেবল প্রথম লাইনটি ছুঁড়ে ফেলতে সিড ব্যবহার করি যা মাইএসকিএল-মতো নয়, তবে আপনি এই পংক্তিটি ফেলে দেওয়ার জন্য ডাম্প.পি স্ক্রিপ্টও সংশোধন করতে পারেন।


1
আমদানিকৃত ডেটা সহ আমার কিছু ইউটিএফ -8 এনকোডিং সমস্যা ছিল তবে আমদানি কমান্ডে --default-চরিত্র-সেট = utf8 যুক্ত করে তা স্থির করে বলে মনে হচ্ছে। এই প্রশ্নোত্তর থেকে নেওয়া: স্ট্যাকওভারফ্লো.com
স্নিপস

ঠিক আছে, আমি এটি যুক্ত করেছি - এটা ঠিক আছে?
alekwisnia

হ্যাঁ, আমি অতিরিক্ত সুইচটি ব্যবহার করছি।
স্নিপস

3

একটি এসকিউএল ডাম্প পান

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;

অথবা

mysql -u root -p somedb < myTemporarySQLFile.sql

এটি আপনাকে একটি পাসওয়ার্ডের জন্য অনুরোধ করবে। দয়া করে নোট করুন: আপনি যদি সরাসরি নিজের পাসওয়ার্ডটি প্রবেশ করতে চান, আপনার সরাসরি স্থানের পরে এটি করতে হবে-p :

mysql -u root -pYOURPASS somedb < myTemporarySQLFile.sql

বৃহত্তর ডাম্পগুলির জন্য:

mysqlimport বা অন্যান্য আমদানি সরঞ্জামগুলি পছন্দ করে বিগডাম্প

বিগডাম্প আপনাকে একটি অগ্রগতি বার দেয়:

এখানে চিত্র বর্ণনা লিখুন


12
স্ক্লাইট বনাম মাইএসকিএলে সামান্য সিনট্যাক্স পার্থক্য এবং পতাকাগুলির কারণে এটি কাজ করে না। আপনার এখনও এটি ম্যানুয়ালি রূপান্তর করতে হবে।
dlite922

1

হা ... আমি যদি এই প্রথম খুঁজে পেতাম! আমার প্রতিক্রিয়া এই পোস্টে ছিল ... স্ক্রিপ্টটি এসকিউএল ডাম্প এসকিএল ফাইলটিকে ফর্ম্যাটতে রূপান্তর করতে যেটিকে এসকিএলাইট 3 ডিবিতে আমদানি করা যায়

দুজনের সংমিশ্রণটি আমার প্রয়োজনের মতো হবে:


Sqlite3 ডাটাবেসটি রুবির সাথে ব্যবহার করতে গেলে আপনি পরিবর্তন করতে পারেন:

tinyint([0-9]*) 

প্রতি:

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

হায়, এটি কেবলমাত্র অর্ধেকটি কাজ করে কারণ আপনি বুলিয়ান চিহ্নিত ক্ষেত্রের মধ্যে 1 এবং 0 এর সন্নিবেশ করিয়ে দিলেও, স্ক্লাইট 3 এগুলি 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)তবে নির্ধারক বা স্ক্রিপ্ট আর্গুমেন্টগুলিতে যথাক্রমে সামঞ্জস্য করা যায়।

দ্রষ্টব্য: এর জন্য মাইএসকিউএল সংযোগকারী / পাইথন ২.০.৪ বা ততোধিকতর প্রয়োজন

গিটহাবের উত্সের একটি লিঙ্ক এখানে যদি নীচে কোডটি পড়তে খুব কঠিন হয় তবে: 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

এই স্ক্রিপ্টটি অবশ্যই এই ক্ষেত্রেটি বাদে ঠিক আছে, আমি দেখা করেছি:

অন্তর্ভুক্ত করুন "অনুরোধের তুলনা_ স্টপওয়ার্ড" ভ্যালু (149, 'চ');
অন্তর্ভুক্ত করুন "অনুরোধের তুলনা_ স্টপওয়ার্ড" ভ্যালু (420, 'টি');

স্ক্রিপ্ট এই আউটপুট দিতে হবে:

অনুরোধের তুলনা_স্টপওয়ার্ড ভ্যালু (149, 'চ') অন্তর্ভুক্ত করুন;
অন্তর্ভুক্ত করুন অনুরোধের তুলনা_স্টপওয়ার্ড ভ্যালু (420, 'টি');

কিন্তু পরিবর্তে যে আউটপুট দেয়:

অন্তর্ভুক্ত করুন অনুরোধের তুলনা_স্টপওয়ার্ড ভ্যালু (1490;
অন্তর্ভুক্ত করুন অনুরোধের তুলনা_স্টপওয়ার্ড ভ্যালু (4201;

সর্বশেষ 0 এবং 1 এর আশেপাশে কিছু অদ্ভুত অ-এসকি অক্ষর রয়েছে।

কোডের নিম্নলিখিত লাইনগুলিতে মন্তব্য করার পরে এটি আর প্রদর্শিত হবে না (৪৩-৪6) তবে অন্যদের সমস্যা দেখা দিয়েছে:


    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

মহান বিবৃতি জন্য নজর রাখুন

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.