আমি কিছু এসকিউএল 3 টেবিলের ডেটা কীভাবে ফেলে দেব?


182

আমি কীভাবে ডেটাবেসের কিছু এসকিউএলাইট 3 টেবিলের (সমস্ত টেবিল নয়) ডেটা এবং কেবল ডেটা, কেবল স্কিমার নয়? ডাম্পটি এসকিউএল ফর্ম্যাটে হওয়া উচিত, কারণ এটি পরে ডাটাবেসে সহজেই প্রবেশ করা উচিত এবং কমান্ড লাইন থেকে করা উচিত। কিছুটা এইরকম

sqlite3 db .dump

তবে স্কিমাটি ডাম্পিং না করে এবং কোন টেবিলগুলি ডাম্প করতে হবে তা নির্বাচন না করে।


কি বিন্যাসে? বিশেষভাবে কিছু, বা আপনি কেবল একটি মানব পাঠযোগ্য ব্যাকআপের সন্ধান করছেন? নির্ধারন করুন.
ডিএমকেকে --- প্রাক্তন মডারেটর বিড়ালছানা

1
আমি এসকিউএল ফর্ম্যাটে ডাম্প করতে চাই, যাতে আমি এটি সহজেই পুনরুদ্ধার করতে পারি। আমি সেই তথ্যটি মূল প্রশ্নের সাথে যুক্ত করেছি।
pupeno

উত্তর:


214

আপনি ডাম্প করা ফাইলটি দিয়ে কী করতে চান তা বলছেন না।

আমি সিএসভি ফাইল পেতে নিম্নলিখিতগুলি ব্যবহার করব, যা আমি প্রায় প্রতিটি ক্ষেত্রে আমদানি করতে পারি

.mode csv 
-- use '.separator SOME_STRING' for something other than a comma.
.headers on 
.out file.csv 
select * from MyTable;

আপনি যদি অন্য কোনও এসকিউএল ডাটাবেসে আবার প্রবেশ করতে চান তবে:

.mode insert <target_table_name>
.out file.sql 
select * from MyTable;

এসকিউএল স্টেটমেন্টগুলি ব্যবহার করে প্রোগ্রামগতভাবে এটি করার কোনও উপায় আছে কি? আমি দোভাষী ব্যবহার করে এটি কীভাবে করব তা দেখতে পাচ্ছি, তবে আমি যদি কোনও স্ক্রিপ্ট লিখতে চাইতাম তবে কী হবে?
কোলেফার

4
আপনি আপনার স্টেটমেন্টগুলিকে একটি ফাইলে রাখতে পারেন (উদাঃ নমুনা। টেক্সট) এবং তারপরে এটি ব্যবহার করে আবেদন করতে পারেন: sqlite3 db.sq3 <નમૂના.txt
সাইবারফোনিক

" অথবা .আউটপুট এর পরিবর্তে .once কমান্ডটি ব্যবহার করুন এবং কনসোলটিতে ফিরে আসার আগে আউটপুট এবং আউটপুট কেবলমাত্র একক পরবর্তী কমান্ডের জন্য পুনঃনির্দেশিত হবে standard পুনরায় স্ট্যান্ডার্ড আউটপুটটিতে লেখা শুরু করার জন্য আউটপুট ব্যবহার করুন
S

156

.Schema এবং .dump কমান্ডের পার্থক্যটি আপনি এটি করতে পারেন। গ্রেপ সহ উদাহরণস্বরূপ:

sqlite3 some.db .schema > schema.sql
sqlite3 some.db .dump > dump.sql
grep -vx -f schema.sql dump.sql > data.sql

data.sql ফাইলটিতে স্কিমা ছাড়া কেবল ডেটা থাকবে, এরকম কিছু:

BEGIN TRANSACTION;
INSERT INTO "table1" VALUES ...;
...
INSERT INTO "table2" VALUES ...;
...
COMMIT;

আমি আশা করি এটা আপনাকে সাহায্য করবে।


5
পছন্দ করুন স্রেফ রান করুনsqlite3 some.db < data.sql
জেলিফিশ

