Add a method for fetching just one value from the database?
flexd opened this issue · 9 comments
I have a query like this
balance = int(list(db.query('balance/all', descending='true', limit='1'))[0]['value'])
Which as you can see is a lot less cleaner then being able to do something like this
balance = int(db.one('balance/all'))
Or something similiar, I don't know. I just found it a bit annoying to have to do [0] and especially ['value'] to get the value of a specific document like that.
Suggestions?
Hi!
The second option seems very cleaner, but the library can't guess the attribute name.
int(db.one("balance/all")["value"])
or
int(db.query("balance/all", flat="value", limit=1))
also, the one method can be a first method.
I don't known that is the cleaner or semantically correct method.
{
"total_rows": 480,
"offset": 0,
"rows": [
{
"id": "07678d458cee44cebf307230beb39170",
"key": "1368053775",
"value": 6437992388.73
},
{
"id": "599d54d35b5c4615a30b133fc1aaf063",
"key": "1368055731",
"value": 6183660317.03
}
]
}
The result is always in that format from the database isn't it, at least if you have something that doesn't return a whole doc, like this python view:
def fun(doc):
if (doc['.type'] == 'Balance'):
yield doc['timestamp'], doc['balance']
Oh, you abosultelly right.
With this, we can improve query method and add a one method:
- Change query method behavior: by default returns a tuple (key, value) and if you only need a value or a key yo can use a flat parameter.
[("foo", 1), ("bar", 2)] == db.query("foobar/all")
[1,2] == db.query("foobar/all", flat="value")
["foo", "bar"] == db.query("foobar/all", flat="key")
- Add one method.
("foo", 1) == db.one("foobar/all")
1 == db.one("foobar/all", flat="value")
"foo" == db.one("foobar/all", flat="key")
What do you think about this?
That looks nice, but how would that look for a normal document?, say:
{
"_id": "2856703783",
"_rev": "1-d169903d3091e1f0d5f896458d6722ab",
"timestamp": 1367443028,
"price": 1068903.96,
".type": "Transaction",
"station": {
"id": 60008494,
"name": "Amarr VIII (Oris) - Emperor Family Academy"
},
"id": 2856703783,
"for": "personal",
"journal_id": 7422767310,
"client": {
"id": 1292578043,
"name": "Aedazan"
},
"action": "sell",
"type": {
"id": 3888,
"name": "Co-Processor II"
},
"quantity": 1
}
By the way, it was also annoying me a bit (and caused some errors at first) that I had to do parameters like this:
transactions = list(db.query('transactions/all', descending='true', limit='25'))
Instead of using 'native' values for python like this:
transactions = list(db.query('transactions/all', descending=True, limit=25))
But that isn't that much of an issue, it's just a matter of nice syntax.
The view queryes always return kay and value. If you need a entire document, write a query like a:
def fun(doc):
if (doc['type'] == 'Balance'):
yield doc['timestamp'], doc
This returns:
{
"total_rows": 480,
"offset": 0,
"rows": [
{
"id": "07678d458cee44cebf307230beb39170",
"key": "1368053775",
"value": {"_id": "2856703783", "_rev": "1-d169...", "price": 2.2, ...}
},
[...]
]
}
And obtain this value with this:
{"_id": "2856703783", "_rev": "1-d169...", "price": 2.2, ...} == db.one("foobar/all", flat="value")
Right, I guess you might want to make the flat="value" default in the code as well, so you can do just db.one("foobar/all") and db.all("foobar/all") to get just a list of values and no keys? Like it is now.
I like it!
I think that the flat parameter as a None for default, because I don't like break current api.
But with this implemented, you have a cleaner api for obtain a values list.
I make this changes tomorrow ;)
Thanks for the idea!
Cool! :-)
Now implemented :)