Why does this query crash if there are no matching results instead of returning an empty result? - azure-cosmosdb

I am using this query to get some statistics from our DB
SELECT DateTimePart("yyyy", c.RedeemedDate) AS RedeemedInYear,
DateTimePart("m", c.RedeemedDate) AS RedeemedInMonth,
AVG(c.RedPriceStoreSummary ?? c.WhitePriceStoreSummary) AS AverageBasketValue
FROM c
WHERE c.IsRedeemed = true
AND c.Brand = 'xxx'
AND c.RedeemedDate != null
AND DateTimePart("yyyy", c.RedeemedDate) = DateTimePart("yyyy", GetCurrentDateTime())
GROUP BY DateTimePart("m", c.RedeemedDate),
DateTimePart("yyyy", c.RedeemedDate)
The problem is that query crashes with the following error if there are no results
Cannot read property 'create' of undefined
If I force the query to where it gets results then everything works fine but I dont want the query to crash if there are no results I want an empty result set.
Am I missing something here?

You need to trap queries in a try block and catch if it returns a 404. This is a hold over in behavior from the previous SDK. Alternatively you can use the stream variant of these SDK functions which will not throw exceptions when data is not found, however you still want to check the http response code and you'll also need to manually deserialize the data.

Related

How can my Flask app check whether a SQLite3 transaction is in progress?

I am trying to build some smart error messages using the #app.errorhandler (500) feature. For example, my route includes an INSERT command to the database:
if request.method == "POST":
userID = int(request.form.get("userID"))
topicID = int(request.form.get("topicID"))
db.execute("BEGIN TRANSACTION")
db.execute("INSERT INTO UserToTopic (userID,topicID) VALUES (?,?)", userID, topicID)
db.execute("COMMIT")
If that transaction violates a constraint, such as UNIQUE or FOREIGN_KEY, I want to catch the error and display a user-friendly message. To do this, I'm using the Flask #app.errorhandler as follows:
#app.errorhandler(500)
def internal_error(error):
db.execute("ROLLBACK")
return render_template('500.html'), 500
The "ROLLBACK" command works fine if I'm in the middle of a database transaction. But sometimes the 500 error is not related to the db, and in those cases the ROLLBACK statement itself causes an error, because you can't rollback a transaction that never started. So I'm looking for a method that returns a Boolean value that would be true if a db transaction is under way, and false if not, so I can use it to make the ROLLBACK conditional. The only one I can find in the SQLite3 documentation is for a C interface, and I can't get it to work with my Python code. Any suggestions?
I know that if I'm careful enough with my forms and routes, I can prevent 99% of potential violations of db rules. But I would still like a smart error catcher to protect me for the other 1%.
I don't know how transaction works in sqlite but what you are trying to do, you can achieve it by try/except statements
use try/except within the function
try:
db.execute("ROLLBACK")
except:
pass
return render_template('500.html'), 500
Use try/except when inserting data.
from flask import abort
try:
userID = int(request.form.get("userID"))
[...]
except:
db.rollback()
abort(500)
I am not familiar with sqlite errors, if you know what specific error occurs except for that specific error.

Firebase + DialogFlow - Realtime database- Cloud function return query result only after second request

I'm writing a simple Google Action which will read the Firebase Realtime Database, and return result in the response. My problem is, the query result is being passed back in response to DialogFlow only after at least 2 attempts.
Below the screenshots showing the end result in the Simulator
First query screenshot
The first line of the response is returned from the Cloud Function, and contains values passed with the "Context". There is no second line in this response.
below is the screen showing the result after sending exactly the same request second time.
Second query screenshot
First line is the same as previously, but this time I also get the second line which contains the query result data.
It looks like my code is "working" (I get the correct data from the database), but for some reason it only works if I trigger it at least 2 times in quick succession.
Below is the code snipped which handle this request:
function googleAssistantHandler(agent) {
let conv = agent.conv();
let outCommandContext = agent.getContext('outcommand');
let outCharacterContext = agent.getContext('outcharacter');
let character = outCharacterContext.parameters.character;
let command = outCommandContext.parameters.command;
agent.add('<prosody rate="140%" pitch="0.4">' + character +' '+ command +'</prosody>');
var movesRef = admin.database().ref('characters/'+character.toLowerCase()+'/moves/');
movesRef.limitToFirst(1).orderByChild("notation")
.equalTo(command.toString()).on("child_added",function(snapshot){
agent.add(`record number is ` + snapshot.key);
});
}
I've tried using once() instead of on() (as it would make more sense in my case... i don't need to listen to changes on the database, i just want to retrieve data once)- but, I couldn't get it to work.
Can you guys help me out understanding why my query returns result only after the second trigger?
Thanks!
you are using a callback method to get the data from database so there is no guaranty that it will be called before your function is returned. to solve the issue, you need to use a Promise and return that Promise in your function so the last few lines of your function will look like this
return movesRef.limitToFirst(1).orderByChild("notation")
.equalTo(command.toString()).on("child_added").then(snapshot= > {
agent.add(`record number is ` + snapshot.key);
});
You need to always use promises when working with databases. Moreover, the first response that you see might be because of the failed function which timed out. If you see your console logs in firebase, you might see the errors. Also check your default response, if it has the text that User said $name or something similar, then that is what causes the issue in the first attempt.
If you still don't get it to work, try logging the returned data and post your logs here.

