Всем привет!

В этой статье я вам расскажу, как я переносил данные из MC Access в SQLite не используя дополнительных утилит или программ, только пакет MS Office и SQLite DB browser.

Немного предыстории

У меня была необходимость экспортировать базу данных из Access (а если точнее из формата .mdb) в SQLite. Совместимых форматов у этих СУБД нету (как оказалось) и мне пришлось придумывать как это можно сделать. И вот что я придумал:

Собственно гайд

Итак, у нас есть .mdb или .accdb (или любой другой формат, который поддерживает Access) и нам нужно получить что то вроде .db или .sqlite. Скажу сразу разнообразные онлайн-сервисы (даже если они есть) я рассматривать не хотел, так как о безопасности и скорости там речи не идёт, поэтому пришлось что то придумывать самому.

Сложность была так же в том, что моя подопытная БД была с Окном и это затрудняло возможность экспорта в некоторые форматы.

Перед тем как мы продолжим, я познакомлю вас с нашей подопытной БД:

MC Access с открытой БД хим. элементов
MC Access с открытой БД хим. элементов

Автор этой БД: Улыбышева Ирина Михайловна. Вы можете скачать оригинал здесь.

Моя же версия этой БД, переведённая на английский язык и экспортированная во множество форматов лежит на GitHub.


Ок, мы знакомы о подопытным, теперь можно приступать. Я скажу сразу, этот способ может показаться немного костыльным, но однако он работает. Если у вас есть другие предложения, по тому, как это можно сделать - пишите в комментарии к статье или в мне в телеграмм (ссылка будет в конце статьи).

Шаг 1. Открываем необходимую БД в Access, переходим во вкладку External Data (Внешние данные) нажимаем Export to Excel. После этого откроется диалоговое окно, в котором необходимо выбрать директорию в которую сохраним файл и формат, в котором сохраним.

Шаг 2. Открываем полученный файл в Excel (надеюсь не надо рассказывать как). И теперь мы можем произвести все необходимые манипуляции с таблицей, например перевести её другой язык и т.п. Когда закончили, нажимаем File > Export > Change File Type и выбираем CSV.

После этого жмём Save As, выбираем путь и сохраняем.

Шаг 3 - Финал. Открываем SQLite DB browser. Создаём новую БД, в меню File выбираем Import и выбираем подпункт Table from CVS. Выбираем интересующую нас таблицу, настраиваем и жмём ОК.

И теперь, можете делать с новой БД всё, что хотите. На этом гайд подошёл к концу. Если есть какие-то замечания - пишите.


От автора

Спасибо, что дочитали статью до конца, надуюсь она была вам полезна и сэкономила вам время. Если хотите повлиять на выход дальнейших статей, то можете подписаться на мой telegram-канал, там в том числе будут опросы касаемо выходов новых статей. Если хотите со мной связаться или предложить тему для статьи - мои контакты есть на сайте.

Ещё раз спасибо, что дочитали до сюда!

Удачи!

