Конвертировать JSONB в XML в Postgres - PullRequest
2 голосов
/ 16 января 2020

У меня есть таблица, аналогичная

CREATE TABLE documents (
  id SERIAL PRIMARY KEY,
  author_id INTEGER NOT NULL FOREIGN KEY REFERENCES(author.id)
  content XML NOT NULL,
  created TIMESTAMP WITH TIMEZONE NOT NULL DEFAULT CURRENT_TIMESTAMP
)

Я хочу перевести базу данных с использования XML на JSONB для хранения этих данных. Я хотел бы сделать это в 3 этапа:

  1. Создать некоторые представления / функции, которые на лету преобразуют существующие данные в JSONB; Появление через Postgrest API
  2. Перенос существующей системы с использования XML на использование JSONB, удаление старого кода API
  3. Преобразование столбца из XML в JSONB навсегда

Это позволяет программному обеспечению работать со старым API (используя данные XML), в то время как я реорганизую его части для использования нового API (JSONB). После завершения рефакторинга я могу отключить старые XML - счастливые дни.

Я нашел этот ответ для преобразования данных из XML в JSONB: Как преобразовать XML в JSONB в Postgres

С некоторыми изменениями я могу сделать так, чтобы он (очень) близко соответствовал моему существующему коду. Короче говоря, я могу преобразовать это:

<xml>
  <hello>world</hello>
  <this is="your">captain</this>
</xml>

в это

{
    "xml": {
        "@tag": "xml",
        "this": {
            "@tag": "this",
            "@value": "captain",
            "@attributes": {
                "is": "your"
            }
        },
        "hello": {
            "@tag": "hello",
            "@value": "world",
            "@attributes": {}
        },
        "@value": null,
        "@attributes": {}
    }
}

РЕДАКТИРОВАТЬ: выше был немного изменен благодаря обратной связи от @ 404

Но мне понадобится какой-то способ, позволяющий измененному коду отправлять JSONB в новый (Postgrest) API, а затем эти данные будут преобразованы в XML, чтобы его можно было по-прежнему использовать. по нерефакторированному коду.

Я посмотрел на XML функции , но я изо всех сил стараюсь сделать так, чтобы я мог динамически преобразовывать JSONB обратно в * Форма 1073 * (не имеет особого значения, если она немного грязная, пока я могу вернуться к форме JSON позже). Похоже, я могу сделать это ОК

SELECT xmlelement(name hello, null, 'world')

Но когда я пытаюсь сделать это

SELECT xmlelement(name key, null, value)
FROM jsonb_each('{
        "this": {
            "@value": "captain",
            "@attributes": {
                "is": "your"
            }
        },
        "hello": {
            "@value": "world",
            "@attributes": {}
        },
        "@value": null,
        "@attributes": {}
    }'
)

Как и следовало ожидать, вы получите XML вывод, как это ...

<key>{"@value": "captain", "@attributes": {"is": "your"}}</key>

... где элемент XML называется " ключ ", а не значение ключа столбец ( в данном случае «this»).

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

Есть ли способ динамической установки имен тегов элементов XML и имен атрибутов?

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

...