2009-01-05 7 views
7

मुझे दस मिलियन पंक्तियों के साथ उत्पादन डीबी मिला है। मैं उत्पादन के पिछले घंटे से 10,000 या तो पंक्तियों को निकालना चाहता हूं और उन्हें अपने स्थानीय बॉक्स में कॉपी करना चाहता हूं। मैं उसको कैसे करू?पोस्टग्रेज़ में एक डेटाबेस से दूसरे डेटाबेस में किसी तालिका की पंक्तियों का सबसेट कॉपी करने का सबसे अच्छा तरीका क्या है?

मान लीजिए कि क्वेरी है दो:

SELECT * FROM mytable WHERE date > '2009-01-05 12:00:00'; 

मैं उत्पादन कैसे दूं, डंप फ़ाइल किसी प्रकार के लिए यह निर्यात, और फिर डेटाबेस के अपने स्थानीय विकास कॉपी में है कि डंप फ़ाइल आयात - के रूप में जितनी जल्दी हो सके जल्दी और आसानी से?

उत्तर

2
psql के भीतर से

, तो आप सिर्फ क्वेरी के साथ copy का उपयोग आप ने हमें दिया है, एक सीएसवी (या जो भी प्रारूप), \c और इसे आयात के साथ स्विच डेटाबेस के रूप में इस निर्यात।

में \h copy में देखें।

+0

मैं इस मिल:

यदि आप किसी भी कस्टम mytable पर चलाता है है, तो आप आयात पर उन्हें निष्क्रिय करने की आवश्यकता हो सकती करने के लिए या एक फ़ाइल से कॉपी करने के लिए होना चाहिए सुपर उपयोगकर्ता ... है इसके चारों ओर किसी भी तरह, यह मानते हुए कि मैं सुपरसियर के रूप में मनमाने ढंग से कोड चलाने के लिए नहीं जा रहा हूँ? – mike

+0

माइकल बुआज़ जैसे उत्तरों से बचने के लिए आपको इस प्रतिबंध को जोड़ने के लिए मूल प्रश्न को संपादित करना चाहिए। – bortzmeyer

0

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

#!/usr/bin/python 

""" 

Copy a *part* of a database to another one. See 
<http://stackoverflow.com/questions/414849/whats-the-best-way-to-copy-a-subset-of-a-tables-rows-from-one-database-to-anoth> 

With PostgreSQL, the only pure-SQL solution is to use COPY, which is 
not available to the ordinary user. 

Stephane Bortzmeyer <[email protected]> 

""" 

table_name = "Tests" 
# List here the columns you want to copy. Yes, "*" would be simpler 
# but also more brittle. 
names = ["id", "uuid", "date", "domain", "broken", "spf"] 
constraint = "date > '2009-01-01'" 

import psycopg2 

old_db = psycopg2.connect("dbname=dnswitness-spf") 
new_db = psycopg2.connect("dbname=essais") 
old_cursor = old_db.cursor() 
old_cursor.execute("""SET TRANSACTION READ ONLY""") # Security 
new_cursor = new_db.cursor() 
old_cursor.execute("""SELECT %s FROM %s WHERE %s """ % \ 
         (",".join(names), table_name, constraint)) 
print "%i rows retrieved" % old_cursor.rowcount 
new_cursor.execute("""BEGIN""") 
placeholders = [] 
namesandvalues = {} 
for name in names: 
    placeholders.append("%%(%s)s" % name) 
for row in old_cursor.fetchall(): 
    i = 0 
    for name in names: 
     namesandvalues[name] = row[i] 
     i = i + 1 
    command = "INSERT INTO %s (%s) VALUES (%s)" % \ 
       (table_name, ",".join(names), ",".join(placeholders)) 
    new_cursor.execute(command, namesandvalues) 
new_cursor.execute("""COMMIT""") 
old_cursor.close() 
new_cursor.close() 
old_db.close() 
new_db.close() 
4

स्रोत सर्वर:

BEGIN; 

CREATE TEMP TABLE mmm_your_table_here AS 
    SELECT * FROM your_table_here WHERE your_condition_here; 

COPY mmm_your_table_here TO 'u:\\source.copy'; 

ROLLBACK; 

अपने स्थानीय बॉक्स:

-- your_destination_table_here must be created first on your box 

COPY your_destination_table_here FROM 'u:\\source.copy'; 

लेख: http://www.postgresql.org/docs/8.1/static/sql-copy.html

+0

ओपी ने स्पष्ट रूप से कहा (केल्टिया के जवाब पर एक टिप्पणी में) कि वह सुपरसियर नहीं है इसलिए कॉपी एक विकल्प नहीं है)। – bortzmeyer

+2

जैसा कि पूछताछकर्ता ने सुपरसुर बाधाओं को रखने के लिए प्रश्न संपादित नहीं किया है, इसे एक अच्छा जवाब माना जाना चाहिए। – Ross

9

स्रोत:

psql -c "COPY (SELECT * FROM mytable WHERE ...) TO STDOUT" > mytable.copy 

गंतव्य:

psql -c "COPY mytable FROM STDIN" < mytable.copy 

इसमें यह माना जाता mytable स्रोत और गंतव्य दोनों में एक ही स्कीमा और स्तंभ क्रम है। यदि यह मामला नहीं है, तो आप STDOUT CSV HEADER और STDIN CSV HEADERSTDOUT और STDIN की बजाय कोशिश कर सकते हैं, लेकिन मैंने कोशिश नहीं की है। त्रुटि::

psql -c "ALTER TABLE mytable DISABLE TRIGGER USER; \ 
     COPY mytable FROM STDIN; \ 
     ALTER TABLE mytable ENABLE TRIGGER USER" < mytable.copy 
संबंधित मुद्दे