Dplyr: Ich kann postgresql schema.table nicht mit dem dplyr-Paket verbinden

Erstellt am 6. Feb. 2014  ·  15Kommentare  ·  Quelle: tidyverse/dplyr

Ich habe diese Frage schon einmal geschrieben, um mehr über GitHub/hadley/dplyr zu erfahren.
http://stackoverflow.com/questions/21592266/i-cannot-connect-postgresql-schema-table-with-dplyr-package

Danke für dplyr, ggplots, reshape2 und .....

feature

Hilfreichster Kommentar

FWIW, für einige Anwendungsfälle ist ein hilfreiches Idiom:

dbSendQuery(con$con, build_sql("SET search_path TO ", schema_name))

Nachfolgende Abfragen, die diese Verbindung verwenden, befinden sich dann innerhalb dieses Schemas.

Alle 15 Kommentare

@hadley denke über deine Antwort nach Ich bin gekommen, um den vollständigen SQL-Satz zu schreiben

my_tbl = tbl(my_db, dplyr::sql('SELECT * FROM mortalidad.def0307'))

und dort konnte ich mich mit dem Schema und der Tabelle verbinden. Danke vielmals. – Diego

Ich wollte gerade das gleiche Problem posten, als ich mit Greenplum arbeitete. Ihre SQL-Methode hat mein Problem gelöst.

Damit bin ich zufrieden. Das einzige, was mich beunruhigt, ist, dass in der SQL-Anweisung Folgendes beachtet wird

SELECT "var1", count(*) AS "n" FROM (SELECT * FROM mortalidad.mort12)

wenn eine Gruppierung erfolgt ist. Es gibt eine Unterabfrage nach FROM und ich weiß nicht, ob dies irgendein Problem mit der Effizienz der SQL-Abfrage haben wird. Ich bin Epidemiologe und mir ist das nicht bewusst.

Würde es Ihnen etwas ausmachen, mir eine Sequenz von SQL-Befehlen zu geben, die ich in postgresql ausführen kann, um ein Schema und eine Datenbank in diesem Schema zu erstellen?

Entschuldigung für die Verzögerung, die ich hier sende, um ein Schema zu erstellen

CREATE TABLE schema_name.table_name
(
Codigo-Zeichen variieren(3),
Nombre-Zeichen variieren(51),
Kontinentaler Charakter variiert(7)
)

19.03.2014 18:56 GMT-03:00 Hadley Wickham [email protected] :

Würde es Ihnen etwas ausmachen, mir eine Sequenz von SQL-Befehlen zu geben, die ich ausführen kann?
postgresql, um ein Schema und eine Datenbank in diesem Schema zu erstellen?

Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf Gi tHub anhttps://github.com/hadley/dplyr/issues/244#issuecomment -38112148
.

Diego Garcilazo
Medizin
Departamento Programas de Salud
Instituto Nacional de Enfermedades Respiratorias
Ein V. Blas Parera 8260 // Santa Fe // Argentinien //0342 - 4896850
http://www.anlis.gov.ar/inst/iner/

Ich denke hier gibt es grundsätzlich zwei Möglichkeiten:

  1. Sonderfall mit Escapezeichen, wenn der Bezeichner einen Punkt enthält. Dies würde bedeuten, dass x.y zu "x"."y" entkommen würde. Dies hat den Vorteil, dass es sehr prägnant ist, es hat den Nachteil, dass von R nach SQL übersetzte Tabellen nicht . in Feldnamen verwenden können (wahrscheinlich nicht sehr häufig).
  2. Verwenden Sie einen neuen Fluchtmechanismus. Der einfachste Weg, dies zu tun, wäre wahrscheinlich, ident() um mehrere Argumente zu erweitern, zB ident("x", "y") . Alternativ könnte dot() was NSE macht, damit Sie dot(x, y) schreiben können. Dies ist mehr Tipparbeit, aber es wird garantiert kein bestehender Code beschädigt.

Dies ist wichtig sowohl für Tabellennamen (zB schema.table ) als auch möglicherweise um Feldnamen in Joins eindeutig zu machen (zB table.field )

Ich tendiere derzeit zur expliziten dot() Funktion, weil es riskant erscheint, die Funktionsweise von Escape global zu ändern.

Hmmmm, für diesen Anwendungsfall können Sie einfach Folgendes tun:

