Як змінити положення стовпця в таблиці бази даних PostgreSQL?


Відповіді:


106

" Змінити положення стовпця " в Wiki PostgreSQL:

На даний момент PostgreSQL визначає порядок стовпців на основі attnumстовпця pg_attributeтаблиці. Єдиний спосіб змінити порядок стовпців - або відтворити таблицю, або додавши стовпці та обертаючи дані, поки не досягнете потрібного макета.

Це досить слабко, але на їх захист, у стандартному SQL, немає рішення і для перестановки стовпця. Бренди баз даних, які підтримують зміну порядкового положення стовпця, визначають розширення до синтаксису SQL.

В мене виникає ще одна ідея: ви можете визначити a, VIEWякий визначає порядок стовпців, як вам це подобається, не змінюючи фізичне положення стовпця в базовій таблиці.


3
@Dana: Я думаю, що це означає "відтворення таблиці" у статті wiki.
Білл Карвін

2
'скидання бази даних': чудовий спосіб пошкодити дані. а отже, "очистити масивну базу даних" ефект.
Кент Фредрік

31
@Kent: Сумнівно, розробники постгресів пройдуть довгий шлях, щоб забезпечити узгодженість даних, і це, безумовно, стосується pg_dump. Зрештою, який сенс робити резервні копії db, якщо відновлення не працює?
Dana Sane

@Dana, так, але ви додаєте 1) великий процес скидання, а потім ви кидаєте, і тоді у вас є велике зайняття часу. Якщо у вас є серйозна масивна база даних, як правило, це стосується 37 стовпців, у вас виникнуть ризики задихатися вводу-виводу диска.
Кент Фредрік

@DanatheSane - це дуже старі коментарі, але те, що говорив Білл, - це по суті те саме, замість того, щоб робити повний дамп бази даних, ви просто скидаєте таблицю (і залежності), вбиваєте оригінал, а потім відтворюєте. Не потрібно брати всю базу даних в автономному режимі або витрачати час на створення нового, що не впливає. З іншого боку, якщо залежностей багато, я вважаю, що робити повний відвал (як ви запропонували) набагато простіше.
vol7ron

37

У 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;

4
Нічого це чудово, я впевнений, що це має бути прийнята відповідь!
Tommaso Thea Cioni

Так, це дуже корисно, спасибі велике!
Акуна

Ви також можете скопіювати поточну таблицю в нову стару таблицю на зразок цієї: СТВОРИТИСЯ ТАБЛИЦІ старого таблиці як ВИБРАТИ * ІМЯ таблиці;
Райан

29

Ця посада стара і, ймовірно, вирішена, але у мене було те саме питання. Я вирішив це, створивши подання вихідної таблиці із зазначенням нового порядку стовпців.

Звідси я міг або використовувати подання, або створити нову таблицю з подання.

    СТВОРИТИ ПОГЛЯД original_tab_vw AS
    ВИБІРИ a.col1, a.col3, a.col4, a.col2
    ВІД original_tab a
    ДЕ a.col1 НЕ НУЛЬНИЙ - або все одно
    SELECT * INTO new_table FROM original_tab_vw

Перейменуйте або видаліть оригінальну таблицю та встановіть назву нової таблиці на стару таблицю.


2
Це здається досить розумним рішенням. Дуже погано, що для автоматизації цієї процедури не існує інструментів GUI.
питання Quolonel

4
гарне рішення, але копіюються лише типи даних (немає первинного ключа тощо)
Regisz

1
Крім того, просто використовуйте подання з перепорядкованими стовпцями як є. Повинно бути мінімальне зниження продуктивності.
pscl

1
Це найкраще рішення.
Микола Шиндаров

23

Один, хоч і незграбний варіант змінити стовпці, коли порядок стовпців потрібно абсолютно змінити, а зовнішні ключі використовуються, - це спочатку скинути всю базу даних з даними, а потім скинути лише схему ( pg_dump -s databasename > databasename_schema.sql). Далі відредагуйте файл схеми, щоб переставити стовпці так, як вам хотілося, потім відтворіть базу даних зі схеми та нарешті відновіть дані у новоствореній базі даних.


1
Чому потік? Як зазначається у прийнятій відповіді, цитуючи PostgreSQL Wiki: »Єдиний спосіб змінити порядок стовпців - або відтворити таблицю, або додавши стовпці та обертаючи дані, поки не досягнете потрібного макета.» Це рішення не є оптимальним (жоден із цих відповідей не є вбудованою операцією для виконання завдання), але він дає спосіб переставити стовпці в таблиці.
Віль

1
Я знову кажу, що немає хороших способів це зробити, і те, що я окреслю вище, - це дійсний спосіб переставити стовпці, якщо вони абсолютно повинні бути переставлені. Якщо ви схвалюєте мою відповідь, будь ласка, прокоментуйте, чому ви вважаєте, що це неприйнятне рішення.
Віль

3
Насправді це дуже вдале рішення, коли таблиця є іноземним ключем в інших таблицях. Всі інші рішення не працюють у цьому есценаріо. Нарешті, використовуйте pg_dump - Column-inserts -s назва бази даних> databasename_schema.sql
Алехандро Саламанка Мазуело


5

Відкрийте таблицю в PGAdmin та на панелі SQL внизу скопіюйте оператор SQL Create Table. Потім відкрийте інструмент запитів і вставте. Якщо в таблиці є дані, змініть ім’я таблиці на "new_name", якщо ні, видаліть коментар "-" у рядку "Drop Table". Потрібно відредагувати послідовність стовпців Зверніть увагу на пропущену / зайву кому в останньому стовпчику, якщо ви її перемістили. Виконайте нову команду Створення таблиці SQL. Оновити та ... voilà.

Для порожніх таблиць на етапі проектування цей метод є досить практичним.

У випадку, якщо таблиця містить дані, нам потрібно також переставити послідовність стовпців даних. Це легко: використовуйте INSERTдля імпорту стару таблицю в її нову версію за допомогою:

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

... де c2, c3, c1є колонами c1, c2, c3зі старої таблиці в своїх нових позиціях. Зауважте, що в цьому випадку ви повинні використовувати "нове" ім'я для відредагованої "старої" таблиці, інакше ви втратите свої дані . У випадку, якщо імен стовпців багато, довгі та / або складні використовують той же метод, що і вище, щоб скопіювати нову структуру таблиці в текстовий редактор і створити там новий список стовпців, перш ніж скопіювати її в INSERTоператор.

Перевіривши, що все добре, DROPстару таблицю та змініть ім'я 'new' на 'old' за допомогою, 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. Ви можете знайти рефіти github тут .


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 буде створено інсетад bigserial типу bigint.

крок 4: Тепер ми можемо опустити подання, скинути вихідну таблицю та перейменувати нову таблицю у стару назву. Трюк закінчився успішно.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.