Mongodb, create update in python - python

Here is my mongodb object. I need to write update function for "graded" field. Sometimes i need to create this field, sometimes update.
#api_view(['POST'])
def updateGrade(request):
db = connect_to_db()
data = json.loads(request.body)
db.update({ '_id': ObjectId(data["id"])},
{ "$set" : {
"worksheetSolutions.$[idx]": {"graded": data["status"]}
} },
{"arrayFilters":[{"idx":data["answerId"]}]}
)
q = db.find_one({'_id': ObjectId(data["id"])})
q['_id'] = str(q['_id'])
return JsonResponse(q, safe=False)
Here is my python code. (not correct at all as I see now)
data.id => _id
data.answerId => id of answer
data.status => true/false var

Ok, with some time i got it
def updateGrade(request):
db = connect_to_db()
data = json.loads(request.body)
db.update({ '_id': ObjectId(data["id"]), "worksheetSolutions.id": data["answerId"]},
{ "$set" : {
"worksheetSolutions.$.graded": data["status"]
} }
)
q = db.find_one({'_id': ObjectId(data["id"])})
q['_id'] = str(q['_id'])
return JsonResponse(q, safe=False)

Related

AttributeError: Could not locate column in row for column 'to_dict'

I use flask with datatable.js plugin with ajax. I am getting following error. Looks like this error is thrown at the end of my view (see code at the bottom). I am not able to locate the cause of issue, any thoughts?
Error: (thrown from view shown below in code)
'data': [it.to_dict() for it in query],
AttributeError: Could not locate column in row for column 'to_dict'
This is my model:
class DiskSpaceView(Database.db.Model, UserMixin):
__tablename__ = 'view_space'
__table_args__ = {"schema":"config"}
column_not_exist_in_db = Database.db.Column(Database.db.Integer, primary_key=True) # just add for sake of this error, dont add in db
object_type = Database.db.Column(Database.db.String)
schemaname = Database.db.Column(Database.db.String)
tablename = Database.db.Column(Database.db.String)
indexname = Database.db.Column(Database.db.String)
object_size_bytes = Database.db.Column(Database.db.String)
object_size = Database.db.Column(Database.db.String)
def to_dict(self):
return {
'column_not_exist_in_db': random.getrandbits(64),
'object_type': self.object_type,
'schemaname': self.schemaname,
'tablename': self.tablename,
'indexname': self.indexname,
'object_size_bytes': self.object_size_bytes,
'object_size': self.object_size
}
This is my Ajax call:
$(document).ready(function () {
var table = $("#dataTbDiskSpace").DataTable({
scrollY: "600px",
scrollCollapse: true,
paging: true,
ajax: "/api/datadiskspace",
serverSide: true,
pageLength : 200,
success: function (ajax) {
console.log("test.js >> DataTable ajax >>>" + JSON.stringify(ajax));
},
columns: [
{ data: "object_type" },
{ data: "schemaname"},
{ data: "tablename"},
{ data: "indexname"},
{ data: "object_size_bytes"},
{ data: "object_size"}
],
columnDefs: [
{
defaultContent: "-",
targets: "_all",
},
],
});
});
This is my view:
#userviews.route('/api/datadiskspace')
def datadiskspace():
query = DiskSpaceView.query.with_entities(DiskSpaceView.object_type, DiskSpaceView.schemaname, DiskSpaceView.tablename,DiskSpaceView.indexname,DiskSpaceView.object_size_bytes, DiskSpaceView.object_size)
print(query)
# search filter
search = request.args.get('search[value]')
if search:
query = query.filter(DatabasePostgres.db.or_(
DiskSpaceView.tablename.like(f'%{search}%'),
DiskSpaceView.indexname.like(f'%{search}%')
))
total_filtered = query.count()
# sorting
order = []
i = 0
while True:
col_index = request.args.get(f'order[{i}][column]')
if col_index is None:
break
col_name = request.args.get(f'columns[{col_index}][data]')
if col_name not in ['object_type', 'schemaname', 'tablename', 'indexname','object_size_bytes','object_size']:
col_name = 'schemaname'
descending = request.args.get(f'order[{i}][dir]') == 'desc'
col = getattr(DiskSpaceView, col_name)
if descending:
col = col.desc()
order.append(col)
i += 1
if order:
query = query.order_by(*order)
# pagination
start = request.args.get('start', type=int)
length = request.args.get('length', type=int)
query = query.offset(start).limit(length)
#debug
counter = 1
for i in query:
print(i)
print(counter)
counter += 1
# response
return {
'data': [it.to_dict() for it in query],
'recordsFiltered': total_filtered,
'recordsTotal': DiskSpaceView.query.count(),
'draw': request.args.get('draw', type=int)
}
EDIT:
I think it may something to do with pagination - if i set for example 200 in my ajax call like: pageLength : 200 then in my view when i print (see #debug) it prints me 200 rows. When I for instance change to pageLength : 50. My print loop prints me 50 rows... I don't understand what's the case but this seems to be pretty intresting.

500 (Internal Server Error) and Unexpected token < in JSON at position 0

I'm trying to create a website based on guides. When it came to updating the basket through the buttons (decrease and increase), then trying to click on them, errors are issued: Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0, which refers to
.then((data) => {
location.reload()
});
cart.js:24 POST http://127.0.0.1:8000/update_item/ 500 (Internal Server Error)
which refers to
fetch(url, {
method:'POST',
headers:{
'Content-Type':'application/json',
'X-CSRFToken': csrftoken,
},
and i have error in console pycharm line 104, in updateItem
productId = data['productId']
KeyError: 'productId'
code cart.js:
var updateBtns = document.getElementsByClassName('update-cart')
for (i = 0; i < updateBtns.length; i++) {
updateBtns[i].addEventListener('click', function () {
var productId = this.dataset.stuff
var action = this.dataset.action
console.log('productId:', productId, 'Action:', action)
console.log('USER:', user)
if (user == 'AnonymousUser') {
console.log('User is not authenticated')
} else {
updateUserOrder(productId, action)
}
})
}
function updateUserOrder(productId, action){
console.log('User is authenticated, sending data...')
var url = '/update_item/'
fetch(url, {
method:'POST',
headers:{
'Content-Type':'application/json',
'X-CSRFToken': csrftoken,
},
body:JSON.stringify({'productId':productId, 'action':action})
})
.then((response) => {
return response.json();
})
.then((data) => {
location.reload()
});
}
views.py
def updateItem(request):
data = json.loads(request.body)
productId = data['productId']
action = data['action']
print('Action:', action)
print('Product:', productId)
customer = request.user.customer
product = Stuff.objects.get(id=productId)
order, created = Order.objects.get_or_create(customer=customer, complete=False)
orderItem, created = OrderItem.objects.get_or_create(order=order, product=product)
if action == 'add':
orderItem.quantity = (orderItem.quantity + 1)
elif action == 'remove':
orderItem.quantity = (orderItem.quantity - 1)
orderItem.save()
if orderItem.quantity <= 0:
orderItem.delete()
return JsonResponse('Item was added', safe=False)
Thank you in advance
What is your Python version?
From Python v3.0, json.loads() will only accept unicode string.
Maybe the problem is that you have to decode request.body first :
data = json.loads(request.body.decode('utf-8'))
If this is not the problem try to check what you are receiving. Because the "<" character looks like html or xml. For example, change your function to:
def updateItem(request):
data = json.loads(request.body)
return HttpResponse(data)

Django `request.query_params.get("page")` returns None?

When I user types in search box and submits, this is how I set the url:
const submitHandler = (event: FormEvent) => {
event.preventDefault();
if (keyword) {
Router.push({ pathname: "", query: { keyword: keyword, page: 1 } });
} else {
Router.push(Router.router?.asPath as string);
}
};
this is how it looks on the url:"http://localhost:4500/?keyword=ca&page=1"
I use Next.js for front end and this is how I send the query params.
export const getServerSideProps = wrapper.getServerSideProps(
async (context) => {
const { store, query } = context;
console.log("params", query);
store.dispatch(fetchProductsStart(query));
store.dispatch(END);
await (store as SagaStore).sagaTask.toPromise();
const state = store.getState();
const productListState = state.productList ? state.productList : null;
return { props: { productListState } };
}
);
console.log("params", query) returns this object:"{ keyword: 'g', page: '1' }". This is what I am sending to backend.
Here is "fetchProductsStart"
export const fetchProductsStart = (
queryParams: {keyword:string,page:string}
): actions.IFetchProductsStart => ({
type: ProductListActionTypes.PRODUCT_LIST_START,
payload: queryParams,
});
This is how I tried to get the params in the backend:
#api_view(['GET'])
def getProducts(request):
q=request.query_params.get("page")
print("page query param",q)
query = request.query_params
print("query_params",query)
print("page query param",q) returns "None"
print("query_params",query) returns "<QueryDict: {'[object Object]': ['']}>"
The issue so far I was sending an object. Instead I stringified it "
store.dispatch(fetchProductsStart(JSON.stringify(query)));
now in backend
query = request.query_params
print("query",query)
it prints: query <QueryDict: {'{"keyword":"m","page":"1"}': ['']}>
but request.query_params.get("keyword") is still not working. It returns None
Try getting request parameters like this request.GET.get('param_name')
the problem was the way how I passed the query params to the backend:
Instead of this store.dispatch(fetchProductsStart(JSON.stringify(query)))
store.dispatch(
fetchProductsStart(`keyword=${query["keyword"]}&page=${query["page"]}`)
);

Load data from MongoDb to Elasticsearch through python

I have some json data loaded in MongoDb. e.g. doc1 = {"id": 1,"name": "x1"},doc2 = {"id": 2,"name": "x2"},doc3 = {"id": 3,"name": "x3"}. Now I want this data to import from MongoDb to Elasticsearch. I wrote this piece of code.
mgclient = MongoClient()
db = mgclient['light-test']
col = db['test']
es1 = Elasticsearch()
print ("Connected", es1.info())
es1.indices.create(index='light-test', ignore=400)
# Pull from mongo and dump into ES using bulk API
actions = []
for data in tqdm(col.find(), total=col.count()):
data.pop('_id')
action = {
"_index": 'light-test',
"_type": 'test',
"_source": data
}
actions.append(action)
print("complete")
# Dump x number of objects at a time
if len(actions) >= 100:
deque(parallel_bulk(es1, actions), maxlen=0)
actions = []
print("done")
a = es1.search(index='light-test', body={
'query': {
'match_all': {
}
}
})
print(a)
The problem is in the query returned. The hits shows blank whereas it should had returned the json files.
results
Help me in importing the data from MongoDb to Elasticsearch.
app = Flask(__name__)
MONGO_URL = '...'
mgclient = MongoClient(MONGO_URL, ssl=True, ssl_cert_reqs=ssl.CERT_NONE)
db = mgclient['light']
col = db['task']
doc1 = {...}
doc2 = {...}
doc3 = {...}
post_id = col.insert_many([doc1, doc2, doc3])
print(col.count())
es1 = Elasticsearch(...)
ESinfo=(es1.info())
# Pull from mongo and dump into ES using bulk API
actions = []
for data in tqdm(col.find(), total=col.count()):
data.pop('_id')
action = {
"index": {
"_index": 'light',
"_type": 'task',
}
}
actions.append(action)
actions.append(data)
#delete = es1.indices.delete(index = 'light')
request_body = {
"settings" : {
"number_of_shards": 1,
"number_of_replicas": 0
}
}
es1.indices.create(index='light', body = request_body, ignore=400)
res = es1.bulk(index = 'light', body = actions, refresh = True)
result = col.find()
names = []
for obj in col.find():
name = obj['name']
names.append(name)
print(names)
#app.route('/query')
def Query():
a = es1.search(index='light', body={
'query': {
'match': {
'name': '...',
}
}
})
return jsonify(query=a)
if __name__ == "__main__":
app.run(host='0.0.0.0', port=1024)
This has helped. thank you :)

Issue storing multi valued json format dictionary into mysql table in DJango

I have below ajax call in my template
temp.html
function saveprof() {
$.ajax({
type: "POST",
url: "saveprof",
async: true,
data: {
'radinput_Aj' : fun(),
'csrfmiddlewaretoken': $("input[name=csrfmiddlewaretoken]").val()
},
success: function (data, textStatus, jqXHR) {
$('#message').html(data);
}
});
}
fun() returns a json format object v - which is as below :
example :
var v = [
{ axis: "", value: 4, order: 0 },
{ axis: "", value: 4, order: 1 },
{ axis: "", value: 4, order: 2 },
{ axis: "", value: 4, order: 3 },
{ axis: "", value: 4, order: 4 },
{ axis: "", value: 4, order: 5 },
{ axis: "", value: 4, order: 6 }
];
Views.py
def saveprof(request):
if request.method == "POST":
radinputV=[]
radinputV = request.POST.get('radinput_Aj')
else:
response_data = 'Nothing to update!'
return HttpResponse(response_data, content_type="text/plain")
response_data = ''
try:
*(Here, I would like to insert the incoming dictionary (radinputV) rows into my model skills)*
except:
response_data = 'Ouch! Something went wrong!'
return HttpResponse(response_data, content_type="text/plain")
Below is the skills model :
class skills(models.Model):
id = models.CharField(max_length=300,blank=True)
skill = models.CharField(max_length=300,blank=True)
rating = models.CharField(max_length=300,blank=True)
ordernum = models.CharField(max_length=300,blank=True)
Here is the mapping of incoming json dictionary from template with the fields in skills model -
skill is axis,
rating is value,
ordernum is order
In the view :
radinputV=[]
radinputV = request.POST.get('radinput_Aj')
radinputV1 = request.POST.get('radinput_Aj[0][value]')
I can access dictionary item by using above notation.
However, if I use above notation, I would need to write 21 statements like this (7 rows * 3 columns) of Dictionary object V... is there a simple way for this ?
How to handle this scenario of inserting multiple rows into mysql table from template JSON object - Django view ?
Edited with the latest try using get method.
You can't send a data structure like this via standard form parameters. You need to serialize it to JSON before sending, and then deserialize it in the view.
Change the data parameter as follows:
data: {
'radinput_Aj' : JSON.stringify(fun()),
'csrfmiddlewaretoken': $("input[name=csrfmiddlewaretoken]").val()
},
and the view:
if request.method == "POST":
data = request.POST.get('radinput_Aj')
radinputV = json.loads(data)

Categories