কিছু রসুন আমার জন্য কাজ করে না। আমার চারপাশে ব্যবহার দরকার sqlite3 storage/db/jobs.s3db .schema jobs > schema.sqlকাজ করে না, তবে echo '.schema' jobs | sqlite3 storage/db/jobs.s3db > schema.sql
ঠিকঠাক

2
এটি একটি ভাল সমাধান বলে মনে হয়েছিল, তবে আমার ক্ষেত্রে বেশিরভাগ লাইন আসলে গ্রেপ দ্বারা সরানো হচ্ছে। .Schema কমান্ড একাধিক লাইনে প্রতিটি টেবিলের স্কিমা উত্পন্ন করে, সুতরাং কেবল একটি লাইন থাকে );এবং গ্রেপ গ্রেপ- );-xবিকল্প যুক্ত করে সমস্ত লাইন সরিয়ে দেয় এই সমস্যাটি সমাধান করে।
সুন্দর

38

সেরা উপায় নয়, তবে ইজারাতে বাহ্যিক সরঞ্জামের প্রয়োজন নেই (গ্রেপ ব্যতীত, যা যাইহোক * নিক্স বাক্সে মানক)

sqlite3 database.db3 .dump | grep '^INSERT INTO "tablename"'

তবে আপনি যে সারণীতে সন্ধান করছেন তার জন্য আপনাকে এই আদেশটি করতে হবে।

মনে রাখবেন যে এতে স্কিমা অন্তর্ভুক্ত নেই।


1
আমি ব্যবহার করেছিsqlite3 Database.s3db .dump
জেডার ডায়াস

3
যদি এই সন্নিবেশকারীদের মানগুলিতে নতুন লাইন থাকে তবে এটি ভঙ্গ হবে। grep -v '^CREATE'অন্য উত্তরের একটি হিসাবে পরামর্শ হিসাবে ভাল ব্যবহার
ডিকুইস

1
grep -v '^CREATE;যদি CREATEবিবৃতিগুলির মধ্যে লাইন বিচ্ছিন্ন হয় (যা তারা কখনও কখনও করেন) ব্যবহার করে বিরতি হবে । সেরা, আইএমও হ'ল স্বয়ংক্রিয়ভাবে CREATEবিবৃতিগুলি ছড়িয়ে দেওয়া নয়, ম্যানুয়ালি সেগুলি সম্পাদনা করে। আপনার যা প্রয়োজন টেক্সট সম্পাদকটি কেবল ব্যবহার করুন এবং CREATEসেই বিবৃতিগুলি অনুসন্ধান করুন এবং ম্যানুয়ালি মুছে ফেলুন। যতক্ষণ ডাটাবেস বিশাল না হয় (এবং যেহেতু আপনি স্ক্লাইট ব্যবহার করছেন, আমি এটি নোট অনুমান করব), তবে এটি বেশ সহজ।
ড্যান জোনস

তবে তৈরির গ্রেপ ভিউগুলি থেকে তৈরিটি গ্রহণ করবে। আমি কীভাবে এটি সরিয়ে ফেলতে পারি?
সিলভ 2611

35

আপনি .dump বিশেষ কমান্ডে এক বা একাধিক টেবিল আর্গুমেন্ট নির্দিষ্ট করতে পারেন, যেমন sqlite3 db ".dump 'table1' 'table2'"


4
আপনি উল্লিখিত হিসাবে আমি যখন একাধিক টেবিলের নাম যুক্ত করব তখন এটি আমাকে এই আউটপুট দেয়: ব্যবহার: .ডাম্প? - সারি-রোডস সংরক্ষণ করুন? ? মতো-প্যাটার্ন?
mwm

1
@ এমডব্লিউএম আমি একই সমস্যাটি পর্যবেক্ষণ করছি sqlite3 3.31.1 (2020/01/27)পরিবর্তণের যে সম্পর্কে কিছুই বলছেন। (যাইহোক, --preserve-rowidsকাজ করে তবে একেবারেই নথিভুক্ত হয় না))
ynn

11

