Как использовать DBI :: dbConnect () для чтения и записи таблиц из нескольких баз данных - PullRequest
0 голосов
/ 09 марта 2020

У меня есть сервер Netezza SQL, к которому я подключаюсь с помощью DBI :: dbConnect. На сервере есть несколько баз данных, которые мы назовем db1 и db2.

Я хотел бы как можно больше использовать dbplyr и пропустить необходимость писать SQL код в RODB C :: sqlQuery (), но я не уверен, как сделать следующее:.

1) Как прочитать таблицу в db1, поработать над ней и заставить сервер записать результат в таблицу в db2, не проходя через мой рабочий стол?
2) Как выполнить левое соединение между таблицей в db1 и другой в db2?

Похоже, что может быть способ подключения к базе данных = "SYSTEM" вместо database = "db1" или "db2", но я не уверен, что будет следующим шагом быть.

con <- dbConnect(odbc::odbc(),
             driver = "NetezzaSQL",
             database = "SYSTEM",
             uid = Sys.getenv("netezza_username"),
             pwd = Sys.getenv("netezza_password"),
             server = "NETEZZA_SERVER",
             port = 5480)

1 Ответ

0 голосов
/ 10 марта 2020

Я работаю над этой проблемой на сервере SQL, используя in_schema и dbExecute следующим образом. Предполагая, что Netezza не слишком отличается.

Часть 1: общее соединение

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

con <- dbConnect(...) # as required by your database

table_1 <- dplyr::tbl(con, from = dbplyr::in_schema("db1", "table_name_1"))
table_2 <- dplyr::tbl(con, from = dbplyr::in_schema("db2.schema2", "table_name_2"))

Хотя in_schema предназначен для передачи имен схем, вы также можете использовать это для передачи имени базы данных (или обоих с точкой между ними). ​​

Теперь должно работать без проблем:

# check connection
head(table_1)
head(table_2)

# test join code
left_join(table_1, table_2, by = "id") %>% show_query()
# check left join
left_join(table_1, table_2, by = "id") %>% head()

Часть 2: запись в базу данных

Удаленная таблица определяется двумя вещами

  1. Соединение
  2. Код текущего запроса (например, результат show_query)

Мы можем использовать их с dbExecute для записи в базу данных. Мой пример будет с SQL сервером (который использует INTO в качестве ключевого слова, вам придется адаптироваться к вашей собственной среде, если синтаксис sql отличается).

# optional, extract connection from table-to-save
con <- table_to_save$src$con

# SQL query
sql_query <- paste0("SELECT *\n",
                    "INTO db1.new_table \n", # the database and name you want to save
                    "FROM (\n",
                    dbplyr::sql_render(table_to_save),
                    "\n) subquery_alias")
# run query
dbExecute(con, as.character(sql_query))

Идея это создать запрос, который может быть выполнен базой данных, которая будет писать новую таблицу. Я сделал это, обработав существующий запрос как подзапрос шаблона SELECT ... INTO ... FROM (...) subquery_alias.

Примечания:

  • Если запрос sql произведен с помощью show_query или sql_render будет работать, когда вы обращаетесь к базе данных напрямую, то вышеприведенное должно работать (все, что изменяется, это то, что команда приходит через R, а не через консоль sql).
  • Функции, которые я написал для сглаживания этого процесса для меня можно найти на здесь . Они также включают добавление, удаление, сжатие, индексирование и обработку представлений.
  • Запись таблицы с помощью dbExecute приведет к ошибке, если таблица уже существует в базе данных, поэтому я рекомендую сначала проверить это.
  • Я использую эту работу в других местах, но вставка имени базы данных с in_schema не сработала для создания представлений. Чтобы создать (или удалить) представление, я должен убедиться, что соединение с базой данных, где я хочу представление.
...