Вопрос или проблема
Я пытаюсь считать данные из CSV с помощью Liquibase и, естественно, пытаюсь использовать loadUpdateData
. В моем CSV есть колонка заголовка, которая является varchar
Данные для некоторых записей содержат $$
, и эти записи вызывают ошибку при вставке с использованием Liquibase. Когда я проверил запрос в логах, он показал следующее:
DO
$$
BEGIN
UPDATE public.ted_talk SET author=" Yelle", date="June 2018", likes = 7700, link = 'https://ted.com/talks/yelle_interpassion_ba_in', views = 259000 WHERE title=""Interpassion" / "Ba$$in"";
IF not found THEN
INSERT INTO public.ted_talk (title, author, date, views, likes, link) VALUES ('"Interpassion" / "Ba$$in"', ' Yelle', 'June 2018', 259000, 7700, 'https://ted.com/talks/yelle_interpassion_ba_in');
END IF;
END;
$$
Как вы знаете, $$ определяется как разделитель для включения блоков кода, и если данные содержат $$, он не может их разобрать. Как мне экранировать $$ так, чтобы Liquibase правильно распознавал строку и сохранял в БД.
Я пытался использовать символ экранирования, такой как \
, но это не помогло.
Я обратился к https://stackoverflow.com/questions/935/string-literals-and-escape-characters-in-postgresql и смог добавить E в начале и успешно выполнить это в БД напрямую.
Но как мне это вставить в Liquibase?
Документация говорит:
Строковая константа, заключенная в долларовые кавычки, состоит из знака доллара (
$
), необязательного “тега” из нуля или более символов, другого знака доллара, произвольной последовательности символов, составляющих содержимое строки, знака доллара, того же тега, который начал это долларовое цитирование, и знака доллара.
Таким образом, вы можете использовать, например
DO
$abc$
BEGIN
UPDATE public.ted_talk SET ... WHERE title=""Interpassion" / "Ba$$in"";
...
END;
$abc$;
Ответ или решение
Вопрос: Проблемы с вставкой данных в Liquibase, содержащих $$ при использовании loadUpdateData
При использовании Liquibase для загрузки данных из CSV-файла, вы столкнулись с проблемой, когда строки, содержащие символы $$, вызывают ошибки при вставке в базу данных. Это связано с тем, что в PostgreSQL символ $$ используется как ограничитель для многострочных строк и блоков кода.
Проблема
Когда в загружаемых данных встречается $$, PostgreSQL не может корректно интерпретировать строку, так как это символ начала и конца блока кода. Например, при попытке выполнения следующего SQL-запроса:
DO
$$
BEGIN
UPDATE public.ted_talk SET author=" Yelle", date="June 2018", likes = 7700, link = 'https://ted.com/talks/yelle_interpassion_ba_in', views = 259000 WHERE title=""Interpassion" / "Ba$$in"";
IF not found THEN
INSERT INTO public.ted_talk (title, author, date, views, likes, link) VALUES ('"Interpassion" / "Ba$$in"', ' Yelle', 'June 2018', 259000, 7700, 'https://ted.com/talks/yelle_interpassion_ba_in');
END IF;
END;
$$
Состояние, описанное выше, приводит к ошибке, так как PostgreSQL не может определить границы строки $$
, что делает трудным корректное преобразование и вставку данных.
Решения
-
Использование тега для долларового оформления строк:
Один из способов обхода этой проблемы состоит в том, чтобы использовать тег с долларовым оформлением, как было указано в официальной документации PostgreSQL. Например, вместо стандартного доллара вы можете определить собственный тег:DO $my_tag$ BEGIN UPDATE public.ted_talk SET ... WHERE title=""Interpassion" / "Ba$$in""; ... END; $my_tag$;
Здесь
my_tag
может быть любым уникальным значением, что позволит избежать путаницы с данными в вашей базе. -
Экранирование символов в Liquibase:
Liquibase не поддерживает автоматического экранирования символов $$ в строках. Однако вы можете использовать кавычки (например, одинарные или двойные), чтобы избежать конфликта с системой долларового оформления. -
Подготовка данных:
Если возможно, измените данные в вашем CSV, заменив $$ на альтернативные символы или предварительно обработав текст перед загрузкой данных. -
Обработка в SQL-скрипте:
Если вы хотите загружать данные через SQL-скрипты Liquibase, вы также можете написать промежуточные процедуры в SQL, которые будут обрабатывать ваши данные с использованием правильного форматирования и экранирования символов.
Заключение
Проблемы с символом $$ при использовании Liquibase для загрузки данных могут быть решены с помощью применения альтернативных тегов с долларовым оформлением и других методов экранирования. Эти подходы позволят вам загружать данные без ошибок и в полном объеме. Для более глубокого понимания данной проблема рекомендую обратиться к документации PostgreSQL по работе с долларовым оформлением строк.