Hi I am using Database Library and Query Keyword to fetch the data from Database. The results that I am getting is by default List of values and to access the value I need to use the Index references like [0][1].
But I want to access my column values as [0].id.
I found the argument returnAsDict which gives the columnname and value, but still it is a List variable only and not a dictionary Variable.
I am not sure whether I am missing something here. Please help
Robot File Code:
*** Settings ***
Library DatabaseLibrary
*** Variables ***
*** Test Cases ***
TC1:WorkingModel
Connect To Database psycopg2 ${DBNAME} ${DBUSER} ${DBPASS} ${DBHOST} ${YB-DBPORT}
#{output} Query select id,description,sourcefrom test.details where id= '9TC1RDREG';
Log To Console ${output[0][0]}
Disconnect From Database
TC2:ExpectedModel
Connect To Database psycopg2 ${DBNAME} ${DBUSER} ${DBPASS} ${DBHOST} ${YB-DBPORT}
&{output} Query select id,description,sourcefrom test.details where id= '9TC1RDREG'; returnAsDict=True
Log To Console ${output[0].id}
Disconnect From Database
Results:
==============================================================================
TC1:WorkingModel ..9TC1RDREG
TC1:WorkingModel | PASS |
------------------------------------------------------------------------------
TC2:ExpectedModel | FAIL |
Cannot set variable '&{output}': Expected dictionary-like value, got list.
------------------------------------------------------------------------------
Test-Stack | FAIL |
2 tests, 1 passed, 1 failed
==============================================================================
You can actually see in the DatabaseLibrary documentation that the values are returned as a list of dictionaries. This would mean that the returned value is still a list, which you'll need to handle as such but each index within that list contains a dictionary of any keys and values on that specific row of data.
Consider a simplified example of the returned content
# The list as it would be returned normally
["value", "anothervalue"]
# The list when using returnAsDict = True
[{"key": "value"}, {"anotherkey": "anothervalue"}]
You'll need to still access the list index first and then look into the dictionary whether the value you want to get is there. This means that the dictionary approach will require more steps but does maintain an explicit connection between the values as they can be returned from the list in single dictionary.
As an example following should work
TC2:ExpectedModel
Connect To Database psycopg2 ${DBNAME} ${DBUSER} ${DBPASS}
... ${DBHOST} ${YB-DBPORT}
#{output}= Query select id, description, source from test.details where id= '9TC1RDREG';
... returnAsDict=True
Log To Console ${output[0]} # Log one dictionary entry from the list
&{dict_0}= Create Dictionary &{output[0]}
Log To Console ${dict_0["id"]} # Log single key from the dictionary on index 0
Disconnect From Database
Related
I am trying to write a robotframework test case that compares the row count of a table on HANA to the row count of a table in Cloudera.
My code would look something like this:
*** Keywords ***
#Part1
Setup My Test
Secure Connect to Hana ...
Retrieve the row count of the hana table
Name Query VCount SELECT COUNT(*) AS CNT FROM table1
${vcount} Run Named Query VCount
Teardown My Test
Disconnect From Database
*** Keywords ***
#Part2
Setup My Test
Secure Connect to Hive ...
Compare this to the row count of the cloudera table
Name Query RCount SELECT count(*) as count from table2
${rcount} Run Named Query RCount
Should Be Equal as Integers ${vcount} ${rcount}
Teardown My Test
Disconnect From Database
Is this possible? If not, is is possible to split Part 1 & 2 between two robot files, and store the result of Part 1 (i.e. the row count) in a variable of some kind and then call it into Part 2 so that a comparison can be done?
I have the following code:
*** Test Cases ***
Testing Connect to SQL Server
${queryTest} Execute Sql String SELECT * FROM users where Id='1'
#log to console ${queryTest} //This print NONE
#${query_results} SeleniumLibrary.Get Text ${queryTest}
#log to console ${query_results}
#${value}= Set Variable ${queryTest[0][0]}
log to console ${value}
log to console should display result
${rowCount}= Row Count SELECT * FROM users where Id='1'
log to console ${rowCount}
#rowCount print 1
What I'm trying to do is printing the query's result in the console
I think Execute Sql String doesn't return anything. There's no return statement in the method, and documentation doesn't mention such an example either (even though they mention a select statement with this keyword, which might be what leads people to believe they eventually get some rows back).
Try using Query keyword:
#{queryTest} Query SELECT * FROM users where Id='1'
there are 22 records on both tables. at records 1-21 it's was right but on record 22 on both table can't compare cause it's not equal. I would like to show result only failed record that's can't compare and let result fail.
connect to database using custom params cx_Oracle ${DB_CONNECT_STRING}
#{queryResults1}= Query Select * from QA_USER.SealTest_Security_A Order by SECURITY_ID
Log ${queryResults1}
#{queryResults2}= Query Select * from QA_USER.SealTest_Security_B Order by SECURITY_ID
Log ${queryResults2}
should be equal ${queryResults1} ${queryResults2}
Disconnect From Database
I need to pass the value stored in a global variable into another value of a variable.
Scenario :
I am Fetching a value from DB using SQL query and storing it in a global variable.
Now I would need to check whether the fetched value satisfies the
required condition for further testing. So in order achieve this I
need the pass the fetched value into second SQL query
Below is example code
*** Settings ***
Library Process
Library DatabaseLibrary
Library Selenium2Library
*** Variables ***
${query} SQL statement to fetch value from a table
${query2} SQL statement to check condition whether the ${query1} fetch
value satisfies required conditions
***Test Cases***
LINES TO CONNECT TO Db
${DBQueryresult} Query ${query}
Log ${DBQueryresult}
Set Global Variable ${GlobalVariable} ${DBQueryresult[0][0]}
Query ${query2}
I would need to pass this ${GlobalVariable} in ${query2} SQL statement.
How can this be achieved or is there any other way for this solution
Not totally clear on what you are trying but maybe this will help. You can imbed vars in the query strings using the ${}
*** Settings ***
Library Process
Library DatabaseLibrary
Library Selenium2Library
*** Variables ***
${query} SQL statement to fetch value from a table
${query_check} SQL statement to check condition whether the ${query} fetch
value satisfies required conditions
***Test Cases***
LINES TO CONNECT TO Db
${result} Query ${query}
Log ${result}
${check}= Query Check ${DBQueryresult[0][0]}
*** Keywords ***
Query Check ${result}
${other_result}= Query New_Query_with_${result}
[Return] ${other_result}
I'm trying to check if an item is in the database before attempting to delete it as part of my test setup.
The issue: The 'Check if Exists in Database' keyword works on its own, but not when combined with the built in keyword 'Run Keyword and Return Status'.
that gets the error: 'InterfaceError: not a query'
Code is below:
***Settings***
Documentation RF DB Test
Library DatabaseLibrary
***Variables***
${token} '<token>'
***Test Cases***
Set Log Level
Set Log Level TRACE
Connect to DB
Connect To Database Using Custom Params cx_Oracle <connection details>
Cleanup DB
${EntryExists}= Run Keyword and Return Status Check if Exists in Database select * from MY_TABLE where token=${token}
Edit
Thanks for your formatting answers and suggestions folks.
I also received the error for this line
Query delete from MY_TABLE where token=${token}
10:14:40.984 FAIL InterfaceError: not a query
10:14:40.984 DEBUG Traceback (most recent call last):
File "...Python\Python35\lib\site-packages\DatabaseLibrary\query.py", line 56, in query
allRows = cur.fetchall()
Basically, I was trying to use the delete command with the Query keyword, but found that the undocumented keyword 'Execute Sql String' worked
Execute Sql String delete from MY_TABLE where token=${token}
Keep your indentation consistent. I would suggest to use 4 spaces (set your IDE and that's it). I can see 4 spaces, 5 spaces, 2 spaces and most importantly: only one space between Check if Exists in Database and select * from MY_TABLE where token=${token}.
Note that RF takes more than two spaces as delimeter (see: http://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#plain-text-format) but one space is not enough.
Why did you created separate Test Case for every keyword?
I suppose your Test Case could look like:
***Test Cases***
Nice Name Of My Test Case
[Documentation] Let's not forget to describe
[Setup] Set Log Level TRACE
[Teardown] Disconnect From Database
Connect To Database Using Custom Params cx_Oracle <connection_details>
${entry_exists} Run Keyword And Return Status Check If Exists In Database select * from MY_TABLE where token=${token}
Run Keyword If '${entry_exists}' == 'True' DB Cleanup
Obviously all the current steps aren't enough for any meaningful Test Case, they should probably end up as a Test Setup, but that's, I believe, what you mean.
Add 4 spaces or tab after keyword "Check if Exists in Database" mentioned below.
${EntryExists}= Run Keyword and Return Status Check if Exists in Database select * from MY_TABLE where token=${token}
"Check if Exists in Database" keyword will return Boolean value(Pass/ Fail). So you don't required to use "Run Keyword And Return Status"