SQL query:-
Class Test
def self.execute_mysql(host, database, query)
Net::SSH.start('test.com', user, forward_agent: true) do |ssh|
ssh.exec!("mysql -ppassword -utestuser -h #{host} #{database} -A --execute '#{query}'")
end
end
Command to run:-
result = Test.execute_mysql('app', 'sample', 'select * from foo')
result string:-
id name address age
1 ram US 25
2 sam US 30
3 jack India 32
.
.
.
.
100 Peterson US 27
result variable returns as string class. Suppose it returns 100 records.How can i loop through each record ?
are you looking for something like this?
> result
=> "id name address age\n1 ram US 25\n2 sam US 30\n3 jack India 32"
> result.split(" ").each_slice(4){|e| print e }
=> ["id", "name", "address", "age"]["1", "ram", "US", "25"]["2", "sam", "US", "30"]["3", "jack", "India", "32"]
The answer to your question depends on a lot of things, and you carefully need to put a lot of checks to make it robust.
I'll however post a simple answer based on some assumptions to get you started on.
res = "id name address age
1 ram US 25
2 sam US 30
3 jack India 32"
arr = []
res.each_line {|line| arr << line.split(" ")}
arr
# => [["id", "name", "address", "age"], ["1", "ram", "US", "25"], ["2", "sam", "US", "30"], ["3", "jack", "India", "32"]]
Now you can easily iterate over the arrays to access particular attribute.
Related
With the table storedata, I am trying to remove the row "Target TargetCheese 4"
The logic here is if there are two or more entries for the same product at a given store it will choose the StoreNumber which best fits that store based on the other rows. If the StoreNumber doesn't match but it is not a duplicate Product then the number will not change; for example SafewayEggs will have StoreNumber equal to 1 even though there are more Safeway entries with the StoreNumber as 6 because there is only one row of SafewayEggs.
let storedata=
datatable (Store:string, Product:string ,StoreNumber:string)
["Target", "TargetCheese", "4",
"Target", "TargetCheese", "5",
"Target", "TargetApple", "5",
"Target", "TargetCorn", "5",
"Target", "TargetEggs", "5",
"Kroger", "KrogerApple", "2",
"Kroger", "KrogerCorn", "2",
"Kroger", "KrogerEggs", "2",
"Safeway", "SafewayApple", "6",
"Safeway", "SafewayCorn", "6",
"Safeway", "SafewayEggs", "1"
];
I am hoping to see this result table from the storedata table:
Store Product StoreNumber
Target TargetCheese 5
Target TargetApple 5
Target TargetCorn 5
Target TargetEggs 5
Kroger KrogerApple 2
Kroger KrogerCorn 2
Kroger KrogerEggs 2
Safeway SafewayApple 6
Safeway SafewayCorn 6
Safeway SafewayEggs 1
You might need different steps:
find the "best fit" StoreNumber - in my example below, the one with most occurences, use arg_max
dataset that has to be cleaned up with (1), more than 1 occurence per store and product, use count
the dataset that needs no cleanup, only one occurence per store and product
a union of (3) and the corrected dataset
let storedata=
datatable (Store:string, Product:string ,StoreNumber:string)
["Target", "TargetCheese", "5",
"Target", "TargetCheese", "4",
"Target", "TargetApple", "5",
"Target", "TargetCorn", "5",
"Target", "TargetEggs", "5",
"Kroger", "KrogerApple", "2",
"Kroger", "KrogerCorn", "2",
"Kroger", "KrogerEggs", "2",
"Safeway", "SafewayApple", "6",
"Safeway", "SafewayCorn", "6",
"Safeway", "SafewayEggs", "1"
];
// (1) evaluate best-fit StoreNumber
let storenumber =
storedata
| order by Store, StoreNumber
| summarize occ= count () by Store, StoreNumber
| summarize arg_max(occ, *) by Store;
// (2) dataset to be cleaned = more than one occurence per store and product
let cleanup =
storedata
| summarize occ = count () by Store, Product
| where occ > 1
| project-away occ;
// (3) dataset with only one occurrence
let okdata =
storedata
| summarize occ= count () by Store, Product
| where occ==1
| project-away occ;
// (4) final dataset
let res1 =storenumber
| join cleanup on Store
| project Store, Product, StoreNumber;
let res2 = storedata
| join okdata on Store, Product
| project-away Store1, Product1;
res1
| union res2;
I don't understand the logic you want for removing the following line:
"Target", "TargetCheese", "4"
But if you want to take the highest value for Store and Product, then you can use the following approach:
storedata
| summarize max(StoreNumber) by Store, Product
Imagine I have a text file with the following two observations:
liame#ziggo.nl:horse22| homeAddress = {
"city": "AMSTERDAM",
"houseNumber": "5",
"houseNumberAddition": null,
"postalCode": "1111 AN",
"street": "Walker",
"__typename": "ShopperAddress"
}
johndoe#live.nl:pizzalover1 | homeAddress = {
"city": "NEW YOK",
"houseNumber": "23",
"houseNumberAddition": null,
"postalCode": "9999 HV",
"street": "Marie Curie",
"__typename": "ShopperAddress"
}
Is there a way to read in this text file in such a way that the data frame looks like this:
username1 username2 city housenumber housenumber_addition postalcode street typename
liam#ziggo.nl horse22 AMSTERDAM 5 null 1111 AN Walker ShopperAddress
johndoe#live.nl pizzalover1 NEW YORK 23 null 9999 HV Marie Curie ShopperAddress
Thx
Your text file shows that there is a pattern to how the data is encoded:
<username1>:<username2> | homeAddress = {
<json_data>
}
We are going to parse the file in 2 passes: first pass to separate one record
from another and second pass to pick out the fields within a record:
A record ends on a line containing a single "}" character
Use regex to separate the fields inside a record
import json, re
import pandas as pd
data = []
pattern = re.compile(r"(.+?):(.+?)\s*\|\s*homeAddress = (.+)", re.DOTALL)
with open('data.txt') as fp:
record = ""
for line in fp:
record += line
if line == "}\n":
m = pattern.match(record)
if m:
username1 = m.group(1)
username2 = m.group(2)
home_address = json.loads(m.group(3))
data.append({
"username1": username1,
"username2": username2,
**home_address
})
record = ""
df = pd.DataFrame(data).rename(columns={"__typename": "typename"})
You can rework a bit your original text to make it a valid dictionary/JSON and feed it to pandas.read_json:
(pd.read_json('[%s]'%re.sub(r'([^:\n]+):([^\|:]+)\s*\|\s*homeAddress = {',
r',{\n "username1":"\1",\n "username2":"\2",',
text)[1:])
.rename(columns={'houseNumber': 'housenumber',
'houseNumberAddition': 'housenumber_addition',
'postalCode': 'postalcode',
'__typename': 'typename'})
)
output:
username1 username2 city housenumber housenumber_addition postalcode street typename
0 liame#ziggo.nl horse22 AMSTERDAM 5 NaN 1111 AN Walker ShopperAddress
1 johndoe#live.nl pizzalover1 NEW YOK 23 NaN 9999 HV Marie Curie ShopperAddress
intermediate reworked data:
[{
"username1":"liame#ziggo.nl",
"username2":"horse22",
"city": "AMSTERDAM",
"houseNumber": "5",
"houseNumberAddition": null,
"postalCode": "1111 AN",
"street": "Walker",
"__typename": "ShopperAddress"
}
,{
"username1":"johndoe#live.nl",
"username2":"pizzalover1 ",
"city": "NEW YOK",
"houseNumber": "23",
"houseNumberAddition": null,
"postalCode": "9999 HV",
"street": "Marie Curie",
"__typename": "ShopperAddress"
}]
I have below API response sample
{
"items": [
{
"id":11,
"name": "SMITH",
"prefix": "SAM",
"code": "SSO"
},
{
"id":10,
"name": "James",
"prefix": "JAM",
"code": "BBC"
}
]
}
As per above response, my tests says that whenever I hit the API request the 11th ID would be of SMITH and 10th id would be JAMES
So what I thought to store this in a table and assert against the actual response
* table person
| id | name |
| 11 | SMITH |
| 10 | James |
| 9 | RIO |
Now how would I match one by one ? like first it parse the first ID and first name from the API response and match with the Tables first ID and tables first name
Please share any convenient way of doing it from KARATE
There are a few possible ways, here is one:
* def lookup = { 11: 'SMITH', 10: 'James' }
* def items =
"""
[
{
"id":11,
"name":"SMITH",
"prefix":"SAM",
"code":"SSO"
},
{
"id":10,
"name":"James",
"prefix":"JAM",
"code":"BBC"
}
]
"""
* match each items contains { name: "#(lookup[_$.id+''])" }
And you already know how to use table instead of JSON.
Please read the docs and other stack-overflow answers to get more ideas.
I have a MySQL database and one of the tables is called 'my_table'. In this table, one of the columns is called 'my_json_column' and this column is stored as a JSON object in MySQL. The JSON object has about 17 key:value pairs (see below). I simply want to return a "slimmed-down" JSON Object from a MySQL query that returns 4 of the 17 fields.
I have tried many different MySQL queries, see below, but I can't seem to get a returned subset JSON Object. I am sure it is simple, but I have been unsuccessful.
Something like this:
SELECT
json_extract(my_json_column, '$.X'),
json_extract(my_json_column, '$.Y'),
json_extract(my_json_column, '$.KB'),
json_extract(my_json_column, '$.Name')
FROM my_table;
yields:
5990.510000 90313.550000 5990.510000 "Operator 1"
I want to get this result instead (a returned JSON Object) with key value pairs:
[ { X: 5990.510000, Y: 90313.550, KB: 2105, Name: "Well 1" } ]
Sample data:
{
"Comment" : "No Comment",
"Country" : "USA",
"County" : "County 1",
"Field" : "Field 1",
"GroundElevation" : "5400",
"Identifier" : "11435358700000",
"Interpreter" : "Interpreter 1",
"KB" : 2105,
"Name" : "Well 1",
"Operator" : "Operator 1",
"Owner" : "me",
"SpudDate" : "NA",
"State" : "MI",
"Status" : "ACTIVE",
"TotalDepth" : 5678,
"X" : 5990.510000,
"Y" : 90313.550
}
Thank you in advance.
Use JSON_OBJECT(), available since MySQL 5.6:
Evaluates a (possibly empty) list of key-value pairs and returns a JSON object containing those pairs
SELECT
JSON_OBJECT(
'X', json_extract(my_json_column, '$.X'),
'Y', json_extract(my_json_column, '$.Y'),
'KB', json_extract(my_json_column, '$.KB'),
'Name', json_extract(my_json_column, '$.Name')
) my_new_json
FROM my_table;
This demo on DB Fiddle with your sample data returns:
| my_new_json |
| ----------------------------------------------------------- |
| {"X": 5990.51, "Y": 90313.55, "KB": 2105, "Name": "Well 1"} |
I'm making API Server with DRF(DB is MySQL).
Now I made some system similar with facebook's like.
First, below is my Database Structure.
[user table]
userkey(PK)
username
[article table]
articleNo(PK)
userkey(FK to user)
content
[like table]
articleNo
userkey(FK to user)
When user click the "Like" buttons, articleNo and User's key will be inserted into like table.
Currently, When I access to /article/, shows below result.
{
"articleNo": 1,
"userkey": "22222",
"content": "test1",
"date": "2018-02-14T22:34:36.673805+09:00"
},
{
"articleNo": 2,
"userkey": "11111",
"content": "test2",
"date": "2018-02-15T22:34:36.673805+09:00"
},
...
...
If like table has two row like this,
+-----------+---------+
| articleNo | userkey |
+-----------+---------+
| 1 | 11111 |
| 1 | 22222 |
+-----------+---------+
It means that 11111 and 22222 user likes articleNo==1.
So When user access to /article?userkey=11111, What I would like instead as output is something like:
{
"articleNo": 1,
"userkey": "22222",
"content": "test1",
"isLiked": "true", // add this line
"date": "2018-02-14T22:34:36.673805+09:00"
},
{
"articleNo": 2,
"userkey": "11111",
"content": "test2",
"isLiked": "false", // add this line
"date": "2018-02-15T22:34:36.673805+09:00"
},
...
...
Is it possible to implement with DRF?
Thanks.
Yes, this can be done entirely on the ORM level, by using Django 1.8 conditional expressions
Having the following model structure (some example values):
class User(models.Model):
userkey = models.AutoField(primary_key=True)
username = models.CharField(max_length=255)
class Article(models.Model):
articleNo = models.AutoField(primary_key=True)
user = models.ForeignKey(User)
content = models.TextField()
class Like(models.Model):
article = models.ForeignKey(Article)
user = models.ForeignKey(User)
To demonstrate how this works, I created some example data:
john = User.objects.create(userkey=1, username='John')
alice = User.objects.create(userkey=2, username='Alice')
john_article = Article.objects.create(articleNo=1, user=john, content='Hi, I am John!')
alice_article = Article.objects.create(articleNo=2, user=alice, content='Hi, I am John!')
alice_likes_john_article = Like.objects.create(user=alice, article=john_article)
alice_likes_her_article = Like.objects.create(user=alice, article=alice_article)
john_likes_his_article = Like.objects.create(user=john, article=john_article)
You could achieve what you want on the ORM level:
articles = Article.objects.all().annotate(
like_count=Sum(
Case(
When(like__user=john, then=1),
default=0,
output_field=IntegerField(),
)
),
).annotate(
likes=Case(
When(like_count__gt=0, then=True),
default=False,
output_field=BooleanField()
)
)
(If somebody knows a simpler way than the above, I would be happy to learn as well)
Now every Article instance in the articles queryset will have two additional attributes: likes_count with the number of likes an article has received from John, and likes, a boolean, indicating if John likes it or not. Obviously you're interested in the latter.
Just override the get_queryset() method of your Article ViewSet, and then add an additional field to the Serializer of your Article class.
Also, you probably need to somehow pass the user instance (or the id) for the filter, but that can be done in various ways, including (for example) reading the query params inside the get_queryset method.