PostgreSQL बाइट कॉलम में डेटा (फ़ाइल) कैसे डालें?


37

यह सवाल bytea v। Oid v। Blobs v। बड़ी वस्तुओं आदि के बारे में नहीं है।

मेरे पास एक मेज है जिसमें एक प्राथमिक कुंजी integerफ़ील्ड और एक byteaफ़ील्ड है। मैं byteaक्षेत्र में डेटा दर्ज करना चाहता हूं । यह, संभवतः, PL/भाषाओं में से एक द्वारा किया जा सकता है , और मैं PL/Pythonभविष्य में इसके साथ काम कर सकता हूं ।

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

संपादित करें: 2008 की इस चर्चा का तात्पर्य है कि मैं जो करना चाहता हूं वह संभव नहीं है। byteaफिर खेतों का उपयोग कैसे किया जाता है?

संपादित करें: 2005 का यह समान प्रश्न अनुत्तरित है।

हल किया गया: वेबसाइट पर यहां दिए गए विवरण ने psycopgएक समाधान के लिए आधार प्रदान किया है जो मैंने पायथन में लिखा है। बाइनरी डेटा को एक byteaकॉलम में उपयोग करके सम्मिलित करना भी संभव हो सकता है PL/Python। मुझे नहीं पता कि क्या यह "शुद्ध" एसक्यूएल का उपयोग करना संभव है।


1
मानस डॉक्स का लिंक टूटा हुआ है और मेरा संपादन अस्वीकार कर दिया गया है (!?)। यहाँ वर्तमान स्थान है
आर्येह लीब तौआरोग

@AryehLeibTaurog: धन्यवाद। मैंने संपादन को अस्वीकार कर दिया क्योंकि यह मेरे लिए स्पष्ट नहीं था कि आपका परिवर्तित पाठ हाइपरलिंक था। यदि आप फिर से संपादन करना चाहते हैं, तो मैं इसे अनुमोदित करूंगा।
सब्रेवॉल्फी

