I'm practicing use python to commit rollback MongoDB (Pymongo)
For example, I have two collections, one collection store all amount of money of each user and log collection is saving data of with roll or input money in bank
total_money_collection
{"user": "Joy" , "total_money" : 100, "ID" : 999}log_money_collection
{"user": "Joy" , "in_out_put_money" : null , "ID" : 999}
I need a hand for simpler way, maybe there is a short pymongo command
,or MongoDB can do such operation that just extract the result is fine
etc.
If I input from log_money_collection
{"user": "Joy" , "in_out_put_money" : -7 , "ID" : 999},
how can "in_out_put_money"
column effect "total_money"
column
Expected output:
total_money_collection
{"user": "Joy" , "total_money" : 93, "ID" : 999}
This is my code (I made lot of make an unnecessary move, I believe there is a simpler way):
import pymongo
import datetime
import json
from bson.objectid import ObjectId
from bson import json_util
import re
def init_db(ip, db, coll):
myclient = pymongo.MongoClient('mongodb://' ip '/')
mydb = myclient[db]
mycol = mydb[coll]
return mydb, mycol, myclient
def Quy_data( mycol , find_values_json , one_or_many_bool):
try:
if one_or_many_bool:
x = []
for y in mycol.find(find_values_json):
x.append(y)
cash_all_value = mycol.find({},{ "Cash_$": 1 })
else:
x = mycol.find_one(find_values_json)
cash_all_value = mycol.find({},{ "Cash_$": 1 })
return x , cash_all_value
except Exception as e:
msg_fail_reason = "error in ins_data function"
return msg_fail_reason
ip_input = input("Enter the ip: ")
exist_DB_name = input("Enter exist DB name: ")
def parse_json(data):
return json.loads(json_util.dumps(data))
try:
exist_coll = input("Enter exist collection (ex: 10_20_cash_all , 10_20_cash_log ): ")
mydb, mycol , myclient = init_db(ip_input, exist_DB_name, exist_coll)
with myclient.start_session(causal_consistency=True) as session:
# Open a transaction session
with session.start_transaction():
# mycol.insert_one({'Name': ' Gosum '}, session=session)
if exist_coll == "10_20_cash_all":
# I set find all ( = find )
one_or_many_bool = True
findvalues_str = input("Enter find data conditions: ")
find_values_json =json.loads(findvalues_str)
x , cash_all_value = Quy_data( mycol , find_values_json , one_or_many_bool )
# if someone want data in json
modified_data_x_json = parse_json(x)
cash_all_value_json = parse_json(cash_all_value)
a = str(cash_all_value_json)
print(modified_data_x_json)
print(type(modified_data_x_json))
print("= = = = = ")
print(a)
print(type(a))
b = re.search("'Cash_$': (.*)", a)
print(b)
except Exception as e:
# Output exception content
print(e)
output for my (I find the user Joy, and try to extract the number after "total_money"
then subtract "in_out_put_money"
)
Enter the ip: localhost
Enter exist DB name: (practice_10_14)-0004444
Enter exist collection (ex: 10_20_cash_all , 10_20_cash_log ): 10_20_cash_all
Enter find data conditions: { "name": "Joy" }
[{'_id': {'$oid': '6348d73be94317989175dc2d'}, 'name': 'Joy', 'ID': 999, 'Age': 23, 'time': {'$date': '2022-10-17T09:11:54Z'}, 'total_money': 100}]
<class 'list'>
= = = = =
[{'_id': {'$oid': '6348d73be94317989175dc2d'}, 'total_money': 100}, {'_id': {'$oid': '6348d73be94317989175dc2e'}, 'total_money': 100}, {'_id': {'$oid': '6348d73be94317989175dc2f'}, 'total_money': 100}, {'_id': {'$oid': '6348d73be94317989175dc30'}, 'total_money': 100}, {'_id': {'$oid': '6348d73be94317989175dc31'}, 'total_money': 100}, {'_id': {'$oid': '635112dea1fa85dd0cfe590b'}, 'total_money': 100}]
<class 'str'>
None
A simple step of commit rollback MongoDB with account money I turn a huge circle to get it, I need a hand for simpler way, maybe there is a short pymongo command
,or MongoDB can do so that just extract the result is fine
etc
CodePudding user response:
the same concept make ur {"user": "Joy" , "total_money" : 93, "ID" : 999}
,
the "total_money" become lesser by subtracting them, for sure U can't directly do that, like python (4 - 1 something)....
here is the code:
import pymongo
import datetime
import json
from bson.objectid import ObjectId
from bson import json_util
import re
myclient = pymongo.MongoClient("mongodb://localhost/")
mydb = myclient["(practice_10_14)-0004444"]
# UD_db_data means update
def UD_db_data(mycol , myquery_json, newvalues_json, one_or_many_bool):
if one_or_many_bool == True:
x = mycol.update_many(myquery_json, newvalues_json)
else:
x = mycol.update_one(myquery_json, newvalues_json)
return x
# Quy_data = query find db_data
def Quy_data( mycol ,find_values_json , one_or_many_bool):
try:
if one_or_many_bool:
x = []
for y in mycol.find(find_values_json):
x.append(y)
else:
x = mycol.find_one(find_values_json)
return x
except Exception as e:
msg_fail_reason = "error in ins_data function"
return msg_fail_reason
mycol_one = mydb["10_20_cash_all"]
mycol_two = mydb["10_20_cash_log"]
mycol_3rd = mydb["10_20_cash_info"]
# already store 100$ in bank
# doc_two = {"ID" : 100998 , "Cash_log$" : 5 } # withdraw 5$ from bank
doc_two = input("Enter ID and log amount$: ")
doc_3rd = input("Enter extra info: ")
doc_two_dic = json.loads(doc_two)
doc_3rd_dic = json.loads(doc_3rd)
# doc_3rd = {"note" : "today is good" }
ID_input = doc_two_dic['ID']
print("ur id is :" str(ID_input))
doc_one = {"ID" : ID_input}
with myclient.start_session() as s:
cash_all_result = mycol_one.find_one(doc_one, session=s)
def cb(s):
try:
while True:
cash_all_result = mycol_one.find_one(doc_one, session=s)
mycol_two.insert_one(doc_two_dic, session=s)
# print( 3/0 )
mycol_3rd.insert_one(doc_3rd_dic, session=s)
print( "now total is :" str(cash_all_result['Cash_$']) )
Cash_total_int = int(cash_all_result['Cash_$'])
log_int = int(doc_two_dic['Cash_log$'])
if Cash_total_int < log_int:
print("error: withdraw is over ur balance")
break
new_Cash_total = Cash_total_int - log_int
print("now total is :" str(new_Cash_total))
newvalues_json = { "$set" : {"Cash_$" : new_Cash_total } }
mycol_one.update_one(doc_one , newvalues_json, session=s)
fail_condition_json = {"ok" : 1 , "fail reason" : "no error "}
print(fail_condition_json)
return fail_condition_json
except Exception as e:
fail_condition_json = {"ok" : 0 , "fail reason" : "error raise on start_session()"}
print(fail_condition_json)
return fail_condition_json
s.with_transaction(cb)
I believe I do the calculation with 3 collection's data
and the output is below
Enter ID and log amount$: {"ID" : 100998 , "Cash_log$" : 23 }
Enter extra info: {"note" : "today is no good" }
ur id is :100998
now total is :72
now total is :49
{'ok': 1, 'fail reason': 'no error '}