CREATEলাইনগুলি বাদ দিতে বা আউটপুট INSERTথেকে কেবল লাইনগুলি ধরার জন্য গ্রেপ ব্যবহার করার পরামর্শ দেয় এমন কোনও উত্তর sqlite3 $DB .dumpখারাপভাবে ব্যর্থ হবে। CREATE TABLEকমান্ড লাইন প্রতি একটি কলাম তালিকাবদ্ধ (ব্যতীত তাই CREATEএটা সব পাবেন না), এবং উপর মান INSERTলাইন এমবেডেড নতুন লাইন থাকতে পারে (তাই আপনি শুধু দখল করতে পারবে না INSERTলাইন)।

for t in $(sqlite3 $DB .tables); do
    echo -e ".mode insert $t\nselect * from $t;"
done | sqlite3 $DB > backup.sql

স্কেলাইট 3 সংস্করণ 3.6.20 এ পরীক্ষিত।

আপনি যদি কিছু সারণী বাদ দিতে চান তবে আপনি সেগুলি ফিল্টার করতে পারেন $(sqlite $DB .tables | grep -v -e one -e two -e three)বা আপনি যদি একটি নির্দিষ্ট উপসেট পেতে চান তবে এটির সাথে প্রতিস্থাপন করুন one two three


9

পল ইগানের উত্তরের উন্নতি হিসাবে, এটি নিম্নলিখিত হিসাবে সম্পাদন করা যেতে পারে:

sqlite3 database.db3 '.dump "table1" "table2"' | grep '^INSERT'

--or--

sqlite3 database.db3 '.dump "table1" "table2"' | grep -v '^CREATE'

সতর্কতামূলকভাবে অবশ্যই আপনাকে গ্রিপ ইনস্টল করতে হবে।


