Лучшая практика для добавления данных в базу данных PostgreSQL? - PullRequest
0 голосов
/ 16 июня 2020

Я пытаюсь добавить статистический c объем данных из файла csv в базу данных postgresql, которую я размещаю на Heroku.

Изначально я делал это программно в моем файле application.py, который обслуживал веб-сервер с помощью flask. Я взаимодействую с базой данных с помощью SQLalchemy

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

for el in books:
   db.execute("INSERT INTO books (isbn, title) VALUES (:isbn, :title)",
             {"isbn": el[0], "title": el[1]})
   db.commit

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

Ответы [ 3 ]

1 голос
/ 17 июня 2020

Я понял, что, поскольку данные не меняются, я могу просто использовать команду sql COPY.

После запуска командной строки с psql DATABASE_URL я смог TRUNCATE таблицу для удалил все в нем, а затем я только что сделал:

\copy books(column_name_1, column_name_2,...) from 'path/to/csv' delimiter ',' csv header;

разделитель - это то, как ваши значения полей разделяются в заголовке csv, а параметр заголовка csv сообщает sql, что за разбивка файла csv есть. В моем случае заголовок csv был первой строкой, которую sql игнорирует параметром заголовка csv, это выглядело так:

isbn,title,author,year

Спасибо всем, кто ответил.

1 голос
/ 16 июня 2020

Вы пишете: «Я фиксирую одни и те же данные каждый раз, когда перезапускаю свой веб-сервер».

База данных постоянно хранит данные, что означает, что данные остаются в вашей базе данных (исключение - in- memory-db, но даже такой тип dbms позволяет хранить данные на диске).

В результате, после того, как вы запустили свой код n раз, данные должны быть там n раз (при условии, что вы также не отбрасываете каждый раз создание таблицы).

Вы можете легко проверить это, например, подсчитав вхождения isbn:

select count(isbn) as c, isbn from books group by isbn order by c desc;

Предполагая, что в csv каждый isbn уникален, все значения счетчика должны быть 1, но в вашем случае это скорее n.

Итак, очистите таблицу и выполните импорт один раз. Вставлять только новые данные, обновлять только существующие, измененные данные.

0 голосов
/ 17 июня 2020

Если данные в CSV никогда не изменяются, \ скопируйте их в базу данных сразу за пределами приложения, а затем отбросьте код, который это делает при запуске. Если вы ожидаете, что в будущем могут быть изменения, имейте код, который вы можете запускать либо внутри приложения (в разделе администратора, если он существует), либо снаружи. То, что делает этот код, будет зависеть от изменений. Если изменения просто добавляют или удаляют полные записи, вы можете обойтись чем-то вроде (псевдокода):

CREATE TEMP table data_staging(fields to match CSV);
\copy data_staging FROM  csv_file
--INSERT new items
INSERT INTO books() SELECT * from data_staging AS ds  LEFT JOIN books ON ds.isbn = books.isbn WHERE books.isbn IS NULL;
--If you want to DELETE
INSERT INTO books() SELECT * FROM books LEFT JOIN  data_staging AS ds    ON books.isbn = ds.isbn WHERE ds.isbn IS NULL;

ОБНОВЛЕНИЕ строк потребует дополнительной работы, так как вам нужно будет пройтись по записям и посмотреть, есть какие-либо изменения между таблицами промежуточного уровня и таблицами книг.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...