LINUX.ORG.RU

скопировать из одной таблицы в несколько со вставкой ID

 ,


0

1

У заказчика есть БД, корорую он ведёт в excel ~1000 строк. Я сделал под него БД на СУБД PostgreSql 9.3. Теперь стоит задача перекинуть из excel в PostgreSql. Поискав нашёл, что можно сначала сохранить в формате csv а потом с помощью COPY залить в мою БД. Проблема только в том, что как я понимаю он может залить только в одну таблицу. Как сделать так, что бы он копировал с разбивкой, учитывая связи типа многие ко многим? То есть надо, что бы он делал вставку в одну таблицу, потом в другую одновременно вытягивания ID вставляемых данных и вставлял полученные ID в третью таблицу. Ну допустим получить ID при вставке можно с помощью RETURNING а дальше, что с ним делать?

★★★★

Последнее исправление: leave (всего исправлений: 1)

Я для такого писал скриптик, который парсил файл и раскидывал по таблицам.

anonymous
()

Может создать файл со строками в виде

INSERT INTO MY_TABLE (ID, XXX, YYY) VALUES (111, 'xxx','yyy');
, предварительно создав нужные таблицы. А констрейнты потом добавить, после заливки данных.

looper
()

спасибо, ПОРЖАЛ..бедный заказчик :(

заполнить SQL базу из CSV:

сценарий1. Вы же на чём-то делали «базу» ? вот на том-самом $somelang и пишется..

сценарий2. В базе заводится таблица «rawfromcsv» и весь csv вливается туда. Далее средствами SQL раскидыватся по рабочим таблицам.

сценарий3. средствами AWK сделать из CSV создать файл с запросами(insert,update) к базе и их потом прогонять.

MKuznetsov ★★★★★
()
Ответ на: комментарий от keeper_b

Ну у меня проект был на питоне, поэтому тулзу для переноса данных из файла в БД я писал тоже на питоне, а в нем SQL-запросы через psycopg2.

anonymous
()
Ответ на: комментарий от MKuznetsov

спасибо, ПОРЖАЛ..бедный заказчик :(

А что? :) Я раньше базами не занимался. Вот приходится изучать.

Ну я пока иду по второму сценарию и как раз спрашиваю как оформить запрос на вставку в таблицу.

keeper_b ★★★★
() автор топика
Ответ на: комментарий от crutch_master

Запрос какой должен быть?

Пробовал так:

INSERT INTO student (surname, name, patronym, citizenship) 
(SELECT name1, name2, name3, country FROM import) RETURNING student_id 
INSERT INTO contract (contract_number, contract_date, payment, curriculum) 
(SELECT contract, datecontract, summcontract, spec FROM import) RETURNING contract_id INSERT INTO phone (student, calling_code, phone_number) (student_id) 
(SELECT code1, phone1 FROM import) INSERT INTO payment (payment_id, actual_amount_of_payment, date_of_pay) (contract_id) 
(SELECT summfact, datefact FROM import) 
INSERT INTO orders_admission (course_enrollment, department) (SELECT curs, fac FROM import) RETURNING order_admission_id 
INSERT INTO list_contract_student (student_id, contract_id) INSERT INTO list_student_in_admission (student_id, order_admission_id);
Не работает ошибка синтаксиса.

keeper_b ★★★★
() автор топика
Ответ на: комментарий от keeper_b

Да вот хрен его знает как там в PGSQL.
В MySQL есть Insert into <tablename> [(<fields list>)] <select>.Тут тоже по идее должен быть. Посмотри синтаксис команды insert ... select для PGSQL.

crutch_master ★★★★★
()
Последнее исправление: crutch_master (всего исправлений: 1)

можно python+xlwt+sqlalchemy

ggrn ★★★★★
()
Ответ на: комментарий от keeper_b

Запрос какой должен быть?

если делаете (а вы ведь делаете) процедуру, которая раскидает все данные из таблицы import по всем остальным, то см. синтаксис FOR в мануале по SQL :-) это проще всего. http://www.postgresql.org/docs/9.1/static/plpgsql-control-structures.html пункт 39.6.4.