1
আমার এটা ভাল লেগেছে. একটি যুক্ত বোনাস হিসাবে, এটি এখনও কাজ করে যদি আপনার একটি ডাম্পড এসকিউএল ফাইলের চারপাশে ঝুলন্ত থাকে, ঠিক cat database.sql | grep '^INSERT' > database_inserts.sql(স্কিমার জন্য একই, এর সাথে প্রতিস্থাপন করুনgrep '^CREATE'
trisweb

2
@trisweb, অবশ্যই আপনি কি বলতে চান grep '^INSERT' < database.sql > database_inserts.sqlযে catপ্রযোজন নেই
সেবাস্টিয়ান

1
এটি সম্পর্কে অতিরিক্ত কিছু নেই। catমূলত চালানো কিছুই খরচ এবং আউটপুট ইনপুট চেইন অব অনেক পরিষ্কার করে তোলে। অবশ্যই, আপনি লিখতেও পারতেন < database.sql grep '^INSERT' ...তবে একটি স্পষ্ট পাইপ পড়া খুব সহজ।
rjh

1
আপনি উল্লিখিত হিসাবে আমি যখন একাধিক টেবিলের নাম যুক্ত করব তখন এটি আমাকে এই আউটপুট দেয়: ব্যবহার: .ডাম্প? - সারি-রোডস সংরক্ষণ করুন? ? মতো-প্যাটার্ন?
mwm

-1: ক্রিয়েট সহ লাইনগুলি অনুসন্ধান করা একটি অকেজো ধারণা। প্রায় প্রতিটি ভিউ বা ট্রিগার বিশেষত, যদি এতে মন্তব্য থাকে তবে একাধিক লাইনের প্রয়োজন।
14: 26

6

পাইথন বা জাভা বা কোনও উচ্চ স্তরের ভাষায় .dump কাজ করে না। আমাদের হাতে হাতে সিএসভিতে রূপান্তর কোড দরকার। আমি একটি পাইথনের উদাহরণ দিই। অন্যান্য, উদাহরণ প্রশংসা করা হবে:

from os import path   
import csv 

def convert_to_csv(directory, db_name):
    conn = sqlite3.connect(path.join(directory, db_name + '.db'))
    cursor = conn.cursor()
    cursor.execute("SELECT name FROM sqlite_master WHERE type='table';")
    tables = cursor.fetchall()
    for table in tables:
        table = table[0]
        cursor.execute('SELECT * FROM ' + table)
        column_names = [column_name[0] for column_name in cursor.description]
        with open(path.join(directory, table + '.csv'), 'w') as csv_file:
            csv_writer = csv.writer(csv_file)
            csv_writer.writerow(column_names)
            while True:
                try:
                    csv_writer.writerow(cursor.fetchone())
                except csv.Error:
                    break

আপনার যদি প্যানেল ডেটা থাকে, অন্য কথায় আইডির সাথে অনেকগুলি পৃথক এন্ট্রি এটিকে চেহারা সহ যুক্ত করে এবং এটি সংক্ষিপ্ত পরিসংখ্যানগুলিও ফেলে দেয়:

        if 'id' in column_names:
            with open(path.join(directory, table + '_aggregate.csv'), 'w') as csv_file:
                csv_writer = csv.writer(csv_file)
                column_names.remove('id')
                column_names.remove('round')
                sum_string = ','.join('sum(%s)' % item for item in column_names)
                cursor.execute('SELECT round, ' + sum_string +' FROM ' + table + ' GROUP BY round;')
                csv_writer.writerow(['round'] + column_names)
                while True:
                    try:
                        csv_writer.writerow(cursor.fetchone())
                    except csv.Error:
                        break 

4

SQLite এর জন্য কমান্ড লাইন শেলের জন্য SQLite ডকুমেন্টেশন অনুসারে আপনি কোনও SQLite টেবিল (বা একটি টেবিলের অংশ) CSV হিসাবে রফতানি করতে পারেন, কেবল "মোড" কে "csv" এ সেট করে এবং এরপরে কাঙ্ক্ষিত সারিগুলি বের করার জন্য একটি কোয়েরি চালাতে পারেন টেবিল:

sqlite> .header on
sqlite> .mode csv
sqlite> .once c:/work/dataout.csv
sqlite> SELECT * FROM tab1;
sqlite> .exit

তারপরে একটি এসকিউএল টেবিলের মধ্যে CSV (কমা বিভাজিত মান) ডেটা আমদানি করতে ".পোর্ট" কমান্ডটি ব্যবহার করুন:

sqlite> .mode csv
sqlite> .import C:/work/dataout.csv tab1
sqlite> .exit

দুটি বিষয় বিবেচনা করার জন্য দয়া করে আরও ডকুমেন্টেশন পড়ুন: (1) সারণী "ট্যাব 1" এর আগে বিদ্যমান নেই এবং (2) সারণী "ট্যাব 1" ইতিমধ্যে উপস্থিত রয়েছে।


3

স্কিমাইট 3 ডিবি ডাম্প স্কিমা অংশগুলি বাদ দিয়ে কোডটি গ্রহণ করা সবচেয়ে ভাল পদ্ধতি হবে।

সিউডো কোড উদাহরণ:

SELECT 'INSERT INTO ' || tableName || ' VALUES( ' || 
  {for each value} ' quote(' || value || ')'     (+ commas until final)
|| ')' FROM 'tableName' ORDER BY rowid DESC

দেখা: src/shell.c:838 প্রকৃত কোডের জন্য

আপনি এমনকি এই শেলটি নিয়ে গিয়ে স্কিমা অংশগুলি মন্তব্য করতে পারেন এবং এটি ব্যবহার করতে পারেন।


3

অন্যান্য সম্ভাব্য সমাধানগুলির পর্যালোচনা

কেবল INSERTs অন্তর্ভুক্ত করুন

sqlite3 database.db3 .dump | grep '^INSERT INTO "tablename"'

কার্যকর করা সহজ তবে যদি আপনার কোনও কলামে নতুন লাইন অন্তর্ভুক্ত থাকে তবে তা ব্যর্থ হবে

এসকিউএলাইট সন্নিবেশ মোড

for t in $(sqlite3 $DB .tables); do
    echo -e ".mode insert $t\nselect * from $t;"
done | sqlite3 $DB > backup.sql

এটি একটি দুর্দান্ত এবং অনুকূলিতকরণযোগ্য সমাধান, তবে যদি আপনার কলামগুলিতে স্পষ্টালাইটে 'জ্যামিতি' টাইপের মতো ব্লব অবজেক্ট থাকে তবে এটি কাজ করে না

স্কিমা সহ ডাম্পের পার্থক্য

sqlite3 some.db .schema > schema.sql
sqlite3 some.db .dump > dump.sql
grep -v -f schema.sql dump > data.sql

নিশ্চিত না কেন, তবে আমার পক্ষে কাজ করছে না

আরেকটি (নতুন) সম্ভাব্য সমাধান

সম্ভবত এই প্রশ্নের সর্বোত্তম উত্তর নেই, তবে আমার পক্ষে কাজ করা একটি হ'ল সন্নিবেশগুলি বিবেচনা করা গ্রাহক যা এই জাতীয় মত প্রকাশের সাথে কলাম মানগুলিতে নতুন লাইন হতে পারে

grep -Pzo "(?s)^INSERT.*\);[ \t]*$"

টেবিলগুলি নির্বাচন করতে ছুঁড়ে ফেলা হবে .dumpনা যেমন টেবিলের নামগুলি মিলে যাওয়ার জন্য একটি যুক্তির মতো স্বীকৃতি দেয় তবে এটি যথেষ্ট না হলে সম্ভবত একটি সাধারণ স্ক্রিপ্টই আরও ভাল বিকল্প হতে পারে

TABLES='table1 table2 table3'

echo '' > /tmp/backup.sql
for t in $TABLES ; do
    echo -e ".dump ${t}" | sqlite3 database.db3 | grep -Pzo "(?s)^INSERT.*?\);$" >> /tmp/backup.sql
done

বা, বিদেশী কীগুলি সম্মানের জন্য আরও কিছু বিশদভাবে বর্ণনা করা হয়েছে এবং কেবলমাত্র একটি লেনদেনে সমস্ত ডাম্পকে আবদ্ধ করে

TABLES='table1 table2 table3'

echo 'BEGIN TRANSACTION;' > /tmp/backup.sql
echo '' >> /tmp/backup.sql
for t in $TABLES ; do
    echo -e ".dump ${t}" | sqlite3 $1 | grep -Pzo "(?s)^INSERT.*?\);$" | grep -v -e 'PRAGMA foreign_keys=OFF;' -e 'BEGIN TRANSACTION;' -e 'COMMIT;' >> /tmp/backup.sql
done

echo '' >> /tmp/backup.sql
echo 'COMMIT;' >> /tmp/backup.sql

অ্যাকাউন্টে বিবেচনা করুন যে );কোনও কলামে একটি স্ট্রিং উপস্থিত থাকলে গ্রেপ এক্সপ্রেশন ব্যর্থ হবে