Google Appengine: Datastore query specifies a filter, the fields in the result are opposite

I'm running python appengine in the dev server. I get this surprising result when I look at this query in the debug console:
Invoice.query(Invoice.number == 3281, Invoice.paid == True).fetch()[0].paid
False
So the query is supposed to select items that match Invoice.paid == True but it in fact returns an item that has Invoice.paid == False. Any idea why this may be occurring?
My bad. I forgot to do invoice.put() after changing the 'paid' field. So it seems somehow in python the field was set to False but in the Datastore it was still True. It is strange though, that the query apparently returns a result that contradicts the filter.

Using sqlite database with qt

Here is my code, there doesn't seem to be anything wrong:
QSqlDatabase db=QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("thedata.sqlite");
db.open();
QSqlQuery query;
query.prepare("SELECT lastname FROM people where firstname='?' ");
query.bindValue(0, lineEdit->text());
bool x = query.exec();
if(x){
lineEdit_2->setText(query.value(0).toString());
}
else {
QSqlError err;
err = query.lastError();
QMessageBox::about(this,"error",err.text() );
}
When the program is working always it gives the error parameter count mismatch I'm using qt 4.8 and its own headers for using sqlite.
I would be very thankful for any advice, though I searched in google i see many posts in this issue but nothing helped me.
Thank you.
You're prepared statement is wrong, it should be:
quary.prepare("SELECT lastname FROM people where firstname=?");
Notice that there are no single quotes (') around the placeholder. If you put the quotes, it gets passed as a literal to the database, leaving you with a parameter-less query and code that passes too many parameters.
(Changing that variable name to query would be a nice touch too.)
Also you need to check the return value if QSqlQuery::prepare, and print out/display the error message you're getting from that if it fails – otherwise QSqlQuery::exec resets the current error and you'll get a pretty meaningless error message if there was a problem parsing the prepared statement.
if(x){
lineEdit_2->setText(quary.value(0).toString());
}
This is incorrect too. The you need to call (and check the return value of) query.next() to position the result set to the first row returned (if there is one). You can't use .value(X) before you've called .next().

Does "insert" in SQLite return SQLITE_OK or SQLITE_DONE?

What does statement "insert" in SQLite return in case of success?
I always believed that it should be SQLITE_DONE, but recently in my logs I found out the following string:
sqlite3_step error: 'not an error'
And here is the code that logs the mentioned string:
prepareStatement(addTranslationStmt2, "INSERT INTO translations(lang1_wordid, lang2_wordid) VALUES(?, ?)");
if (!addTranslationStmt2) return -2;
sqlite3_bind_int(addTranslationStmt2, 1, word_id);
sqlite3_bind_int(addTranslationStmt2, 2, translation_id);
if(sqlite3_step(addTranslationStmt2) != SQLITE_DONE)
{
NSLog(#"sqlite3_step error: '%s'", sqlite3_errmsg(database));
sqlite3_reset(addTranslationStmt2);
return -1;
}
sqlite3_reset(addTranslationStmt2);
I am wondering, why does it work in most cases.
Should I change SQLITE_DONE in my code to SQLITE_OK?
Thanks.
SQLITE_DONE
http://www.sqlite.org/c3ref/step.html
You could also try printing out the error code to find out what the problem is.
In cases like these, I like to look at code samples. Here are some good ones:
http://sqlite.phxsoftware.com/forums/p/76/6659.aspx
The SQLite Result Codes Reference lists SQLITE_OK as indicating a successful result. It is also the first error code, having an error code of 0, making it the canonical result (i.e. the result I would expect on a successful operation).
You should put a breakpoint or print statement in your code to find out if it really is returning zero, and check your data to make sure you're getting the result you expect. If that all checks out, I would change your condition to check for SQLITE_OK.
The details of the behavior of the sqlite3_step() interface depend on whether the statement was prepared using the newer "v2" interface sqlite3_prepare_v2() and sqlite3_prepare16_v2() or the older legacy interface sqlite3_prepare() and sqlite3_prepare16().
In the legacy interface, the return value will be either SQLITE_BUSY, SQLITE_DONE, SQLITE_ROW, SQLITE_ERROR, or SQLITE_MISUSE. With the "v2" interface, any of the other result codes or extended result codes might be returned as well.
Switching from "Debug" configuration to "Release" resolved the issue for me.

Resources