I want to use .find() like this for mongoDB in Python :
import pymongo
client = pymongo.MongoClient('mongodb://localhost:27000')
db = client['responsi']
cursor = db['produk']
for x in cursor.find({"pricing.pct_savings":{"$gt":25}}).sort({"pricing.pct_savings":-1}):
print(x)
But, it showing error like this :
Traceback (most recent call last):
File "Find.py", line 7, in <module>
for x in cursor.find({"pricing.pct_savings":{"$gt":25}}).sort({"pricing.pct_savings":-1}):
File "G:\PROGRAM FILES\Python\lib\site-packages\pymongo\cursor.py", line 708, in sort
keys = helpers._index_list(key_or_list, direction)
File "G:\PROGRAM FILES\Python\lib\site-packages\pymongo\helpers.py", line 69, in _index_list
raise TypeError("if no direction is specified, "
TypeError: if no direction is specified, key_or_list must be an instance of list
How to solved this problem?
Thank you!
Sorry, I have bad score in english.
As opposed to the mongo shell, pymongo takes key and direction as the arguments to the sort method (or list, but that's another form that is not relevant to you currently, I'll show it too)
So your query should actually be cursor.find({"pricing.pct_savings":{"$gt":25}}).sort("pricing.pct_savings", pymongo.DESCENDING)
The other form gets a list of tuples of field name and the direction, and allows you to sort by multiple fields, for example collection.find().sort([('my_field_1',pymongo.DESCENDING), ('my_field_2',pymongo.ASCENDING)])
See the relevant documentation here https://api.mongodb.com/python/current/api/pymongo/cursor.html?highlight=sort#pymongo.cursor.Cursor.sort
You can find the ASCENDING and DESCENDING constants here https://api.mongodb.com/python/current/api/pymongo/collection.html#pymongo.ASCENDING
BTW (not related to your original question)
db['produk'] is actually a collection, not a cursor, so it would be better if you would call it collection, and not cursor.
Cursor is what find() returns
should only have this structure
from bson import ObjectId
id = '375g68h97b680jf78j'
data = cursor.find_one_and_delete({'_id': ObjectId(id)})
Related
I have been trying to upload close to a thousand SVG files to a particular program (FontForge) and as such searched for a way to automate it. Unfortunately I am really unfamiliar with Python, to the extent that I'm not sure if what I changed about the code ended up changing something fundamental.
The original code you were meant to individually continue the table that the original coder left with the file name and glyph names of the SVG files. This would require doing it manually, as I realized quickly it wouldn't allow loops within the brackets itself. The original code was as follows, albeit with more items:
select = [
('null', 'null'),
('bs-info-circle', 'infoCircle'),
]
Looking at it, and with a lot of googling and experimentation, I guessed that it was a list of tuples. As such, I created various loops adding onto a toSelect list that I created. Since they are rougly the same I'll just show one here:
for x in svc:
icon="svc-"+x+"con_lang"
glyph=x
#print((icon, glyph))
toSelect.extend(((icon, glyph),)) #comma necessary to force it to add in a pair, rather than individually
The variable svc is a list of strings: ['ba', 'be', 'bi', 'bo'...] pulled from a TXT file. The variable toSelect, when printed, looks as follows:
[('svc-bacon_lang', 'ba'), ('svc-becon_lang', 'be'), ('svc-bicon_lang', 'bi'), ...]
Long story short, I now have a list that seems to be formatted the same as the contents of the original code. As such, I set it equal in a simple manner:
select = toSelect
However, running the build program that pulls from this code is giving the following error message:
Traceback (most recent call last):
File "C:\Users\*****\Downloads\ff-batch-main\ff-batch-main\build.py", line 392, in <module>
run_fontforge(config)
File "C:\Users\*****\Downloads\ff-batch-main\ff-batch-main\build.py", line 148, in run_fontforge
for key, name in config.select:
ValueError: not enough values to unpack (expected 2, got 1)
I have tried every variation of declaring select that I can, including a few that cause the following error message:
Traceback (most recent call last):
File "C:\Users\*****\Downloads\ff-batch-main\ff-batch-main\build.py", line 392, in <module>
run_fontforge(config)
File "C:\Users\*****\Downloads\ff-batch-main\ff-batch-main\build.py", line 148, in run_fontforge
for key, name in config.select:
ValueError: too many values to unpack (expected 2)
Printing the value of select[0] does seem to tell me that that error is caused by all of the entries being considered one entry on the list? So at least I know that.
Still, I can't figure out why it doesn't take my original attempt, as select[0] = ('null', 'null'). I'm worried that select isn't supposed to be a list at all, but is something different that I'm simply unfamiliar with since I do not know python. Is this some sort of function that I broke by adding items sequentially instead of all at once?
I will also show the code from the 'build' program that is flagged as the problem. The only thing that I edited was the 'config' program, as instructed by the coder, but hopefully this at least will give context?
def run_fontforge(config):
from icon_map import maps
try:
from select_cache import maps as icons
except:
icons = {}
print(f"Generating fonts => {config.build_dir}/{config.font_name}.ttf")
with open('select_cache.py', 'w') as f:
f.write("# SVG to Font Icon mapping\n")
f.write(f"# Generated: {datetime.now()}\n")
f.write("maps = {\n")
last = config.font_start_code - 1
for _,m in icons.items():
last = max(last, m['code'])
last += 1
for key, name in config.select:
icon = icons.get(key)
src = maps.get(key)
So yeah. Um, any advice or explanations would be greatly appreciated, and I'll do my best to give additional information when possible? Unfortunately I started trying to understand Python yesterday and am coming at this from a rusty knowledge of java so I am not really fluent, might not know terms and whatnot. I just wanted to import some files man...
You've gotten quite far just 1 day into Python.
My hypothesis for the bug is config.select not containing the toSelect data.
Ways to investigate:
Interactively run this to verify that toSelect is a list of pairs:
for k, n in toSelect: pass
print both variables, or interactively evaluate config.select == toSelect to compare them, or set breakpoints in the PyCharm or VSCode debugger and examine these variables.
Is this some sort of function that I broke by adding items sequentially instead of all at once?
No.
BTW, you can make:
toSelect.extend(((icon, glyph),))
easier to understand by writing it as:
toSelect.append((icon, glyph))
Bonus: The most "Pythonic" way to write that for loop is as a list comprehension:
toSelect = [("svc-"+x+"con_lang", x) for x in svc]
I'm trying to program a reddit bot, but get this error message:
Traceback (most recent call last):
File "main.py", line 64, in <module>
run_bot(r, comments_replied_to)
File "main.py", line 34, in run_bot
comments_replied_to.append(comment.id)
AttributeError: 'filter' object has no attribute 'append'
Here is my code: https://pastebin.com/caz14jm7
I think I have to change append into a list, but I don't know how to do that
Part of this is a version difference. In Python 2, filter returned a list. In Python 3, filter returns a generator, which you are treating like a list. The filter generator does not have an append method.
So, you just need to turn it into a list:
comments_replied_to = list(filter(None, comments_replied_to))
Or, even better (in the opinion of many):
comments_replied_to = [k for k in comments_replied_to if k]
I have 2 potential solutions for you,
solution 1:
Line 55 You can change like this
comments_replied_to = List(filter(None, comments_replied_to))
so that, your get_saved_comments() will return a list.
This will help you use the append method and comments_replied_to.append(comment.id) should work without any error
Solution 2:
Line 60: You can change like this
comments_replied_to = list(get_saved_comments())
As long as comments_replied_to is a list type, it will allow you to append method without any issues.
check this blog to have a better understanding over append method
https://www.programiz.com/python-programming/methods/list/append
Having an error where i'm trying to get the first work from a string that is passed in to a method within a class. But i am getting AttributeError: 'Deck' object has no attribute 'split' when I run. The 'new_card' that is passed in will be for example 'Two of Hearts'. and new_Card is a string and self.values is a dictionary
# returns integer value of a card
def get_card_value(self, new_card):
return self.values[new_card.split()[0]]
and the error:
Traceback (most recent call last):
File "/home/andypaling/Documents/Programming/python/random/card_game/game.py", line 146, in
if not Game.check_same_cards(player1_deck, player2_card):
File "/home/andypaling/Documents/Programming/python/random/card_game/game.py", line 87, in check_same_cards
if card1.get_card_value(card1) == card2.get_card_value(card2):
File "/home/andypaling/Documents/Programming/python/random/card_game/game.py", line 40, in get_card_value
split_string = new_card.split(' ')
thanks for any help
Hey it seems like you are using a diffrent data type and not a string in your case judging that your making a card game i am guessing you are using a tuple. Try converting the data to a string then split it using the .split() function.
I hope this can help.
I have captured a string from a REST get request and have placed it in a variable. The string is:
{"name":"na1mailboxarchive","objectCount":49564710,"dataBytes":36253526882451},{"name":"na1mailboxarchive2","objectCount":17616567,"dataBytes":13409204616615}
I am trying to convert it to a dictionary so I can increment through it and capture the bucket name, size and object count. I have tried eval()
bucket_dict = eval(bucket_info)
but the program errors out with a:
Traceback (most recent call last):
File "./test.py", line 83, in <module>
for k,b in bucket_dict.items():
AttributeError: 'tuple' object has no attribute 'items'
When I print the value of bucket_dict I get:
({'name': 'na1mailboxarchive', 'objectCount': 49564710, 'dataBytes': 36253526882451}, {'name': 'na1mailboxarchive2', 'objectCount': 17616567, 'dataBytes': 13409204616615})
I think the foul up is the () at the beginning and the end of the dictionary. Nothing else I have tried works either.
Try this instead
import ast
string = '{"name":"na1mailboxarchive","objectCount":49564710,"dataBytes":36253526882451},{"name":"na1mailboxarchive2","objectCount":17616567,"dataBytes":13409204616615}'
result = ast.literal_eval(string)
print(result)
result is returned as a dictionary
I got it figured out.
Firstly the json return from the REST API get is badly formatted. I will take that up with the vendor. Secondly I used some iof the infrmation form #PrashantKumar and #MisterMiyagi to sus out the issue I was having. In my original code I had loaded the list with:
bucket_info = [acct_string[acct_string_start+11:acct_len-4]]
The variable was capturing the leading "[" and trailing "]" as a part of the string. Once I removed them then the list behaved correctly and I now can work with it. Thank you for the information and the trail markers.
I am getting following error while updating a document inside a collection in mongodb using python using pymongo. Any help is greatly appreciated.
x = 4
str = "ratings.${x}.rating"
db.amitava1.update({"_id":1},{"$inc":{[str]:1 } } )
Traceback (most recent call last):
File "", line 1, in TypeError: unhashable type:
'list'***
Youre getting that error because you're doing {"$inc":{[str]:1 }}. Namely, trying to assing [str] as the key in the in the dictionary {[str]:1 }.
It says that because you cannot use a list as a key for a dictionary, because a list is unhashable. You can only use hashable types (types that have a __hash__ function defined) key values.
It looks like you have some other issues with your code though. I think you need to use
str = "ratings.${x}.rating".format(x=x)
or something in order to replace the x in your string.