14 ноября 2010

Находясь в обожании postgresql

На данный момент нахожусь в поисках python-postgresql драйвера, и случайно заглянул на wiki postgresql.
В моем проекте есть функция автоматической генерации расписаний в соответствии с некоторыми условиями (диапазон, шаг). Но она пока несколько сложна для объяснения базовых принципов генерации списка дат. Лучше использую более простой пример. Для некоторого планирования существует таблица, содержащая список нерабочих дней предприятия. Данная таблица может заполняться как вручную, так и автоматически. Набросок "по-быстрому" функции заполнения таблицы воскресеньями (Никогда не повторяйте этого дома!). Лучше не вчитывайтесь, просто увидте цикл, и поймите мою ошибку. В целом функция генерирует на 700 дней вперед от сегодня.

CREATE OR REPLACE FUNCTION fill_holidays()
  RETURNS void AS
$BODY$
declare
currentDay date = current_date;
begin
<<for_loop>>
FOR i IN  1..700 by 1 LOOP
  if (date_part('dow', currentDay) = 0 and not exists (select _day from catalog_holidays where _day = currentDay)) then
  insert into catalog_holidays(_date) values (currentDay);
 end if;
 currentDay = currentDay + 1;
 raise notice '%',currentDay;
END LOOP for_loop;
return;
end;
 $BODY$
  LANGUAGE plpgsql;
COMMENT ON FUNCTION fill_holidays() IS 'Заполнить выходными';


Так делает среднестатистический c++ программист. А вот как надо делать. Цель та же, генерация на 700 дней вперед. Смотрите внимательно, а то вы можете случайно пропустить строчку, которая все это делает:

insert into catalog_holidays(_date) (select a::date from generate_series(current_timestamp, current_timestamp + '700 days', '1 day') a where extract('isodow' from a) = 7);
И не подумайте, что пытаюсь вас надуть неиспользованием хранимой процедуры и говорю о сокращении кода. В первом случае я использовал хранимую процедуру, потому что анонимных блоков в 8.4 еще не было. Во втором же случае вы видите, что хранимая процедура неуместна за отсутствием вспомогательной переменной и цикла.

А теперь внимание...сделайте для меня точно эту же операцию на oracle. А когда сделаете, подумайте, на что вы тратите свои деньги и время. Сравните приведение типов в этих двух СУБД, а еще сравните работу со датами/временем, пока я не сделал это за вас. Иногда мне кажеться, что одни люди занимаются "финансово-денежными операциями", а другие искусством создания программ. Но это уже совсем другая история...
Список литературы:
Scott Bailey 'Artacus'. Date Generator /  Postgresql Wiki

P.S. Мне действительно очень стыдно за первый вариант функции.

3 комментария:

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

    ОтветитьУдалить
  2. По поводу примера, ИМХО, правильнее было бы распарсить
    производственный календарь какой-нибудь.
    Для этого не обязателен слоник синий,
    но можно и с pl/perl поизвращаться.
    Один раз написать, и закроется вопрос навсегда.
    И имена полей в инсерте я бы всё-таки указал)))

    ОтветитьУдалить
  3. Спасибо, поправил.
    У куте впринципе работа с базой данных далека от совершенства.
    На данный момент рассматриваю создание python драйвера для postgresql с помощью cython c поддержкой конвертации типов, python callback notice receiver. А точнее обертка вокруг libpq уже готова. В начале 2010 года питонисты подняли вопрос, что postgersql драйвера устарели или имеют не свободные лицензии.
    В куте работу с базами данных можно улучшить, но только ценой доработки всей иерархии существующих классов. И определением своих qvariant конвертируемых типов.

    ОтветитьУдалить