13 Мар

Настройка подключений к нескольким базам данных в Rails.

Решил сделать перевод на русский язык статьи Setting up multiple databases in Rails: the definitive guide

(By Roberto Ostinelli / December 2, 2015).

Переводчик я непрофессиональный, поэтому в некоторых местах буду позволять себе вольности, но общий смысл будет сохранен.

Статья написана для Rails 4, но работает и в Rails 5 тоже, по крайней мере, на момент перевода статьи. 

———————

Может быть множество разных причин, зачем вам может понадобиться подключение к нескольким базам данных в вашем Ruby in Rails приложении. В моём случае необходимо было хранить большое количество данных, отражающих поведение пользователя: клики, посещаемые страницы, изменения истории и т. д.

Такие типы баз данных обычно не критичны для основной цели, а разрастаются намного быстрее (и до гораздо бОльших размеров), чем другие БД.

Требования к ним достаточно разнообразны: к примеру, они требуют больше пространства, более терпимы к аппаратным и программным сбоям, а также у них в приоритете идёт запись в базу, а не чтение. По этим причинам иногда выгодно отделить такие БД от основной базы вашего приложения. Зачастую для таких задач используются нереляционные СУБД, что уже выходит за пределы темы, по которой писалась данная статья.

Я нашел и прочитал множество различных решений, но я так и не смог найти такого, которое бы полностью выполняло следующие условия:

  • Должны быть различные и изолированные друг от друга миграции и схемы для каждой базы данных
  • Должны использоваться генераторы Rails для создания новых миграций для каждой БД, независимо друг от друга
  • Должны присутствовать специфические для баз данных задания rake для основных операций над БД (например такие же, как и для основной БД)
  • Должна быть интеграция с заданиями spec RSpec’а.
  • Должно работать с Database Cleaner
  • Должно работать на Heroku

Это мой взгляд на то, как удовлетворить все вышеуказанные требования и получить полностью рабочее Rails-приложение с подключением к нескольким БД.

Читать далее

25 Авг

Формат даты OLE

В БД одной из программ, с которой мне довелось столкнуться, дата записывалась числом в следующем формате 42004.9492447917.
Сначала я немного не понял, потом поискал в интернете и всё понял.
В общем, это запись даты в формате OLE (так называемый OLE Automation Date или дата с плавающей точкой).

Логика переформатирования в обычную дату следующая:
число до запятой — количество дней, прошедших с полуночи 30 декабря 1899 года
число после запятой  — часть дня, которая прошла с его начала. То есть если в сутках у нас 86400 секунд, то полдень будет выражен числом 0.5, как-то так.

То есть, если нам нужно перекодировать число 42004.9492447917 в обычную дату, считаем, то получаем следующее:
42004 — это 42004-й день с 30 декабря 1899 года, то есть 01 января 2015 года
0.9492447917 — это количество секунд, которое прошло с 00:00 этого же дня, разделенное на общее количество секунд в сутках, то есть 0.9492447917*86400 = 82014 секунды, то есть 22 часа 46 минут 54 секунды.
В итоге получаем дату: 01.01.2015 22:46:54

Написал пару небольших функций на RUby для конвертирования дат из одного формата в другой.
Для начала, конечно же, запросим require 'time'

Из OLE в стандартный формат:

def convert_time(t)
 puts Time.at((time.to_f - 25569) * 86400).utc
end

utc в конце необходим для того, чтобы вам выдалось время без поправки на вашу таймзону.
time.to_f — конвертируем входные данные в float
(time.to_f - 25569) — делаем началом отсчета 1 января 1970 года
((time.to_f - 25569) * 86400) — конвертируем дату в Unix time

Из стандартной даты в OLE:

def to_ole(t)
 Time.parse(t).to_f/86400 + 25569
end

Здесь изначально дата должна быть в любом подходящем формате и обязательно с указанием UTC, иначе скрипт будет прибавлять или отнимать к нужному времени количество часов для подгонки под локальное время.
Собственно всё.

09 Окт

PHP + MSSQL

Попросили меня тут на днях сделать простенький интерфейсик для работы с базой данных одной программы по управлению доступом (СКУД). Но дело в том, что там используется база MSSQL.
Не, ну а чо, микрософт, так микрософт. Начал рыть инфу, что да как делать. В общем, нашел такую штуку как FreeTDS — это драйвер для подключения как раз-таки к нужной мне БД.
Поставил, прогеморроился полдня с ней, но так и не получилось настроить. В итоге начал искать другие варианты.
И наткнулся на одном сайте, что с php, установленной через apt-get, не очень кошерно использовать тулзы, установленные из исходников. Подсказали, что при таком варианте достаточно доустановить просто
apt-get install libsybdb5 freetds-common php5-sybase
/etc/init.d/apache2 restart

В общем, установил, рестартнул Апач, в коде пхп прописал что-то типа такого:

  try {
    $hostname = "server_ip";
    $port = 1433;
    $dbname = "DatabaseName";
    $username = "Login"; 
    $pw = "Password"; 
    $pdo = new PDO ("dblib:host=$hostname:$port;dbname=$dbname",$username,$pw);
  } catch (PDOException $e) {
    echo "Failed to get DB handle: " . $e->getMessage() . "\n";
    exit;
  }

и всё волшебным образом заработало!