JSON value to be print by Python - json

I have created a script where I need to get each details of user that is being generated in JSON. What could be the possible way in order for me display the "name": "admin"?
Please see script below.
`
import xmlrpc.client
import json
class TestlinkAPIClient:
# substitute your server URL Here
SERVER_URL = "https://testserver"
def __init__(self, devKey):
self.server = xmlrpc.client.ServerProxy(self.SERVER_URL)
self.devKey = devKey
def getUserByLogin(self):
for userDetail in self.server.tl.getUserByLogin(dict(devKey=self.devKey,user='user1')):
user_status = int(userDetail.get("isActive")) #json(userDetails.json) value isActive = 1 else isActive = 0 for not active
lastname = userDetail.get("lastName")
firstname = userDetail.get("firstName")
userLogin = userDetail.get("login")
activeStatus = ("Active User")
globalrole = userDetail.get("globalRole")
tproject = userDetail.get("tprojectRoles")
#for role in tproject.values():
for projectID in tproject:
user_detail = (userLogin + " " + lastname + " " + firstname + " " + str(globalrole['name']) + " " + "ProjectID: " + projectID)
print(user_detail)
# substitute your Dev Key Here
client = TestlinkAPIClient("testlinkApiKey")
details = client.getUserByLogin()
with open('./DebugProjectRoleDetails.json', 'w') as f:
json.dump(details , f)
and here is the sample json format, hhere I should get an output of the "name": "admin"
[
{
"firstName": "UserFirst",
"lastName": "UserLast",
"emailAddress": "first.last#morpho.com",
"locale": "fr_FR",
"isActive": "1",
"defaultTestprojectID": "",
"globalRole": {
"name": "projectadmin",
}
"globalRoleID": "10",
"tprojectRoles": {
"1234": {
"name": "admin"
}
}
]
expected output:
0001 User projectadmin ProjectID: 1001 projectRoles=viewer

If userDetail is in a JSON file and you want to save it as a dictionary, so you can use the get() method, you need to use json.load:
import json
with open('./user.json') as f:
details = json.load(f)
Since tproject is also a dictionary you need to use get() to extract the role (value) corresponding to the project (key)
for userDetail in details:
user_status = int(userDetail.get("isActive"))
lastname = userDetail.get("lastName")
firstname = userDetail.get("firstName")
userLogin = userDetail.get("login")
activeStatus = ("Active User")
globalrole = userDetail.get("globalRole")
tproject = userDetail.get("tprojectRoles")
# for role in tproject.values():
for projectID in tproject:
role = tproject.get(projectID)
user_detail = f"{userLogin} {lastname} {firstname} {str(globalrole['name'])} ProjectID: {projectID} {role}"
print(user_detail)
ouput using your JSON sample:
None UserLast UserFirst projectadmin ProjectID: 1234 {'name': 'admin'}

I have noticed that it is possible to declare 2 items in a for loop.
dictionary_item_tproject = tproject.items()
for projectID,projectRole in dictionary_item_tproject:
print(userLogin + " " + lastname + " " + firstname + " " + str(globalrole['name']) + " " + str(projectID) + " " +str(projectRole['name']))
This solve my problem. Now I am able to parse JSON properly. Thanks everyone.

Related

Pattern for rest query params in flask

Is there a pattern for dealing with query params in a flask rest server? I know I can create a sql query word for word using string manipulation in python, but I find that to be ugly and error prone, I was wondering if there is a better way. Here's what I have:
param1 = request.args.get('param1', type = int)
param2 = request.args.get('param2', type = int)
if param1 is not None:
if param2 is not None:
cursor.execute("SELECT * FROM table WHERE p1 = %s AND p2 = %s", (str(param1), str(param2)))
else:
cursor.execute("SELECT * FROM table WHERE p1 = %s", (str(param1),))
else:
if param2 is not None:
cursor.execute("SELECT * FROM table WHERE p2 = %s", (str(param2),))
else:
cursor.execute("SELECT * FROM table")
It's easy to see the number of possible SQL statements is 2 to the number of parameters, which grows out of control... so, again, without using string manipulation to custom build the sql query, is there an idiom or pattern that is used to accomplish this in a more elegant way? Thanks.
Loop through your parameters.
params = []
for i in range(1, HoweverManyParamsYouNeed):
params.append(request.args.get('param' + str(i), type = int))
s = ""
for i in range(1, len(params)):
if params[ i ] is not None:
if not s:
s = "p" + str(i) + " = " + str(params[ i ])
else:
s = s + " AND p" + str(i) + " = " + str(params[ i ])
full = "SELECT * FROM table"
if s:
full = full + " WHERE " + s
cursor.execute(full)
You might need to correct this code, since I do not have a way to run it.
I suggest using ORM(https://en.wikipedia.org/wiki/Object-relational_mapping) instead of raw sql queries.
First you need install flask-sqlalchemy (https://flask-sqlalchemy.palletsprojects.com/)
Then define your model
class MyModel(db.Model):
id = db.Column(db.Integer, primary_key=True)
column1 = db.Column(db.Integer)
column2 = db.Column(db.Integer)
Let's say you have your filter lookup somewhere
allowed_filters = {"column1", "column2"}
Finally instead of cursor you can use SQLAlchemy's ORM to retrieve your filtered objects.
query = MyModel.query
for field, value in request.args.items():
if field in allowed_filters:
query = query.filter(getattr(MyModel, field) == value)
my_object_list = list(query.all())
If you really want to create your queries manually you can always iterate over args:
where_clause = ""
params = []
for field, value in request.args.items():
if field in allowed_filters:
if len(where_clause) > 0:
where_clause += " AND "
where_clause += "{} = %s".format(field)
params.append(value)
if len(where_clause) > 0:
cursor.execute("SELECT * FROM table WHERE {}".format(where_clause), tuple(params))
else:
cursor.execute("SELECT * FROM table")

sql: Scan error on column index 19, name "L2Name": unsupported Scan, storing driver.Value type <nil> into type *string

Using Golang and the built in database/sql library and the postgres lib/pq library, I'm trying to read from a database that has some null values in some of the records. the code compiles, but when I try to run it I get the following error:
sql: Scan error on column index 19, name "L2Name": unsupported Scan, storing driver.Value type <nil> into type *string
I have the struct like this:
// Assets Info Dataset
type AssetInfo struct {
Asset_id string
Asset_name string
Organisation_id string
LastCheckIn string
Asset_Status string
Asset_latitude string
Asset_longitude string
Organisation_name string
CurrentDevice_name string
AssetActiveDeviceType string
AssetSafetyTimer float32
TemplateName string
TemplateL2name string
TemplateL2contact string
TemplateL3name string
TemplateL3contact string
TemplateL4name string
TemplateL4contact string
TemplateEscalationNotes string
}
Here is my code:
db, err := sql.Open("mysql", "stevejc:19939c#tcp(127.0.0.1:3306)/johntcw_loneworker?charset=utf8")
checkErr(err)
defer db.Close()
for {
sqlstatement := "SELECT" +
" assets.ID, assets.Name, assets.LastCheckIn, assets.Status, assets.OffTimer," +
" assets.SafetyTimer, assets.HazardTimer, assets.HazardTimerStartedTime, assets.LastSignedOn," +
" assets.Latitude, assets.Longitude, assets.TemplateID, assets.ActiveDeviceType, assets.CurrentDeviceID," +
" assets.OffTimerTemp, assets.OrganisationID," +
" organisations.Name As OrganisationName," +
" devices.Label As CurrentDeviceName," +
" templates.Name As TemplateName, templates.L2Name, templates.L2Contact, templates.L3Name, templates.L3Contact," +
" templates.L4Name, templates.L4Contact, templates.Note" +
" FROM assets" +
" LEFT JOIN organisations ON assets.OrganisationID = organisations.ID" +
" LEFT JOIN devices ON assets.CurrentDeviceID = devices.ID" +
" JOIN templates ON assets.TemplateID = templates.ID" +
" WHERE assets.Status != 'Not monitoring' AND assets.AssetStatus = 'Active' AND assets.Display != '0'"
// select monitoring assets
rows, err := db.Query(sqlstatement)
checkErr(err)
for rows.Next() {
var assetid string
var name string
var lastcheckin string
var status string
var offtimer float32
var offtimertemp float32
var safetytimer float32
var hazardtimer float32
var hazardstarttime string
var lastsignedon string
var lat string
var lon string
var templateid string
var activedevicetype string
var currentdeviceid string
var organisationid string
var organisationname string
var currentdevicename string
var templatename string
var l2name string
var l2contact string
var l3name string
var l3contact string
var l4name string
var l4contact string
var escalationnotes string
err = rows.Scan(&assetid,
&name,
&lastcheckin,
&status,
&offtimer,
&safetytimer,
&hazardtimer,
&hazardstarttime,
&lastsignedon,
&lat,
&lon,
&templateid,
&activedevicetype,
&currentdeviceid,
&offtimertemp,
&organisationid,
&organisationname,
&currentdevicename,
&templatename,
&l2name,
&l2contact,
&l3name,
&l3contact,
&l4name,
&l4contact,
&escalationnotes)
checkErr(err)
assetinfo := new(AssetInfo)
assetinfo.Asset_id = assetid
assetinfo.Asset_name = name
assetinfo.LastCheckIn = lastcheckin
assetinfo.Asset_Status = status
assetinfo.Organisation_id = organisationid
assetinfo.Asset_longitude = lon
assetinfo.Asset_latitude = lat
assetinfo.Organisation_name = organisationname
assetinfo.CurrentDevice_name = currentdevicename
assetinfo.AssetActiveDeviceType = activedevicetype
assetinfo.AssetSafetyTimer = safetytimer
assetinfo.TemplateName = templatename
assetinfo.TemplateL2name = l2name
assetinfo.TemplateL2contact = l2contact
assetinfo.TemplateL3name = l3name
assetinfo.TemplateL3contact = l3contact
assetinfo.TemplateL4name = l4name
assetinfo.TemplateL4contact = l4contact
assetinfo.TemplateEscalationNotes = escalationnotes
The output of the code is ok, I can get all the data I want from the database. Except the SQL error is also printed on the console. And the L2Name is not a null value here, I can get the value printing on the console. So don't know why the error showing a type ?
Simplest fix is to wrap the nullable cols in your sql statement with a COALESCE(templates.L2Name, ''), thanks for #pmk help.
sqlstatement := "SELECT" +
" assets.ID, assets.Name, assets.LastCheckIn, assets.Status, assets.OffTimer," +
" assets.SafetyTimer, assets.HazardTimer, assets.HazardTimerStartedTime, assets.LastSignedOn," +
" assets.Latitude, assets.Longitude, assets.TemplateID, assets.ActiveDeviceType, assets.CurrentDeviceID," +
" assets.OffTimerTemp, assets.OrganisationID," +
" organisations.Name As OrganisationName," +
" devices.Label As CurrentDeviceName," +
" templates.Name As TemplateName, COALESCE(templates.L2Name, ''), COALESCE(templates.L2Contact, '')," +
" COALESCE(templates.L3Name, ''), COALESCE(templates.L3Contact, '')," +
" COALESCE(templates.L4Name, ''), COALESCE(templates.L4Contact, ''), templates.Note" +
" FROM assets" +
" LEFT JOIN organisations ON assets.OrganisationID = organisations.ID" +
" LEFT JOIN devices ON assets.CurrentDeviceID = devices.ID" +
" JOIN templates ON assets.TemplateID = templates.ID" +
" WHERE assets.Status != 'Not monitoring' AND assets.AssetStatus = 'Active' AND assets.Display != '0'"
For fields that can be NULL you should use sql.NullString data structure.
Here is more details:
https://golang.org/pkg/database/sql/#NullString

Mysql NodeJs syncronous queries

Thank you for the answer,
I did that : i used "sync-mysql" :
but now its very very slow...
Maybe i could do the same code using Mysql NPM
Do you know how my code must look like if I want to use asyncronous function and doing the same thing as below ? It will help me a lot :)
I have almost finished my project and I only have this function left
const customer_booked = []
customer_booked[0] = []
customer_booked[1] = []
let sql = "SELECT * " +
"FROM customer as C " +
"WHERE customer_reference REGEXP '^[c]i*' "
if (filters[0].value.length){
sql += "AND C.customer_name LIKE '%" + filters[0].value + "%' "
}
if (filters[3].value.length){
sql += "LIMIT " + filters[3].value
}
var result = connection.query(sql);
const customers = [];
const booked = connection.query('SELECT cr.customer_id, a.codeAgent ' +
'FROM customer_reservation as cr ' +
'INNER JOIN agent as a ' +
'ON a.id = cr.agent_id')
booked.forEach(customer_booking => {
customer_booked[0].push(customer_booking.customer_id)
customer_booked[1].push(customer_booking.codeAgent)
});
result.forEach( customer => {
var months;
let d1 = new Date(customer.last_order);
let d2 = new Date();
months = (d2.getFullYear() - d1.getFullYear()) * 12;
months -= d1.getMonth() + 1;
months += d2.getMonth();
months = months <= 0 ? 0 : months;
if (customer_booked[0].includes(customer.customer_id)){
let code_agent_index = customer_booked[0].indexOf(customer.customer_id)
customer.available = 'booked'
customer._rowVariant = 'warning'
customer.agent_code = customer_booked[1][code_agent_index]
}
else if (months >= 12){
customer.available = 'available'
customer._rowVariant = 'success'
} else {
customer.available = 'notAvailable'
customer._rowVariant = 'danger'
}
let sql2 = "SELECT * " +
"FROM customer_addresses AS CA " +
"WHERE CA.customer_id = " + customer.id
customer.addresses = connection.query(sql2)
customers.push(customer);
//customers[customers.length].push()
})
callback(false, result)
You can use node.js async/await using IIFE, like this:
(async() => {
const users = await getUsers();
for(const user of users){
user.addresses = await getAddresses(user.id);
// your other code just translated to JS.
}
return users;
})()
So, the main idea is to await your async code.
For example we use IIFE (Immediately Invoked Function Expression) to access needed async/await and for tests.
In real code you should name functions with keyword async
Here is nice tutorials which could explain how to use async/await 1, 2

parameterized execute query breaking due to wrong string concatenation in appcelerator

I am trying to execute an INSERT query using db.execute using the Appcelerator APIs. As per its docs it should be ideally used as :
var thisName = 'Arthur';
var thisPhoneNo = '1-617-000-0000';
var thisCity = 'Mountain View';
db.execute('INSERT INTO people (name, phone_number, city) VALUES (?, ?, ?)', thisName, thisPhoneNo, thisCity);
Database execute API doc for Appcelerator
So here is my problematic code which is almost blinding me:
var _tbl = "g_work_docket";
var records = [{
"id" : "2134",
"accession_no" : "20043446",
"opened" : "2014-07-25",
"job_origin" : "TRAMS Inspection",
"deadline" : "2014-09-30",
"completed_by" : "naren",
"completed" : "2016-02-18",
"mitigation_option" : "",
"location_no" : "186:03:",
"notes" : "",
"comments" : "",
"priority" : null,
"status" : "closed",
"is_approved" : "0",
"reviewer_comments" : "",
"updated_at" : "2016-02-18 12:58:50",
"is_deleted" : "0",
"site" : "K"
}, {
"id" : "3016",
"accession_no" : "196920850",
"opened" : "2000-01-19",
"job_origin" : "TRAMS Inspection",
"deadline" : "2001-01-01",
"completed_by" : "naren",
"completed" : "2016-02-18",
"mitigation_option" : "",
"location_no" : "770:01:",
"notes" : "Further inspection :\n\nDecay assesment : microdrill trunk base",
"comments" : "",
"priority" : null,
"status" : "closed",
"is_approved" : "0",
"reviewer_comments" : "",
"updated_at" : "2016-02-18 13:26:14",
"is_deleted" : "0",
"site" : "W"
}];
_.each(records, function(record) {
var qry = "INSERT OR REPLACE INTO " + _tbl + " (";
_.each(record, function(value, key, list) {
qry += '' + key + ',';
});
qry = qry.slice(0, -1);
qry += ") VALUES (";
_.each(record, function(value, key, list) {
qry += '?,';
});
qry = qry.slice(0, -1);
qry += "),";
_.each(record, function(value, key, list) {
qry += "'" + value + "',";
});
qry = qry.slice(0, -1);
db.execute(qry);
});
This always errors saying:
[ERROR] : Error: near "'2134'": syntax error (code 1): , while compiling: INSERT OR REPLACE INTO g_work_docket (id,accession_no,opened,job_origin,deadline,completed_by,completed,mitigation_option,location_no,notes,comments,priority,status,is_approved,reviewer_comments,updated_at,is_deleted,site) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?),'2134','20043446','2014-07-25','TRAMS Inspection','2014-09-30','naren','2016-02-18','','186:03:','','','null','closed','0','','2016-02-18 12:58:50','0','K'
Resolved this issue by passing the values by pushing them into an array first and then passing it to the db.execute function's 2nd param.
_.each(records, function(record) {
var qry = "INSERT OR REPLACE INTO " + _tbl + " (";
var dataValues = [];
_.each(record, function(value, key, list) {
qry += '' + key + ',';
});
qry = qry.slice(0, -1);
qry += ") VALUES (";
_.each(record, function(value, key, list) {
qry += '?,';
});
qry = qry.slice(0, -1);
qry += ")";
_.each(record, function(value, key, list) {
dataValues.push(value);
});
db.execute(qry, dataValues);
});

How to insert data to a sqlite database with table name as variable

I would like to insert data into my sqlite data base but with a variable as the name of the table where the data should be entered.
try {
Random rand = new Random();
uniqueID = rand.nextInt(9998) + 1; //Generates a random number from 1 - 9999 inclusively
String dateStart = day1.getText() + "/" + month1.getText() + "/" + year1.getText();
String dateEnd = day2.getText() + "/" + month2.getText() + "/" + year2.getText();
String projectN = projectName.getText();
String addr = address.getText();
//String engineerN = engineerName.getText();
//String engineerP = engineerPassword.getText();
Class.forName("org.sqlite.JDBC");
conn2.setAutoCommit(false);
PreparedStatement ps = conn2.prepareStatement("insert into "My table name" (uniqueid,name,address,startingdate,estcompletion) values(?,?,?,?,?,?)");
ps.setInt(1, uniqueID);
ps.setString(2, projectN);
ps.setString(3, addr);
ps.setString(4, dateStart);
ps.setString(5, dateEnd);
//ps.setString(6, engineerN);
ps.execute();
ps.close();
conn2.commit();
conn2.close();
}
catch ( Exception e1) {
System.err.println( e1.getClass().getName() + ": " + e1.getMessage() );
System.exit(0);
}
}
}
public String JJI() {
return projectName.getText();
}
}
"My table name" in the prepared statement is the place where I want to put my table name getting it from projectName.getText(); at the end. The user enters projectname.getText in another class.
Thank you for the help!
Store your table name in a String variable (how you like): String tableName = "users";
Make a query variable that contains your SQL query:
String query = "insert into '" + tableName + "' (uniqueid,name,address,startingdate,estcompletion) values(?,?,?,?,?,?)";
If you would like to have variables to insert, replace the "?" with your variable names as you have done in your code:
ps.setInt(1, uniqueID);
ps.setString(2, projectN);
ps.setString(3, addr);
ps.setString(4, dateStart);
ps.setString(5, dateEnd);
Execute the query:
PreparedStatement ps = conn2.prepareStatement(query);
ps.execute();