MKuznetsov ★★★★★
()

Наверное как-то так: Шаг 1: Создается таблица куда складывается вся информация. Шаг 2: Пишется ХП, в которой разбрасывается инфа по базе, на время заполнения таблиц ограничения целостности лучше отключить.

nt_crasher ★★★
()
Ответ на: комментарий от keeper_b

Какая ошибка то? Небось ; не хватает между операциями?

kardapoltsev ★★★★★
()
Ответ на: комментарий от keeper_b

bash, python, что угодно чем умеешь пользоваться/больше нравится.

kardapoltsev ★★★★★
()
Ответ на: комментарий от anonymous

скриптик, который парсил файл и раскидывал по таблицам

+1

kardapoltsev ★★★★★
()
Ответ на: комментарий от keeper_b

да и вообще - забивай на постгресс, пока не поздно. Перелазь в энтерпрйзный оракле. На apex.oracle.com свояеш свою базу с белкджеком за пару дней.

Пока сокурсники/конкуренты будут воять аналог восхваляя божков опенсорс, разберёшься в основах и начнёшь по результатам халтурках таскать девчёнок по кабакам :-)

MKuznetsov ★★★★★
()

~1000 строк
БД на СУБД PostgreSql 9.3

молодец, правильно мыслишь, можно под это дело ещё и сервер купить и сторадж и коммутаторы и всё всё всё.

ukr_unix_user ★★★★
()

цена вопроса?

anonymous
()
Ответ на: комментарий от MKuznetsov

В общем получилось так:

CREATE OR REPLACE FUNCTION insert_students() RETURNS VOID AS
$$
DECLARE
  stud RECORD;
   
  _id1 int;
  _id2 int;
  _id3 int;
BEGIN
  FOR stud IN (SELECT code1, phone1, code2, phone2, code3, phone3, name1, name2, name3, contract, datecontract, summcontract, summfactsem, summfact, datefact, spec, academic_program, qualification, curs, country, fac FROM import) 
  LOOP
    INSERT INTO student (surname, name, patronym, citizenship) VALUES (stud.name1, stud.name2, stud.name3, stud.country) RETURNING student_id INTO _id1;
    INSERT INTO contract (contract_number, contract_date, payment, curriculum) VALUES (stud.contract, stud.datecontract, stud.summcontract, stud.spec) RETURNING contract_id INTO _id2;
    INSERT INTO list_contract_student (lstudent_id, lcontract_id) VALUES (_id1, _id2);
    INSERT INTO orders_admission (course_enrollment, department) VALUES (stud.curs, stud.fac) RETURNING order_admission_id INTO _id3;
    INSERT INTO list_student_in_admission (student_id, order_admission_id) VALUES (_id1, _id3);
    INSERT INTO payment (payment_id, actual_amount_of_payment, date_of_pay) VALUES (_id2, stud.summfact, stud.datefact);
    IF stud.code1 IS NOT NULL THEN
    INSERT INTO phone (student, calling_code, phone_number) VALUES (_id1, stud.code1, stud.phone1);
    END IF;
    IF stud.code2 IS NOT NULL THEN
    INSERT INTO phone (student, calling_code, phone_number) VALUES (_id1, stud.code2, stud.phone2);
    END IF;
    IF stud.code3 IS NOT NULL THEN
    INSERT INTO phone (student, calling_code, phone_number) VALUES (_id1, stud.code3, stud.phone3);
    END IF;
    RAISE NOTICE 'вы вставили значение с id1 = %, id2 = % и id3 = %', _id1, _id2, _id3;
  END LOOP;
END
$$ LANGUAGE plpgsql;

Всё работает как надо.

Тему закрываю.

keeper_b ★★★★
() автор топика

У заказчика есть БД, корорую он ведёт в excel ~1000 строк. Я сделал под него БД на СУБД PostgreSql 9.3. Теперь стоит задача

Ты ведь шутишь, правда?

ziemin ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.