2016-07-05 30 views
6

Là một phần của quy trình làm việc R của tôi cho một trong các dự án của tôi, tôi tải dữ liệu từ bảng postgreSQL trên máy chủ từ xa.Tạo đường hầm SSH cho máy tính khác qua R để truy cập bảng postgreSQL

Mã của tôi trông như thế này (thông tin đăng nhập ẩn danh).

Lần đầu tiên tôi mở kết nối ssh tới máy chủ từ xa trong thiết bị đầu cuối.

ssh -p Port -L LocalPort:IP:RemotePort servername" 

sau đó tôi kết nối với cơ sở dữ liệu Postgres trong R.

# Load the RPostgreSQL package 
library("RPostgreSQL") 

# Create a connection 
Driver <- dbDriver("PostgreSQL") # Establish database driver 
Connection <- dbConnect(Driver, dbname = "DBName", host = "localhost", port = LocalPort, user = "User") 

# Download the data 
Data<-dbGetQuery(Connection,"SELECT * FROM remote_postgres_table") 

Cách tiếp cận này hoạt động tốt, và tôi có thể tải dữ liệu với không có vấn đề.

Tuy nhiên, tôi muốn thực hiện bước đầu tiên - tức là, tạo kết nối ssh - trong R, thay vì ở đầu cuối. Đây là nỗ lực của tôi để làm như vậy, kèm theo lỗi.

# Open the ssh connection in R 
system("ssh -T -p Port -L LocalPort:IP:RemotePort servername") 

# Load the RPostgreSQL package 
library("RPostgreSQL") 

# Create a connection 
Driver <- dbDriver("PostgreSQL") # Establish database driver 
Connection <- dbConnect(Driver, dbname = "DBName", host = "localhost", port = LocalPort, user = "User") 

# Download the data 
Data<-dbGetQuery(Connection,"SELECT * FROM remote_postgres_table") 

Error in postgresqlExecStatement(conn, statement, ...) : 
RS-DBI driver: (could not Retrieve the result : server closed the connection unexpectedly 
This probably means the server terminated abnormally 
before or while processing the request. 

Để làm rõ câu hỏi của tôi, tôi muốn thực hiện toàn bộ công việc này (thiết lập kết nối, tải dữ liệu PostgreSQL) hoàn toàn bằng R mà không cần bất kỳ bước trong thiết bị đầu cuối.

+2

'system2 ("ssh", c ("- L8080: localhost: 80", "-N", "-T", "otherhost"), wait = FALSE) 'đã làm việc cho tôi trên linux. Tuy nhiên, không hoạt động trên các cửa sổ, có thể do thiếu 'fork', vì vậy bạn có thể cần một thứ gì đó trong nền (chẳng hạn như' parallel' hoặc ['future'] (https://github.com/HenrikBengtsson/future)) để chạy phiên R khác). Dừng nó có thể hoạt động với 'tools :: pskill', chưa được thử nghiệm. – r2evans

+0

@ r2evans Làm việc cho tôi, cảm ơn bạn. – Andy

Trả lời

2

Theo đề xuất của @ r2evans.

##### Starting the Connection ##### 
# Start the ssh connection to server "otherhost" 
system2("ssh", c("-L8080:localhost:80", "-N", "-T", "otherhost"), wait=FALSE) 

Bạn có thể giết quá trình bằng cách tìm và nhập thủ công trong pid hoặc tự động bằng cách tiêu diệt tất cả các pids khớp với tên máy chủ của bạn. Được cảnh báo rằng bạn chỉ muốn sử dụng phiên bản sau này nếu bạn đang sử dụng một tên máy chủ tương đối duy nhất mà không có khả năng được nhân đôi trong các quy trình khác.

##### Killing the Connection: Manually ##### 
# To end the connection, find the pid of the process 
system2("ps",c("ax | grep otherhost")) 
# Kill pid (x) identified by the previous grep. 
tools::pskill(x) 

##### Killing the Connection: Automatically ##### 
# To end the connection, find the pid of the process 
GrepResults<-system2("ps",c("ax | grep otherhost"),stdout=TRUE) 
# Parse the pids from your grep into a numeric vector 
Processes<-as.numeric(sub(" .*","",GrepResults)) 
# Kill all pids identified in the grep 
tools::pskill(Processes) 
0

Là một thay thế bạn có thể sử dụng plink với shell

library(RPostgreSQL) 
drv <- dbDriver("PostgreSQL") 

cmd<- paste0(
    "plink ", 
    # use key and run in background process 
    " -i ../.ssh/id_rsa -N -batch -ssh", 
    # port forwarding 
    " -L 5432:127.0.0.1:5432", 
    # location of db 
    " [email protected]" 
) 

shell(cmd, wait=FALSE) 
# sleep a while before the the connection been established. 
Sys.sleep(5) 

conn <- dbConnect(
    drv, 
    host = "127.0.0.1", 
    port=5432, 
    dbname="mydb", 
    password = "pass" 
) 

dbListTables(conn) 
Các vấn đề liên quan