0

I have visited a similar question in SO which was asked earlier. In the answer its mentioned that :

When the buffer is "flushed", it will be displayed. Normally, if the output is a terminal, the buffer is flushed at a new line.

In the below code I have set flush is True in print statement but still the error message is displayed earlier.

Below is a simple program which performs CRUD operations in mongoDB database.

Code:

import pymongo

client = pymongo.MongoClient("mongodb://127.0.0.1/27017")

mydb = client["Employee"]

collection = mydb.collection

# record = {"firstname":"Udesh", "lastname":"Ranjan"}

# collection.insert_one(record)

records = [{"Name":"Your Name", "age":78, "Passion":"Astronomy"},
           {"Name":"Your Name", "age":38, "Passion":"Basket Ball"}]

# collection.insert_many(records)

print(collection.find_one(), flush=True) // flushing the output stream
print(dir(collection), flush=True)
# print(collection.find())
condition = {}
# condition = {"age":{"$in":[35, 35, 78, 22]}}
# condition = {"age":{"$lt":100, "$gt":30}}
# condition = {"age":{"$lt":100, "$gt":10}, "Name":"Your Name"}
condition = {"$or":[{"Name":"Your Name"}, {"firstname":"Udesh"}]}

for data in collection.find(condition):
    # print(data, type(data))
    for index, (key, item) in enumerate(data.items()):
        if index != 0:
            print(key, item, flush=True)
    print()


inventory = mydb.inventory
records = [
    {"item":"journal", "qty":30, "size":{"h":14, "w":20, "uom":"cm"}, "price":450.00},
    {"item":"journal", "qty":20, "size":{"h":14, "w":25, "uom":"cm"}, "price":350.00},
    {"item":"journal", "qty":10, "size":{"h":14, "w":10, "uom":"cm"}, "price":550.00},
    {"item":"journal", "qty":3, "size": {"h":14, "w":30, "uom":"cm"}, "price":250.00},
    {"item":"journal", "qty":50, "size":{"h":14, "w":50, "uom":"cm"}, "price":150.00},
    {"item":"journal", "qty":39, "size":{"h":0.4, "w":.30, "uom":"m"}, "price":5000.00},
    {"item":"journal", "qty":25, "size":{"h":140, "w":100, "uom":"mm"}, "price":1453.00},
]

records = []
inventory.insert_many(records)

condition = {}

for record in inventory.find(condition):
    print(record)

Output:

C:\ProgramData\Anaconda3\envs\tf_gpu\python.exe C:\Users\devpa\PycharmProjects\MondoDBKrishNaik\src\hello.py 

Traceback (most recent call last):
  File "C:\Users\devpa\PycharmProjects\MondoDBKrishNaik\src\hello.py", line 47, in <module>
    inventory.insert_many(records)
  File "C:\Users\devpa\AppData\Roaming\Python\Python39\site-packages\pymongo\_csot.py", line 105, in csot_wrapper
    return func(self, *args, **kwargs)
  File "C:\Users\devpa\AppData\Roaming\Python\Python39\site-packages\pymongo\collection.py", line 698, in insert_many
    raise TypeError("documents must be a non-empty list")
TypeError: documents must be a non-empty list
{'_id': ObjectId('63ad6d71597ce7bc64ed82e0'), 'firstname': 'Udesh', 'lastname': 'Ranjan'}
['_BaseObject__codec_options', '_BaseObject__read_concern', '_BaseObject__read_preference', '_BaseObject__write_concern', '_Collection__create', '_Collection__create_indexes', '_Collection__database', '_Collection__find_and_modify', '_Collection__full_name', '_Collection__name', '_Collection__write_response_codec_options', '__bool__', '__call__', '__class__', '__class_getitem__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattr__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__next__', '__orig_bases__', '__parameters__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', '__weakref__', '_aggregate', '_aggregate_one_result', '_command', '_count_cmd', '_delete', '_delete_retryable', '_insert_one', '_is_protocol', '_read_preference_for', '_retryable_non_cursor_read', '_socket_for_reads', '_socket_for_writes', '_timeout', '_update', '_update_retryable', '_write_concern_for', '_write_concern_for_cmd', 'aggregate', 'aggregate_raw_batches', 'bulk_write', 'codec_options', 'count_documents', 'create_index', 'create_indexes', 'database', 'delete_many', 'delete_one', 'distinct', 'drop', 'drop_index', 'drop_indexes', 'estimated_document_count', 'find', 'find_one', 'find_one_and_delete', 'find_one_and_replace', 'find_one_and_update', 'find_raw_batches', 'full_name', 'index_information', 'insert_many', 'insert_one', 'list_indexes', 'name', 'next', 'options', 'read_concern', 'read_preference', 'rename', 'replace_one', 'update_many', 'update_one', 'watch', 'with_options', 'write_concern']
firstname Udesh
lastname Ranjan

firstname Udesh
lastname Ranjan

Name Your Name
age 78
Passion Astronomy

Name Your Name
age 38
Passion Basket Ball


Process finished with exit code 1

The error message is displayed due to the records are empty.

But why the error message is displayed before the print statement even after flushing the output stream?

1 Answer 1

2

Because you call inventory.insert_many with an explicitly empty records. You literally have

records = []
inventory.insert_many(records)

Remove the line

records = []

and then the line inventory.insert_many(records) won't give you your error.

Sign up to request clarification or add additional context in comments.

7 Comments

Thanks Elliott but I have done it purposefully to see what happens and its generating error. My question is why error message is displayed earlier even after flushing the output stream. The print messages should be displayed earlier isn't it?
@devp Because there are newlines in the stacktrace and newlines trigger buffer flushing. Also note that is output to stderr (not stdout).
But I am flushing the output and by default the print method display a newline @ the end of line so stdout messages should be displayed earlier than stderr
@devp But the error happens first, and you don't catch the exception so the stacktrace is printed. And the stacktrace contains newlines; and newlines flush. So it prints immediately. I'm not sure why you would want to see an error at some other time. Either handle the error (with a try except), or prevent it by checking for an empty list. I don't think anyone wants a programming language that silently swallows errors.
But there are newlines generate using print() before the error message generated due to inventory.insert_many(records). I'm not trying to display error @ some time. I still cannot understand why the error stack trace message is display before the print statement message even after flushing the stream.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.