Комментарии (16)


  1. cartonworld
    10.09.2023 18:32
    +2

    Проще, кажется, использовать, например, DBeaver и Import MS Access DB into MySQL DB


    1. falmer
      10.09.2023 18:32
      -1

      Тогда статья получится значительно короче или не получится вовсе.


  1. Akina
    10.09.2023 18:32
    +11

    Совместимых форматов у этих СУБД нету (как оказалось)

    Обе СУБД прекрасно общаются с CSV - Access по щелчку пальцев экспортирует:

    SQLite точно так же без проблем импортирует (эта часть, слава богу, описана).

    Кстати, ничто не мешает прямо из Access подключиться к SQLite по ODBC (соответствующий пункт на скриншоте - имеется) и вообще перегнать данные напрямую, в принципе избегая промежуточного хранилища.

    И теперь мы можем произвести все необходимые манипуляции с таблицей, например перевести её другой язык и т.п. 

    Эхх.. и передача данных - через третьи руки, и их редактирование - опять через третьи руки..

    Больше всего похоже, что автор взялся за то, чем вообще никогда не занимался, но вместо серьёзного исследования и изучения сляпал абы как, лишь бы получилось.. а потом, вместо того, чтобы сдать работу и помалкивать о том, через какое место она делалась, ещё и выволок всё своё незнание на всеобщее обозрение. И даже гордится им..

    Вы бы, друг мой, не позорились, а?


  1. k-semenenkov
    10.09.2023 18:32

    Я на всякий случай оставлю это здесь (сорри, я автор) -
    https://ksdbmerge.tools/cross-dbms-diff-merge-overview.html
    Открываем в одной панельке файл аксес, в другом - файл с SQLite базой
    В бесплатной версии нужно будет пройтись по очереди по табличкам, для каждой нажать "выделить все записи" и "мерж". В платной можно это сделать сразу для всех таблиц.
    Из минусов, по крайней мере по сравнению с подходом из статьи - таблички в SQLite базе должны быть созданы заранее, с таким же набором колонок и первичным ключом (есть планы на будущее по импорту схемы, но пока сильно далекие).

    Еще наверно стоит отметить что в аксесе есть multivalue типы данных которые вряд ли могут быть нормально перелиты предложенными способами.


    1. Akina
      10.09.2023 18:32

      в аксесе есть multivalue типы данных которые вряд ли могут быть нормально перелиты предложенными способами

      Хорошо бы понять, о чём именно Вы ведёте речь... в любом случае всё нормально перельётся (правда, не в случае, когда приёмником выступает SQLite - уж больно бедненько там с типами), дав на выходе либо ENUM, либо SET. В последнем случае можно также воспользоваться JSON-массивом.

      Можно также подумать об автоматическом создании таблицы-словаря и внешнего ключа в неё.

      Ну и универсальный вариант - использование на приёмнике TEXT/BLOB поля,- может быть использован вообще практически в любом случае.


      1. k-semenenkov
        10.09.2023 18:32

        Я веду речь о https://support.microsoft.com/en-us/office/create-or-delete-a-multivalued-field-7c2fd644-3771-48e4-b6dc-6de9bebbec31. В значении поля такого типа будет лежать список, к мультивелью относятся в том числе и аттачмент поля.

        >> Можно также подумать об автоматическом создании таблицы-словаря и внешнего ключа в неё.
        Чтобы сохранить структуру, тут на каждое такое поле нужно создавать отдельную таблицу с отношением многие-к-одному на основной набор данных. В каких-то случаях и дополнительная таблица-словарь может быть полезна. В общем, потребует какого-то кастомного решения.


        1. Akina
          10.09.2023 18:32

          Ааа... ну это типичнейший SET. Сами данные - это маска битовых флагов, а в метаданных таблицы хранятся текстовые описания этих флагов. Очень хорошо такой тип данных, включая и начинку под капотом, описан, например, в Reference Manual у MySQL.

          Просто M$ не может же использовать стандартные именования, несолидно, им надо непременно что-то своё оригинальное выдумать... мир, правда, не прогибается, но надежда умирает последней.

          Чтобы сохранить структуру, тут на каждое такое поле нужно создавать отдельную таблицу с отношением многие-к-одному на основной набор данных

          Ну в принципе это куда как более правильное решение, чем использование SET. Костыль - он и есть костыль. Где-то упрощает, где-то усложняет. Но в простейших случаях как раз ему самое место.


          1. k-semenenkov
            10.09.2023 18:32

            Я знаком с SET в MySQL, на первый взгляд да, может быть похоже, но в общем случае - нет. Набор значений может задаваться внешней таблицей или запросом (аналог внешнего ключа). Даже если это фиксированный список как в SET - можно удалить значение из списка в "схеме" и при этом оставить уже выбранные значения в данных. В случае аттачментов это вообще произвольный список пар блоб плюс имя файла.
            Не уверен что плод больной фантазии MS, это вполне могло быть содрано из какого-нибудь файлмейкера - еще один популярный на западе инструмент для создания баз данных вместе с интерфейсом, наподобие аксесса.


            1. Akina
              10.09.2023 18:32

              Набор значений может задаваться внешней таблицей или запросом (аналог внешнего ключа).

              В любом из этих случаев мы имеем скрытую статическую таблицу либо запрос, причём работает оно на уровне интерфейса, а не на уровне самой БД. А само поле остаётся текстовым (или что там выбрано) - если изменить список, то ранее введённые значения, даже в новой версии списка отсутствующие, никакого отторжения у БД не вызывают. И флаг "ограничиться только значениями из списка" для уже существующих данных не помогает, хотя злостно нарушает целостность. То есть подсистема контроля непротиворечивости данных просто спит.


  1. edo1h
    10.09.2023 18:32

    Сложность была так же в том, что моя подопытная БД была с Окном

    что бы это значило?


    1. Akina
      10.09.2023 18:32

      Вероятно, речь идёт о том, что Аксессова БД содержала не только данные, но и интерфейс к ним - скажем, форму ввода и редактирования данных. Что, само собой, в SQLite ну никак не перетащить.


  1. Demiourgos
    10.09.2023 18:32
    +1

    Кажется я созрел для написания статей на Хабр.
    Если уж такое тут можно, то мне есть чего припомнить!


    1. theurus
      10.09.2023 18:32
      +1

      Напиши статью на хабре как правильно использовать rm -rf а то не все знают


      1. Demiourgos
        10.09.2023 18:32
        -1

        Со скриншотами и вертикальным видео с отзывами участников эксперимента?


  1. Didntread
    10.09.2023 18:32
    +1

    прямо вот так открывать и пересохранять экселем данные для миграции - такое себе, он может поменять их как ему вздумается, а что именно он поправил не напишет. Даже если вам сделали и прислали эксельку, нужно убедиться, что локаль в системе у вас и у создателя файла совпадает. Как указано выше, лучше использовать csv, и если и трогать их экселем, то импортировать через Data->Import Text File, аккуратно расставив типы данных в колонках.


  1. maledog
    10.09.2023 18:32

    Вспомнилось как во времена ковида англицкий минздрав потерял часть данных при экспорте через Excel. Не учел лимиты на количество столбцов. В вашем случае вы можете так же потерять строки сверх лимита Excel. А еще можно неслабо так споткнуться если при импорте из csv неправильно определится тип столбца, или данные не будут соответствовать полям таблицы. Так что, быстро? — да, надежно? — нет.