MySQL / 10. Импорт и экспорт данных

Проверка корректности и преобразование данных

Задача
Вам необходимо убедиться в том, что данные, содержащиеся в файле, корректны.

Решение
Проверьте их, возможно, преобразовав в более подходящий формат.

Обсуждение
Рассмотренные ранее в главе рецепты показывают, как работать со структурными характеристиками файлов, читая строки и разделяя их на отдельные столбцы. Это очень полезные операции, но часто приходится иметь дело не только со структурой файла данных, но и с его содержимым:

• Иногда разумно проверить значения данных на предмет их разрешенности для типов столбцов, в которых их планируется хранить. Например, можно проверить, являются ли значения, предназначенные для столбцов INT, DATE и ENUM, соответственно целыми числами, датами в формате CCYYMM- DD и разрешенными членами перечислимого типа.

• Значения данных могут потребовать переформатирования. Особенно часто встречается перезапись дат из одного формата в другой. Например, если вы импортируете файл FileMaker Pro в MySQL, то, вероятно, понадобится преобразование дат из формата MM-DD-YY в формат ISO. Если же действие выполняется в обратном направлении, из MySQL в FileMaker Pro, потребуется обратное преобразование дат, а также разбиение столбцов DATETIME и TIMESTAMP на отдельные столбцы даты и времени.

• Может возникнуть необходимость распознавания специальных значений. Значения NULL часто представляются значением, которое больше не встречается в файле, таким как -1, Unknown или N/A. Если вы не хотите, чтобы эти значения были переданы буквально, необходимо распознавать их и обрабатывать специальным образом.

Этот раздел начинает ряд рецептов, описывающих проверку корректности данных и способы форматирования, полезные в таких ситуациях. Рассматриваются: непосредственное сравнение, сравнение с образцом (pattern matching), проверка с использованием информации из базы данных. Некоторые операции проверки корректности встречаются снова и снова, так что, возможно, имеет смысл создать библиотеку функций. Упаковка операций проверки корректности в библиотеку упрощает создание использующих их утилит, а утилиты в свою очередь облегчают выполнение операций командной строки для целых файлов, избавляя вас от необходимости редактирования вручную.Создание цикла обработки ввода Многие из обсуждаемых рецептов являются типичными представителями проверок, выполняемых в программах, которые читают файл и проверяют значения отдельных столбцов. В общем виде утилиту подобной обработки файла можно записать так:

#! /usr/bin/perl -w
# loop.pl – Стандартный цикл обработки ввода
# Предполагаем, что строки ввода разделены символами табуляции,
# признак конца строки – перевод строки.
use strict;
while (<>) # читать каждую строку
{
chomp;
# разбить на части по символам табуляции, сохраняя все поля
my @val = split (/\t/, $_, 10000);
for my $i (0 .. @val - 1) # перебор столбцов строки
{
# ... test $val[$i] here ...
}
}
exit (0);

Цикл while() читает каждую строку ввода и разбивает ее на поля. Внутри цикла каждая строка разбита на поля. Затем внутренний цикл for() перебирает поля строки, обеспечивая их последовательную обработку. Если вы выполняете проверку не для всех полей одинаково, то следует заменить цикл for() отдельными проверками по столбцам. Цикл работает с вводом, элементы которого разделены символами табуляции, а признаком конца строки является символ перевода строки. Таким же предполагают ввод и большинство утилит, создаваемых в оставшейся части главы. Чтобы применять эти программы для файлов данных другого формата, можно преобразовать их в файл.

Размещение часто выполняемых проверок в библиотеке
Часто выполняемый тест можно оформить как библиотечную функцию. Операцию будет легко выполнять, кроме того, у нее появится имя, которое будет более понятным описанием производимого действия, чем сам код сравнения. Например, следующий тест выполняет сравнение с образцом, чтобы узнать, состоит ли $val целиком из цифр (возможно, предваренных знаком), затем проверяет, положительно ли значение:

$valid = ($val =~ /^\+?\d+$/ && $val > 0);

Другими словами, производится поиск строк, представляющих положительные целые числа. Чтобы упростить использование теста и сделать болеепонятным его предназначение, можно поместить его в функцию, которая будет применяться так:

$valid = is_positive_integer ($val);

Сама функция определяется следующим образом:

sub is_positive_integer
{
my $s = shift;
return ($s =~ /^\+?\d+$/ && $s > 0);
}

Теперь поместим определение функции в библиотечный файл, чтобы ее могли использовать различные сценарии. Файл модуля Cookbook_Utils.pm из каталога lib дистрибутива recipes является примером библиотечного файла, содержащего ряд функций проверки корректности данных. Посмотрите, может быть, какие-то его функции пригодятся вам при создании собственных программ (или в качестве модели для написания своих библиотечных функций).

Чтобы обратиться к модулю из сценария, включите в него предложение use: use Cookbook_Utils;

Естественно, необходимо установить файл модуля в каталоге, где Perl сможет его обнаружить.

Важное преимущество размещения набора утилит в библиотечном файле заключается в возможности использования их всяческими программами.

Задачи манипулирования данными редко бывают абсолютно уникальными. Если вы сможете использовать хотя бы несколько тестов на корректность из библиотеки, вполне вероятно, что объем создаваемого кода уменьшится, даже для очень специфичных программ.

Статьи по MySQL на эту тему:

Диагностическая утилита для LOAD DATA
Импорт XML в MySQL
Использование временных таблиц для преобразования дат
Использование дат с недостающими частями
Обмен данными между MySQL и FileMaker Pro

Вернуться в раздел: MySQL / 10. Импорт и экспорт данных