এটি পুনরুদ্ধার করতে (ইতিমধ্যে তৈরি টেবিলগুলির সাথে একটি ডাটাবেসে)

sqlite3 -bail database.db3 < /tmp/backup.sql

2

এই সংস্করণটি সন্নিবেশকারীদের ভিতরে নতুন লাইনের সাথে ভালভাবে কাজ করে:

sqlite3 database.sqlite3 .dump | grep -v '^CREATE'

অনুশীলনে এমন সমস্ত লাইন বাদ দেয় CREATEযা দিয়ে শুরু হয় নতুন লাইনের উপস্থিতি কম


0

প্রত্যাহার করে উত্তরটি নিকটতম হওয়া উচিত, তবুও এটি আমার ক্ষেত্রে কার্যকর হয় না। একটি সন্নিবেশ ক্যোয়ারী সবেমাত্র ভেঙে গেছে এবং রফতানি বন্ধ হয়ে গেছে। কারণ কী তা নিশ্চিত নয়। তবে এটি সময়কালে কাজ করে.dump

অবশেষে এসকিউএল থেকে উত্পন্ন বিভক্তকরণের জন্য একটি সরঞ্জাম লিখেছিলাম .dump:

https://github.com/motherapp/sqlite_sql_parser/


-3

আপনি প্রতিটি ক্ষেত্রের পরে সিএসভি তৈরির জন্য কমা সন্নিবেশকারী টেবিলগুলিতে একটি নির্বাচন করতে পারেন, বা সমস্ত ডেটা ফেরত দিতে এবং একটি সিএসভিতে সংরক্ষণ করার জন্য একটি জিইউআই সরঞ্জাম ব্যবহার করতে পারেন।


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