मैं PostgreSQL डेटाबेस तालिका में एक कॉलम की स्थिति को कैसे बदलूं?


112

मैंने निम्नलिखित कोशिश की है, लेकिन मैं असफल रहा:

ALTER TABLE person ALTER COLUMN dob POSITION 37;

6
इस सवाल का जवाब पहले दिया
Tometzky

जवाबों:


106

PostgreSQL विकी में " ऑल्टर कॉलम पोजिशन " कहती है:

PostgreSQL वर्तमान attnumमें pg_attributeतालिका के स्तंभ के आधार पर स्तंभ क्रम को परिभाषित करता है । कॉलम ऑर्डर को बदलने का एकमात्र तरीका या तो तालिका को फिर से बनाना है, या जब तक आप वांछित लेआउट तक नहीं पहुंचते हैं, तब तक कॉलम और घूर्णन डेटा जोड़कर।

यह बहुत कमज़ोर है, लेकिन उनके बचाव में, मानक एसक्यूएल में, किसी कॉलम को रिपॉज़िट करने का कोई समाधान नहीं है। डेटाबेस ब्रांड जो स्तंभ की क्रमिक स्थिति को बदलने का समर्थन करते हैं, SQL सिंटैक्स के विस्तार को परिभाषित करते हैं।

एक अन्य विचार मेरे साथ होता है: आप VIEWआधार तालिका में स्तंभ की भौतिक स्थिति को बदलने के बिना स्तंभों के क्रम को निर्दिष्ट कर सकते हैं कि आप इसे कैसे पसंद करते हैं।


3
@ दाना: मुझे लगता है कि विकी लेख में "तालिका को फिर से बनाना" से इसका मतलब है।
बिल करविन

2
'डेटाबेस को डंप करें' :: डेटा को नुकसान पहुंचाने का शानदार तरीका। और इसलिए "बड़े पैमाने पर डेटाबेस को साफ़ करें" प्रभाव।
केंट फ्रेड्रिक

31
@Kent: संदेह है, पोस्टग्रैड देव डेटा स्थिरता सुनिश्चित करने के लिए एक लंबा रास्ता तय करते हैं और यह निश्चित रूप से pg_dump पर लागू होगा। सब के बाद, db बैकअप करने की बात क्या है अगर पुनर्स्थापना का काम किया जाता है?
दाना द साने

@ दाना, हाँ, लेकिन आप 1 जोड़ रहे हैं) डंप करने के लिए एक बड़ी प्रक्रिया है, और फिर आप ड्रॉप करते हैं, और फिर आपके पास एक बड़ा समय लेने वाला लोड होता है। यदि आपके पास एक गंभीर रूप से विशाल डेटाबेस है, जो आमतौर पर 37 कॉलम के साथ होता है, तो आपको डिस्क आईओ चोकिंग के साथ जोखिम होने वाले हैं।
केंट फ्रेड्रिक

@DanatheSane ये सुपर पुरानी टिप्पणियां हैं, लेकिन बिल जो कह रहा था वह अनिवार्य रूप से एक ही बात है, एक पूर्ण डेटाबेस डंप करने के बजाय, आप केवल टेबल (और निर्भरता) को डंप करते हैं, मूल को मारते हैं, फिर से बनाते हैं। पूरे डेटाबेस को ऑफ़लाइन लेने की आवश्यकता नहीं है, या ऐसा कुछ नहीं है जो प्रभावित न हो। दूसरी ओर, अगर बहुत सारी निर्भरताएँ हैं, तो मैंने एक पूर्ण डंप (जैसा आपने सुझाव दिया था) बहुत आसान होने के लिए पाया है।
Vol7ron

36

PostgreSQL में, एक फ़ील्ड जोड़ते समय इसे तालिका के अंत में जोड़ा जाएगा। अगर हमें विशेष स्थिति में सम्मिलित करने की आवश्यकता है तो

alter table tablename rename to oldtable;
create table tablename (column defs go here);
insert into tablename (col1, col2, col3) select col1, col2, col3 from oldtable;

3
वाह यह बहुत अच्छा है, मुझे यकीन है कि यह स्वीकृत उत्तर होना चाहिए!
टॉमसो थेया सिओनी

हाँ, यह वास्तव में उपयोगी है, बहुत बहुत धन्यवाद!
एक्यूना

आप वर्तमान तालिका को इस तरह एक नए पुराने प्रकार पर भी कॉपी कर सकते हैं: पुराने टेबल के रूप में पुराने टेबल बनाएं * टैबलेन से;
रायन

29

यह पोस्ट पुरानी है और शायद हल हो गई है लेकिन मेरे पास एक ही मुद्दा था। मैंने नए स्तंभ क्रम को निर्दिष्ट करते हुए मूल तालिका का एक दृश्य बनाकर इसे हल किया।