@Andriy_M आपको क्यों लगता है कि "यह पोस्ट के मूल इरादे से भटकता है।" (
Editatik01

@ चमत्कार १ some३: क्योंकि मुझे आभास हुआ कि सुझाए गए कुछ टैग अप्रासंगिक थे (ठीक है, वास्तव में सिर्फ एक blob)। अगर वह गलती थी, तो मैं ईमानदारी से माफी मांगता हूं।
एंड्री एम

जवाबों:


26

सुपरयुसर के रूप में:

create or replace function bytea_import(p_path text, p_result out bytea) 
                   language plpgsql as $$
declare
  l_oid oid;
begin
  select lo_import(p_path) into l_oid;
  select lo_get(l_oid) INTO p_result;
  perform lo_unlink(l_oid);
end;$$;

lo_get 9.4 में पेश किया गया था इसलिए पुराने संस्करणों के लिए आपको इसकी आवश्यकता होगी:

create or replace function bytea_import(p_path text, p_result out bytea) 
                   language plpgsql as $$
declare
  l_oid oid;
  r record;
begin
  p_result := '';
  select lo_import(p_path) into l_oid;
  for r in ( select data 
             from pg_largeobject 
             where loid = l_oid 
             order by pageno ) loop
    p_result = p_result || r.data;
  end loop;
  perform lo_unlink(l_oid);
end;$$;

फिर:

insert into my_table(bytea_data) select bytea_import('/my/file.name');

रिवर्स प्रक्रिया के लिए, मैं प्रयास नहीं किया है इस , लेकिन अगर यह काम करता है, lo_export आप सभी की जरूरत हो जाएगा
जैक डगलस


15

यह समाधान रनटाइम के मामले में बिल्कुल कुशल नहीं है, लेकिन अपने स्वयं के हेडर बनाने की तुलना में यह बहुत आसान है COPY BINARY। इसके अलावा, इसे किसी भी लाइब्रेरी या भाषा को बाहर करने की स्क्रिप्टिंग की आवश्यकता नहीं है।

सबसे पहले, फ़ाइल के आकार को दोगुना करते हुए फ़ाइल को एक हेक्सडंप में परिवर्तित करें। xxd -pहमें बहुत करीब आता है, लेकिन यह कुछ कष्टप्रद नई कहानियों में फेंकता है जिन्हें हमें ध्यान रखना है:

xxd -p /path/file.bin | tr -d '\n' > /path/file.hex

अगला, PostgreSQL में डेटा को एक बहुत बड़े textक्षेत्र के रूप में आयात करें । यह प्रकार प्रति क्षेत्र मान में एक जीबी तक होता है, इसलिए हमें अधिकांश उद्देश्यों के लिए ठीक होना चाहिए:

CREATE TABLE hexdump (hex text); COPY hexdump FROM '/path/file.hex';

अब जब हमारा डेटा एक बड़ी बड़ी हेक्स स्ट्रिंग है, तो हम decodeइसे byteaटाइप करने के लिए PostgresQL का उपयोग करते हैं :

CREATE TABLE bindump AS SELECT decode(hex, 'hex') FROM hexdump;

इस समाधान के परिणामस्वरूप फ़ाइल से \ n वर्ण निकाले जा रहे हैं।
SabreWolfy

2
सब्रेवॉल्फी: नहीं, यह नहीं है। tr -d '\n'XXD के उत्पादन, जो ASCII हेक्साडेसिमल वर्ण (0-9 और वायुसेना) के रूप में इनपुट के द्विआधारी सामग्री encodes पर काम कर रहा है। xxd आउटपुट मान को पठनीय बनाने के लिए नियमित अंतराल पर आउटपुट लाइन फीड के लिए भी होता है, लेकिन इस मामले में हम चाहते हैं कि उन्हें हटा दिया जाए। मूल डेटा में लाइन फ़ीड हेक्स रूप में होगी, और अप्रभावित रहेगी।
गुडसाइड

5

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

xxd  -p /home/user/myimage.png | tr -d '\n' > /tmp/image.hex
echo "
    -- CREATE TABLE hexdump (hex text);
    DELETE FROM hexdump;
    COPY hexdump FROM '/tmp/image.hex';

    -- CREATE TABLE bindump (binarydump bytea);
    DELETE FROM bindump;

    INSERT INTO bindump (binarydump)  
    (SELECT decode(hex, 'hex') FROM hexdump limit 1);

    UPDATE users 
    SET image= 
    (
        SELECT decode(hex, 'hex') 
        FROM hexdump LIMIT 1
    )  
    WHERE id=15489 ;
    " | psql mydatabase

1

Postgres COPY BINARY फ़ंक्शन का उपयोग करें । यह मोटे तौर पर ओरेकल की बाहरी तालिकाओं के बराबर है ।


धन्यवाद। आपके द्वारा दिया गया लिंक इंगित करता है कि डेटा या तो ASCII या PostgreSQL के बाइनरी टेबल प्रारूप में होना चाहिए। पृष्ठ के नीचे, उल्लेख किया गया है कि बाइनरी टेबल प्रारूप को पहले COPY TO कमांड के साथ बनाया गया है। क्या इनमें से कोई भी दृष्टिकोण मुझे एक बाइनरी फ़ाइल (पीडीएफ, दस्तावेज़, स्प्रेडशीट) को एक byteaकॉलम में सम्मिलित करने की अनुमति देगा ?
सब्रेवॉल्फ़ी

COPY BINARY पर PostgreSQL प्रलेखन ( postgresql.org/docs/8.4/interactive/sql-copy.html ) इंगित करता है कि बाइनरी डेटा सम्मिलित करते समय एक विशेष फ़ाइल हेडर की आवश्यकता होती है। क्या मुझे इस हेडर को बनाने और बाइनरी डेटा के साथ जोड़ने की आवश्यकता है? यह द्विआधारी डेटा की एक स्ट्रिंग को संग्रहीत करने के लिए कुछ जटिल लगता है।
सब्रेवॉल्फी

हम्म, अब जब आप इसका उल्लेख करते हैं तो मुझे यकीन नहीं है, मुझे सिर्फ कमांड याद है और यह मान लिया कि यह ऐसा करेगा। शायद PL / जो भी करने का एकमात्र तरीका है।
गयुस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.