(Pymongo) several functions cover with Commit and rollback, and one of them stll proceed while whole function should stop
I read the manual, that all the example commit and rollback only cover two operation, is that the limit?, usually should contain 3 or more operations and either operate in the same time or not operate if error https://pymongo.readthedocs.io/en/stable/api/pymongo/client_session.html
I tried to contain 3 operation inside commit and rollback but
mycol_two.insert_one() didn't stop proceed like other function when error occur
brief description:
I have three collections in same DB
collection "10_20_cash_all"
collection "10_20_cash_log"
collection "10_20_cash_info"
commit and rollback on line 39 to 44
line 42 print( 3/0 ) , I intent to make an error, expect all function would stop proceed
import pymongo
import datetime
import json
from bson.objectid import ObjectId
from bson import json_util
import re
myclient = pymongo.MongoClient("mongodb://localhost:27017/")
mydb = myclient["(practice_10_14)-0004444"]
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 70$ 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)
command prompt:
Enter ID and log amount$: {"ID" : 100998 , "Cash_log$" : 5 }
Enter extra info: {"note" : "today is good" }
ur id is :100998
{'ok': 0, 'fail reason': 'error raise on start_session()'}
the "10_20_cash_log" still store new value which shoud empty/not run like '"10_20_cash_info"' is empty
{
"_id" : ObjectId("635262e502725626c39cbe9e"),
"ID" : 100998,
"Cash_log$" : 5
}
I try to add several entries tho the same document in Cosmo Db with Python using the library pydocumentdb
I thought that was possible with the function CreateDocuments
Creation of the Document with one entry works
def GetSalesOrder(document_id):
# notice new fields have been added to the sales order
order2 = {'id' : document_id,
'account_number' : 'Account2',
'purchase_order_number' : 'PO15428132599',
'order_date' : datetime.date(2005,7,11).strftime('%c'),
'due_date' : datetime.date(2005,7,21).strftime('%c'),
'shipped_date' : datetime.date(2005,7,15).strftime('%c'),
'subtotal' : 6107.0820,
'tax_amount' : 586.1203,
'freight' : 183.1626,
'discount_amt' : 1982.872,
'total_due' : 4893.3929,
'items' : [
{'order_qty' : 3,
'product_code' : 'A-123', # notice how in item details we no longer reference a ProductId
'product_name' : 'Product 1', # instead we have decided to denormalise our schema and include
'currency_symbol' : '$', # the Product details relevant to the Order on to the Order directly
'currecny_code' : 'USD', # this is a typical refactor that happens in the course of an application
'unit_price' : 17.1, # that would have previously required schema changes and data migrations etc.
'line_price' : 5.7
}
],
'ttl' : 60 * 60 * 24 * 30
}
return order2
coll_link = database_link + '/colls/sales'
print('\n1.2 Creating collection\n')
collection = client.CreateCollection(database_link,
{ 'id': "sales" })
print('\n1.2 Creating document\n')
sales_order = DocumentManagement.GetSalesOrder("SalesOrder")
client.CreateDocument(coll_link, sales_order)
Then i try to reuse this code with a different entry into the same document but my program fails with :
Top level Error: args:('document is None.',), message:N/A
Thanks for your help
The complete code that fails
import pydocumentdb.documents as documents
import pydocumentdb.document_client as document_client
import pydocumentdb.errors as errors
import datetime
import config as cfg
HOST = cfg.settings['host']
MASTER_KEY = cfg.settings['master_rw_key']
DATABASE_ID = cfg.settings['database_id']
COLLECTION_ID = cfg.settings['collection_id']
database_link = 'dbs/' + DATABASE_ID
collection_link = database_link + '/colls/' + COLLECTION_ID
class IDisposable:
""" A context manager to automatically close an object with a close method
in a with statement. """
def __init__(self, obj):
self.obj = obj
def __enter__(self):
return self.obj # bound to target
def __exit__(self, exception_type, exception_val, trace):
# extra cleanup in here
self = None
class DocumentManagement:
#staticmethod
def CreateDocuments(client):
coll_link = database_link + '/colls/sales'
print('\n1.2 Creating collection\n')
collection = client.CreateCollection(database_link,
{ 'id': "sales" })
print('\n1.2 Creating document\n')
sales_order = DocumentManagement.GetSalesOrder("SalesOrder")
client.CreateDocument(coll_link, sales_order)
#staticmethod
def AddEntry(client):
coll_link = database_link + '/colls/sales' #+ '/docs/SalesOrder'
print('\n1.2 Creating row\n')
sales_order = DocumentManagement.GetSalesOrder2("SalesOrder")
client.CreateDocument(coll_link, sales_order)
#staticmethod
def CreateStoredProcedure(client):
coll_link = database_link + '/colls/sales'
sproc1 = {
'id': 'countDocuments',
'body': (
'function () {' +
' var collection = getContext().getCollection(); ' +
' collection.queryDocuments(' +
' collection.getSelfLink(),' +
' \'SELECT VALUE COUNT(SalesOrder.id) FROM SalesOrder\',' +
' function(error, result) {' +
' if (error) throw error;' +
' var count = result[0];' +
' getContext().getResponse().setBody(count);' +
' }' +
' );' +
' }'
)
}
print('\n1.2 Creating sproc\n')
retrieved_sproc = client.CreateStoredProcedure(coll_link, sproc1)
#staticmethod
def CountEntries(client):
coll_link = database_link + '/colls/sales'
sproc_link = coll_link + '/sprocs/countDocuments'
print('\n1.2 Counting rows\n')
#sales_order = DocumentManagement.getSalesOrder2("SalesOrder")
#client.CreateDocument(coll_link, sales_order)
params = {}
options = {}
options['enableCrossPartitionQuery'] = True
result = client.ExecuteStoredProcedure(sproc_link, params, options)
print(result)
#staticmethod
def DeleteCollection(client):
coll_link = database_link + '/colls/sales'
print('\n1.2 Delete collection\n')
client.DeleteCollection(coll_link)
#staticmethod
def DeleteDocument(client, doc_id):
coll_link = database_link + '/colls/sales'
print('\n1.2 Deleting Document by Id\n')
doc_link = coll_link + '/docs/' + doc_id
client.DeleteDocument(doc_link)
#staticmethod
def GetSalesOrder(document_id):
# notice new fields have been added to the sales order
order2 = {'id' : document_id,
'account_number' : 'Account2',
'purchase_order_number' : 'PO15428132599',
'order_date' : datetime.date(2005,7,11).strftime('%c'),
'due_date' : datetime.date(2005,7,21).strftime('%c'),
'shipped_date' : datetime.date(2005,7,15).strftime('%c'),
'subtotal' : 6107.0820,
'tax_amount' : 586.1203,
'freight' : 183.1626,
'discount_amt' : 1982.872,
'total_due' : 4893.3929,
'items' : [
{'order_qty' : 3,
'product_code' : 'A-123', # notice how in item details we no longer reference a ProductId
'product_name' : 'Product 1', # instead we have decided to denormalise our schema and include
'currency_symbol' : '$', # the Product details relevant to the Order on to the Order directly
'currecny_code' : 'USD', # this is a typical refactor that happens in the course of an application
'unit_price' : 17.1, # that would have previously required schema changes and data migrations etc.
'line_price' : 5.7
}
],
'ttl' : 60 * 60 * 24 * 30
}
return order2
#staticmethod
def GetSalesOrder2(document_id):
order = {'id' : document_id, 'account_number' : 'Account3',#
'purchase_order_number' : 'PO15428132601',
'order_date' : datetime.date(2005,7,11).strftime('%c'),
'due_date' : datetime.date(2005,7,21).strftime('%c'),
'shipped_date' : datetime.date(2005,7,15).strftime('%c'),
'subtotal' : 6107.0820,
'tax_amount' : 586.1203,
'freight' : 183.1626,
'discount_amt' : 1982.872,
'total_due' : 4893.3929,
'items' : [
{'order_qty' : 3,
'product_code' : 'A-123', # notice how in item details we no longer reference a ProductId
'product_name' : 'Product 1', # instead we have decided to denormalise our schema and include
'currency_symbol' : '$', # the Product details relevant to the Order on to the Order directly
'currecny_code' : 'USD', # this is a typical refactor that happens in the course of an application
'unit_price' : 17.1, # that would have previously required schema changes and data migrations etc.
'line_price' : 5.7
}
],
'ttl' : 60 * 60 * 24 * 30
}
def run_sample():
with IDisposable(document_client.DocumentClient(HOST, {'masterKey': MASTER_KEY} )) as client:
try:
DocumentManagement.CreateDocuments(client)
DocumentManagement.CreateStoredProcedure(client)
DocumentManagement.CountEntries(client)
DocumentManagement.AddEntry(client)
DocumentManagement.CountEntries(client)
DocumentManagement.DeleteDocument(client,'SalesOrder')
DocumentManagement.DeleteCollection(client)
except errors.HTTPFailure as e:
print('\nrun_sample has caught an error. {0}'.format(e.message))
finally:
print("\nrun_sample done")
if __name__ == '__main__':
try:
run_sample()
except Exception as e:
print("Top level Error: args:{0}, message:N/A".format(e.args))
The reason your code is failing is because your GetSalesOrder2 method is not returning anything (or in other words returning an undefined object). If you look closely it is missing return statement. Please change this method to something like:
def GetSalesOrder2(document_id):
order = {'id' : document_id, 'account_number' : 'Account3',#
'purchase_order_number' : 'PO15428132601',
'order_date' : datetime.date(2005,7,11).strftime('%c'),
'due_date' : datetime.date(2005,7,21).strftime('%c'),
'shipped_date' : datetime.date(2005,7,15).strftime('%c'),
'subtotal' : 6107.0820,
'tax_amount' : 586.1203,
'freight' : 183.1626,
'discount_amt' : 1982.872,
'total_due' : 4893.3929,
'items' : [
{'order_qty' : 3,
'product_code' : 'A-123', # notice how in item details we no longer reference a ProductId
'product_name' : 'Product 1', # instead we have decided to denormalise our schema and include
'currency_symbol' : '$', # the Product details relevant to the Order on to the Order directly
'currecny_code' : 'USD', # this is a typical refactor that happens in the course of an application
'unit_price' : 17.1, # that would have previously required schema changes and data migrations etc.
'line_price' : 5.7
}
],
'ttl' : 60 * 60 * 24 * 30
}
return order
Also, each document in a collection need to have a unique id so please define a different id for this document.
I am fully aware there are other topics on this on this website, but the solutions do not work for me.
I am trying to grab the 'last' value from this API address:
https://cryptohub.online/api/market/ticker/PLSR/
In Python, I have tried many different scripts, and tried hard myself but I always end up getting a "KeyError" although "last" is in the API. Can anyone help me?
Your data in response has structure:
$ curl https://cryptohub.online/api/market/ticker/PLSR/ | json_pp
{
"BTC_PLSR" : {
"baseVolume" : 0.00772783,
"lowestAsk" : 0.00019999,
"percentChange" : -0.0703703704,
"quoteVolume" : 83.77319071,
"last" : 0.000251,
"id" : 78,
"highestBid" : 5e-05,
"high24hr" : 0.000251,
"low24hr" : 1.353e-05,
"isFrozen" : "0"
}
}
i.e. dictionary inside dictionary, so to extract values you need:
data = response.json()["BTC_PLSR"]
visitors = data["id"]
UPDATE on comment:
Im not sure I understand you, I did a simple test and it works fine:
$ python3 << EOF
> import requests
> url = 'https://cryptohub.online/api/market/ticker/PLSR/'
> response = requests.get(url)
> data = response.json()['BTC_PLSR']
> print('ID ==> ', data['id'])
> EOF
ID ==> 78
As you can see line print('ID ==> ', data['id']) returns output ID ==> 78
Test source code:
import requests
url = 'https://cryptohub.online/api/market/ticker/PLSR/'
response = requests.get(url)
data = response.json()['BTC_PLSR']
print('ID ==> ', data['id'])
This is what I currently have
code
coll = con['X']['Y']
s = "meta http equiv"
m = {'i': s}
n = json.dumps(m)
o = json.loads(n)
coll.insert(o)
data
{
"_id" : ObjectId("58527fe656c7a95cfaf40a15"),
"i" : "meta http equiv"
}
Now in the next iteration, s will change(as per my computations) and I want to append the value of s to same key
let's say in next iteration s becomes sample test data and on same key i
So I want this
{
"_id" : ObjectId("58527fe656c7a95cfaf40a15"),
"i" : "meta http equiv sample test data and"
}
How to achieve this?
Change the way you have formed s:
s = "meta http equiv"
s = (coll.get('i', '') + ' ' + s) if coll.get('i', '') else s
If coll isn't a dict object use getattr instead:
s = "meta http equiv"
s = (getattr(coll, 'i', '') + ' ' + s) if getattr(coll, 'i', '') else s
Need this:
POST&https%3A%2F%2Fsecure.trademe.co.nz%2FOauth%2FRequestToken&oauth_callback%3Dhttp%253A%252F%252Fwww.website-tm-access.co.nz%252Ftrademe-callback%26oauth_consumer_key%3DC74CD73FDBE37D29BDD21BAB54BC70E422%26oauth_nonce%3D7O3kEe%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1285532322%26oauth_version%3D1.0%26scope%3DMyTradeMeRead%252CMyTradeMeWrite
Myattempt:
New_base_string ="POST&https%3A%2F%2Fsecure.trademe.co.nz%2FOauth%2FRequestToken&oauth_callback%3Dhttp%253A%252F%252Fwww.website-tm-access.co.nz%252Ftrademe-callback%26oauth_consumer_key%" + str(consumer_key) +"3DC74CD73FDBE37D29BDD21BAB54BC70E422%26oauth_nonce%3" + str(nonce) + "%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3" + str(time) + "%26oauth_version%3D1.0%26scope%3DMyTradeMeRead%252CMyTradeMeWrite"
I just tried to append it to the end, will this work or will i need to append to a list and then encode?
so like this:
headers = { my_variable + other_variable }
authorization = '5C82CC6BC7C6472154FBC9CAB24A29A2 ' + ', '.join([key + '="' + urllib.parse.quote_plus(str(value)) + '"' for key, value in headers.items()])
General
If you want to URL encode parameters to your POST request the best way is:
import urllib
f = { 'eventName' : 'myEvent',
'eventDescription' : 'cool event',
'url' : 'http://www.google.com'}
print 'POST&%s' % urllib.urlencode(f)
Output:
POST&eventName=myEvent&url=http%3A%2F%2Fwww.google.com&eventDescription=cool+event
with Dictionary its not ordered if you want to order it just use a list
import urllib
f = [ ('eventName', 'myEvent'),
('eventDescription', 'cool event'),
('url', 'http://www.google.com')]
print 'POST&%s' % urllib.urlencode(f)
Output
POST&eventName=myEvent&eventDescription=cool+event&url=http%3A%2F%2Fwww.google.com
How to get your need this string (Python 3.5)
While the general example is tested in python 2.7, I wrote your example with python 3.5 code.
import urllib.parse
method = "POST"
url = "https://secure.trademe.co.nz/Oauth/RequestToken"
params = [('oauth_callback', 'http://www.website-tm-access.co.nz/trademe-callback'),
('oauth_consumer_key', 'C74CD73FDBE37D29BDD21BAB54BC70E422'),
('oauth_nonce', '7O3kEe'),
('oauth_signature_method', 'HMAC-SHA1'),
('oauth_timestamp', 1285532322),
('oauth_version', 1.0),
('scope', "MyTradeMeRead,MyTradeMeWrite")]
print('POST&%(url)s&%(params)s' % { 'url' : urllib.parse.quote_plus(url), 'params' : urllib.parse.quote_plus(urllib.parse.urlencode(params)) })
Output
POST&https%3A%2F%2Fsecure.trademe.co.nz%2FOauth%2FRequestToken&oauth_callback%3Dhttp%253A%252F%252Fwww.website-tm-access.co.nz%252Ftrademe-callback%26oauth_consumer_key%3DC74CD73FDBE37D29BDD21BAB54BC70E422%26oauth_nonce%3D7O3kEe%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1285532322%26oauth_version%3D1.0%26scope%3DMyTradeMeRead%252CMyTradeMeWrite