यहाँ से मैं या तो दृश्य का उपयोग कर सकता था या दृश्य से एक नई तालिका बना सकता था।

    क्रिएट व्यू ओरिजिनल_टैब_वीडब्ल्यू एएस
    A.col1, a.col3, a.col4, a.col2 का चयन करें
    मूल_तब से
    जहां भी a.col1 है, जो भी पूरा नहीं है
    सेलेक्ट * INTO new_table से original_tab_vw

मूल तालिका का नाम बदलें या छोड़ें और नई तालिका का नाम पुरानी तालिका पर सेट करें।


2
यह एक बहुत ही उचित समाधान की तरह लगता है। यह बहुत बुरा है कि इस प्रक्रिया को स्वचालित करने के लिए कोई GUI उपकरण नहीं हैं।
क्वोलोनल प्रश्न

4
अच्छा समाधान लेकिन केवल डेटा प्रकार की प्रतिलिपि बनाई जाती है (कोई प्राथमिक कुंजी नहीं, आदि)
Regisz

1
वैकल्पिक रूप से - बस के रूप में reordered कॉलम के साथ दृश्य का उपयोग करें। न्यूनतम प्रदर्शन में गिरावट होनी चाहिए।
पीएससी

1
यह सबसे अच्छा उपाय है।
निकोले शिंदारोव

23

एक, स्तम्भों को पुनर्व्यवस्थित करने के लिए एक अनाड़ी विकल्प के साथ, जब स्तंभ क्रम बिल्कुल बदला जाना चाहिए, और विदेशी कुंजी उपयोग में है, पहले डेटा के साथ पूरे डेटाबेस को डंप करना है, फिर बस स्कीमा ( pg_dump -s databasename > databasename_schema.sql) को डंप करें । इसके बाद कॉलम को फिर से व्यवस्थित करने के लिए स्कीमा फ़ाइल को संपादित करें, फिर आप डेटाबेस को स्कीमा से फिर से बनाएँ, और अंत में नए बनाए गए डेटाबेस में डेटा को पुनर्स्थापित करें।


1
एक गिरावट क्यों? जैसा कि स्वीकृत उत्तर बताते हैं, PostgreSQL Wiki को उद्धृत करते हुए: »कॉलम ऑर्डर को बदलने का एकमात्र तरीका या तो तालिका को फिर से बनाना, या कॉलम जोड़ना और डेटा को तब तक घुमाना है जब तक आप वांछित लेआउट तक नहीं पहुंच जाते।» यह समाधान इष्टतम नहीं है (इनमें से कोई भी उत्तर कार्य को पूरा करने के लिए अंतर्निहित ऑपरेशन की अनुपस्थिति में है), लेकिन यह एक तालिका में स्तंभों को पुनर्व्यवस्थित करने का एक तरीका प्रदान करता है।
विले

1
मैं फिर से कहता हूं, ऐसा करने के लिए कोई अच्छा तरीका नहीं है, और जो मैं ऊपर उल्लिखित करता हूं वह स्तंभों को पुनर्व्यवस्थित करने का एक वैध तरीका है यदि उन्हें बिल्कुल पुनर्व्यवस्थित किया जाना चाहिए। यदि आप मेरे उत्तर को अस्वीकार करते हैं, तो कृपया टिप्पणी करें कि आप इसे अस्वीकार्य समाधान क्यों मानते हैं।
विले

3
वास्तव में, यह एक बहुत अच्छा समाधान है जब तालिका अन्य तालिकाओं में विदेशी कुंजी है। अन्य सभी समाधान इस एसेनारियो में काम नहीं करते हैं। अंत में, pg_dump --column- आवेषण -s databasename> databasename_schema.sql
अलेजांद्रो सलामांका मजुएलो

9

मुझे नहीं लगता कि आप वर्तमान में कर सकते हैं: Postgresql विकि पर इस लेख को देखें ।

इस लेख के तीन वर्कअराउंड हैं:

  1. तालिका को पुन: बनाएँ
  2. कॉलम जोड़ें और डेटा स्थानांतरित करें
  3. किसी दृश्य के साथ अंतर छिपाएं।

5

PGAdmin में तालिका खोलें और तल पर SQL फलक में SQL बनाएँ तालिका कथन की प्रतिलिपि बनाएँ। फिर Query Tool खोलें और पेस्ट करें। यदि तालिका में डेटा है, तो तालिका का नाम बदलकर 'new_name' करें, यदि नहीं, तो ड्रॉप टेबल लाइन में टिप्पणी "-" को हटा दें। आवश्यकतानुसार स्तंभ क्रम संपादित करें। यदि आपने इसे स्थानांतरित किया है, तो अंतिम कॉलम में अनुपलब्ध / शानदार अल्पविराम का ध्यान रखें। नए SQL बनाएँ तालिका आदेश निष्पादित करें। ताज़ा करें और ... voilà।