my_tbl <- tbl(my_db, sql('mortalidad.def0307'))

Und ein anderer Code für zukünftige Referenzen (war nicht erfolgreich)

dot <- function(...) {
  args <- dots(...)
  is_name <- vapply(args, is.name, logical(1))
  if (any(!is_name)) {
    stop("All arguments to dot() must be names.")
  }

  dots <- vapply(args, as.character, character(1))
  class(dots) <- c("ident_multi", "ident", "sql", "character")
  dots
}

dot <- function(...) {
  out <- paste(escape(c(...), parens = FALSE), collapse = ".")
  class(out) <- c("ident", "sql", "character")
  out
}

#' <strong i="6">@export</strong>
escape.ident_multi <- function(x, parens = FALSE, collapse = ", ", con = NULL) {
  y <- vapply(x, escape_ident, FUN.VALUE = character(1), con = con)
  paste(y, collapse = ".")
}

#' <strong i="7">@export</strong>
format.ident_multi <- function(x, ...) paste0("<SQL> ", paste(x, collapse = "."))

# lahman_sqlite() %>% tbl("Batting")
# lahman_sqlite() %>% tbl("main.Batting")
# lahman_sqlite() %>% tbl(sql("main.Batting"))
# lahman_sqlite() %>% tbl(dot("main", "Batting"))

Hallo Hadley,

Ich habe das gleiche Problem und die Verschachtelung scheint ein Problem für die Leistung zu sein (in meinem Fall ein schwerwiegendes, da ich an Daten mit 100 Millionen Zeilen arbeite). Könnten Sie erläutern, warum Ihr letzter Versuch fehlgeschlagen ist?

Vielen Dank

FWIW, für einige Anwendungsfälle ist ein hilfreiches Idiom:

dbSendQuery(con$con, build_sql("SET search_path TO ", schema_name))

Nachfolgende Abfragen, die diese Verbindung verwenden, befinden sich dann innerhalb dieses Schemas.

Hallo Harlan,

danke - und ich verwende so etwas bereits (außer ich erweitere den Suchpfad um das Schema. Aber es hilft nur bis jetzt. Wenn Sie Tabellen mit gleichen Namen in 2 Schemas haben, wird es nicht.

Wie auch immer, ich habe mich gefragt, warum nicht das '$'-Zeichen im base_scalar SQL-Übersetzer überladen wird.

Es wäre sogar aus r-Perspektive sinnvoll

a$b$c, wäre a eine Umgebung (dh ein Schema), eine Tabelle und eine Spalte ca. Der einzige Gedanke, der dann behoben werden muss, ist tbl_sql, das sollte nicht so einfach überprüfen, ob der Tabellenname in der Datenbank existiert. Stattdessen könnte es prüfen, ob eine "SELECT"-Anweisung Teil der SQL-Abfrage ist, und wenn nicht, ein SELECT * voranstellen und die Variablen auf diese Weise überprüfen.

Könnte man in diesem Fall sogar NSE für die tbl-Funktion aktivieren?

Ach ja, noch ein Kommentar:

dbSendQuery

funktioniert oft nicht für RJDBC (zumindest mit Vertica). Die obige Abfrage, dh SET search_path TO ...

gibt kein Ergebnis zurück. dbSendQuery erwartet eine. Für Vertica funktioniert dies nicht und man muss dbSendUpdate verwenden. Ist das auch bei MySQL der Fall (oder schlägt dbSendUpdate zumindest bei MySQL nicht fehl)?

Ich mag die Idee, $ überladen. Ich werde auf jeden Fall darüber nachdenken, wenn ich das nächste Mal an dplyr arbeite.

@hhoeflin haben Sie RPostgreSQL anstelle von RJDBC ausprobiert, um mit Vertica zu sprechen?

Nein - hatte keine Ahnung, dass RPostgreSQL eine Option ist. Jedenfalls - das vertica Backend ist jetzt schon für RJDBC implementiert. Hatte es jedoch versucht und stieß auf Probleme, da die Postgres-Tabellen, auf die es zuzugreifen versucht, um herauszufinden, welche Tabellen in der Datenbank vorhanden sind, unterschiedlich zu sein scheinen.

Dies wird langsam durch DBI gelöst: https://github.com/rstats-db/DBI/issues/24

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen