Estou tentando executar um experimento de ciência de dados, conforme explicado neste tutorial . O tutorial tem 5 lições e cada lição tem algumas subseções.
Para este tutorial, estou usando
- uma máquina virtual SQL Server 2016 RC3 no Azure, com R Services habilitado.
- RRE para Windows 8.0.0 como um cliente de ciência de dados / R Client (para conexão remota ao SQL Server)
- Um novo SQL Login criado com acesso de leitura, gravação e ddl ao banco de dados - usado para conectar-se ao SQL Server por meio do cliente R.
Concluí com êxito a Lição 1, ou seja, criar objetos de dados do SQL Server a partir do meu cliente R, consultar e modificar dados do SQL Server e definir/definir contextos de computação.
Estou com um erro no início da Lição 2 do tutorial.
Depois que altero o contexto de computação de local para sql server, uma função simples de resumo (rxsummary) está gerando um erro.
O erro se parece com isso:
C:\Users\...\Project0\DeepDive Experiment.R(109): Error in try({ : ODBC statement error: [Microsoft][ODBC SQL Server Driver][SQL Server]Could not find stored procedure 'master..xp_ScaleR_init_job'. Error in rxInDbJobIdParam(schedulerJobInstance, FALSE) : hpcServerJob object has an invalid id. Ensure it was returned from a prior rxStartClusterJob() call Error in rxStartClusterJob(hpcServerJob, timesIsValidated = TRUE, continueOnFailure = FALSE) : Error in try({ : ODBC statement error: [Microsoft][ODBC SQL Server Driver][SQL Server]Could not find stored procedure 'master..xp_ScaleR_init_job'. Error in rxInDbJobIdParam(schedulerJobInstance, FALSE) : hpcServerJob object has an invalid id. Ensure it was returned from a prior rxStartClusterJob() call
Qualquer ajuda em
- por que esse erro está ocorrendo?
- como localizar/verificar procedimentos armazenados no banco de dados mestre - como verificar se xp_scaleR_init_job existe?
- como adicionar/criar o procedimento armazenado se ele não existir?
será apreciado.
Para facilitar o acesso, segue o script completo comentado até chegar ao erro:
###########################################DATA SCIENCE DEEP DIVE TUTORIAL###############################################
##Create the SQL Server Data Objects##
#Provide your database connection string in an R variable.
#DDUser01 is a login created on the sql server instance for remote login.
#It has read, write and ddl access to the DeepDive database.
sqlConnString <- "Driver=SQL Server;Server=*ip address*; Database=DeepDive;Uid=DDUser01;Pwd=*******"
#Specify the name of the table you want to create, and save it in an R variable.
sqlFraudTable <- "ccFraudSmall"
#Chunking
sqlRowsPerRead = 5000
#Define a variable to store the new data source
sqlFraudDS <- RxSqlServerData(connectionString = sqlConnString,table = sqlFraudTable, rowsPerRead = sqlRowsPerRead)
#Create a new R variable, sqlScoreTable, to store the name of the table used for scoring.
sqlScoreTable <- "ccFraudScoreSmall"
#Define a second data source object
sqlScoreDS <- RxSqlServerData(connectionString = sqlConnString,table = sqlScoreTable, rowsPerRead = sqlRowsPerRead)
##Load Data into SQL Tables Using R##
#Create an R variable, and assign to the variable the file path for the CSV file.
ccFraudCsv <- file.path(rxGetOption("sampleDataDir"), "ccFraudSmall.csv")
#RxTextData function to specify the text data source.
inTextData <- RxTextData(file = ccFraudCsv, colClasses = c(
"custID" = "integer", "gender" = "integer", "state" = "integer",
"cardholder" = "integer", "balance" = "integer",
"numTrans" = "integer",
"numIntlTrans" = "integer", "creditLine" = "integer",
"fraudRisk" = "integer"))
#Call rxDataStep to insert the data into the SQL Server table
rxDataStep(inData = inTextData, outFile = sqlFraudDS, overwrite = TRUE)
#Variable for creating a path to the source file - score
ccScoreCsv <- file.path(rxGetOption("sampleDataDir"), "ccFraudScoreSmall.csv")
#RxTextData function to get the data and save it in the variable
inTextData <- RxTextData(file = ccScoreCsv, colClasses = c(
"custID" = "integer", "gender" = "integer", "state" = "integer",
"cardholder" = "integer", "balance" = "integer",
"numTrans" = "integer",
"numIntlTrans" = "integer", "creditLine" = "integer"))
#Call rxDataStep to overwrite the current table with the new schema and data.
rxDataStep(inData = inTextData, sqlScoreDS, overwrite = TRUE)
##Query the Data ##
#Use the function rxGetVarInfo and specify the data source you want to analyze
rxGetVarInfo(data = sqlFraudDS)
##Modify Metadata##
#Mapping of USA State abbreviations (categorical) to their integer identifiers
#Create an R variable that holds the vector of strings to add to it - different states of the USA.
stateAbb <- c("AK", "AL", "AR", "AZ", "CA", "CO", "CT", "DC",
"DE", "FL", "GA", "HI","IA", "ID", "IL", "IN", "KS", "KY", "LA",
"MA", "MD", "ME", "MI", "MN", "MO", "MS", "MT", "NB", "NC", "ND",
"NH", "NJ", "NM", "NV", "NY", "OH", "OK", "OR", "PA", "RI","SC",
"SD", "TN", "TX", "UT", "VA", "VT", "WA", "WI", "WV", "WY")
#Create a column information object that specifies the mapping of the existing integer values to the categorical levels
#This statement also creates factor variables for gender and cardholder.
ccColInfo <- list(
gender = list(
type = "factor",
levels = c("1", "2"),
newLevels = c("Male", "Female")),
cardholder = list(type = "factor",
levels = c( "1", "2"),
newLevels = c("Principal", "Secondary")),
state = list(type = "factor", levels = as.character(1:51), newLevels = stateAbb)
)
#Update the SQL Server data source that uses the updated data
sqlFraudDS <- RxSqlServerData(connectionString = sqlConnString,
table = sqlFraudTable, colInfo = ccColInfo,
rowsPerRead = sqlRowsPerRead)
#Query new information
rxGetVarInfo(data = sqlFraudDS)
##Create and Set a Compute Context##
#Specify the connection string for the instance where computations will take place.
sqlConnString <- "Driver=SQL Server;Server=*ip address*; Database=DeepDive;Uid=DDUser01;Pwd=*******"
#Specify the location of the shared directory (temp folder for workspace objects) and save it in a variable.
sqlShareDir <- paste("c:AllShare", Sys.getenv("USERNAME"), sep="")
#Create shared directory if it does not exist
if (!file.exists(sqlShareDir)) dir.create(sqlShareDir, recursive = TRUE)
#Specify how you want the output handled.
#Here, you are indicating that the R session on the workstation should always wait for R job results,
#but not return console output from remote computations.
sqlWait <- TRUE
sqlConsoleOutput <- FALSE
#Define the compute context object
sqlCompute <- RxInSqlServer(
connectionString = sqlConnString,
shareDir = sqlShareDir,
wait = sqlWait,
consoleOutput = sqlConsoleOutput)
#ALTERNATIVE:Enable Tracing on the Compute Context
sqlComputeTrace <- RxInSqlServer(
connectionString = sqlConnString,
shareDir = sqlShareDir,
wait = sqlWait,
consoleOutput = sqlConsoleOutput,
traceEnabled = TRUE, traceLevel = 7)
#Change Compute Context to the Server
rxSetComputeContext(sqlCompute)
##Compute Summary Statistics##
#Compute summary statistics for several of the variables
##THIS IS WHERE I FACE THE ERROR##
sumOut <- rxSummary(formula = ~gender + balance + numTrans + numIntlTrans + creditLine, data = sqlFraudDS)
Aparentemente, o SQL Server 2016 precisa de um R Server Client (RRE) que seja pelo menos 8.0.3. Este site fala sobre isso. Também recebi a mesma resposta do Suporte da Microsoft.
O servidor R que tenho é o RRE 8.0.0. Esse provavelmente foi o motivo do erro que recebi. Quando instalei o Microsoft R Client, o script funcionou (exceto rxCube)! Eu poderia enviar cálculos para o SQL Server e terminar o tutorial.
Se você digitar
rxGetOption("demoScriptsDir")
em seu console R, deverá ver o diretório onde estão os scripts de amostra, por exemploTrabalhe no script
RevoScaleR_SqlServer_GettingStarted.r
, pois ele contém todo o código - acho que estão faltando alguns bits (como osqlShareDir
bit). Eu também diria que esses scripts não são perfeitos, tive muitos problemas com eles, às vezes executá-los duas vezes ajudou.