डिजाइन चरण में खाली तालिकाओं के लिए यह विधि काफी व्यावहारिक है।

यदि तालिका में डेटा है, तो हमें डेटा के कॉलम अनुक्रम को भी पुनर्व्यवस्थित करने की आवश्यकता है। यह आसान है: INSERTअपने नए संस्करण में पुरानी तालिका को आयात करने के लिए उपयोग करें:

INSERT INTO new ( c2, c3, c1 ) SELECT * from old;

... जहां c2, c3, c1स्तंभ हैं c1, c2, c3अपने नए पदों में पुराने तालिका के। कृपया ध्यान दें कि इस मामले में आपको संपादित 'पुरानी' तालिका के लिए एक 'नए' नाम का उपयोग करना होगा , या आप अपना डेटा खो देंगे । यदि स्तंभ के नाम कई हैं, तो एक पाठ संपादक में नई तालिका संरचना की प्रतिलिपि बनाने के लिए लंबे और / या जटिल एक ही विधि का उपयोग करते हैं, और INSERTबयान में प्रतिलिपि करने से पहले नया कॉलम सूची बनाएं ।

यह जांचने के बाद कि सब कुछ ठीक है, DROPपुरानी तालिका और 'नया' नाम बदलकर 'पुरानी' का उपयोग करना ALTER TABLE new RENAME TO old;और आप कर चुके हैं।


1

मैं बहुत सारी टेबलों को फिर से ऑर्डर करने पर काम कर रहा था और मैं नहीं चाहता था कि मैं एक ही तरह के सवाल लिखूं और इसलिए मैंने एक स्क्रिप्ट बनाई जो यह सब मेरे लिए कर सके। अनिवार्य रूप से, यह:

  1. तालिका निर्माण SQL से हो जाता है pg_dump
  2. डंप से सभी उपलब्ध कॉलम हो जाता है
  3. वांछित क्रम में कॉलम डालता है
  4. pg_dumpडेटा के साथ री-ऑर्डर की गई तालिका बनाने के लिए मूल क्वेरी को संशोधित करता है
  5. पुरानी टेबल को गिराता है
  6. पुरानी तालिका से मिलान करने के लिए नई तालिका का नाम बदलता है

इसका उपयोग निम्नलिखित सरल कमांड चलाकर किया जा सकता है:

./reorder.py -n schema -d database table \
    first_col second_col ... penultimate_col ultimate_col --migrate

यह sql को प्रिंट करता है ताकि आप इसे सत्यापित कर सकें और इसका परीक्षण कर सकें, यह एक बड़ा कारण था जिसके आधार पर मैंने इसे बनाया pg_dump। आप यहाँ जीथब रेपो पा सकते हैं ।


0

यदि आप सिरदर्द नहीं चाहते हैं तो मैं Django का उपयोग करता हूं और प्रत्येक तालिका में आईडी कॉलम की आवश्यकता होती है। दुर्भाग्य से, मैं लापरवाह था और मेरी तालिका bp.geo_location_vague में यह फ़ील्ड शामिल नहीं था। मैंने छोटी चाल की शुरुआत की। चरण 1:

CREATE VIEW bp.geo_location_vague_vw AS
    SELECT 
        a.id, -- I change order of id column here. 
        a.in_date,
        etc
    FROM bp.geo_location_vague a

चरण 2: (बिना तालिका बनाए - तालिका स्वचालितता बनाएगी!)

SELECT * into bp.geo_location_vague_cp2 FROM bp.geo_location_vague_vw

चरण 3:

CREATE SEQUENCE bp.tbl_tbl_id_seq;
ALTER TABLE bp.geo_location_vague_cp2 ALTER COLUMN id SET DEFAULT nextval('tbl_tbl_id_seq');
ALTER SEQUENCE bp.tbl_tbl_id_seq OWNED BY bp.geo_location_vague_cp2.id;
SELECT setval('tbl_tbl_id_seq', COALESCE(max(id), 0)) FROM bp.geo_location_vague_cp2;

क्योंकि मुझे टेबल में बिगसेरियस स्यूडोटाइप है। SELECT * के बाद pg में bigint टाइप insetad bigserial बनाएगा।

चरण 4: अब हम दृश्य को छोड़ सकते हैं, स्रोत तालिका छोड़ सकते हैं और पुराने नाम में नई तालिका का नाम बदल सकते हैं। चाल सफलतापूर्वक समाप्त हो गई थी।


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