Python appengine Query does not work when using a variable - python

I am trying to use a fetcher method to retrieve items from my datastore. If I use the following
def getItem(item_id):
q = Item.all()
q.filter("itemid = ", item_id)
It fails because nothing is returned. If I hard code in an item like
def getItem(item_id):
q = Item.all()
q.filter("itemid = ", 9000)
it fetches just fine, and sings merrily along. I have tried every which way to get this to work. I have used
result = db.GqlQuery("SELECT * FROM Item WHERE item_id = :1 LIMIT 1",
title).fetch(1)
to the same effect. If I hard code in a number, works fine. I have tried setting the select statement as a local string, assembling it that way, casting the int as a string, and nothing. When I output the SELECT statement to the screen, looks fine. I can cut ans paste the output into the string, and whammo, it works. Any help would be appreciated.

Does it make any difference if you do this:
def getItem(item_id):
q = Item.all()
q.filter("itemid = ", int(item_id))
The most likely cause of the problem that I can see is that the item_id parameter may be a string even though it is holding a numerical value. Coerce it to an int, and see if that makes any difference.

Related

How to use quotation marks and full stops in Python function argument

I can't seem to get this formatting working in Python. I am trying to define a function that holds an argument on the form - "[Some].[Name]"
Can anyone tell me how I can this working? I think I have tried all combinations of ' and ", but regardless both the [.] and ["] in the argument seems to not work.
In the below code I am trying to define the argument as "VWS.co"
def get_stock_data(Company):
#This function defines the data to be collected.
#send a get request to query Company's end of day stock prices in period
global VWS_data
Stock_data = yf.Ticker(Company)
Stock_data = Stock_data.history(period="5y")
# look at the first 5 rows of the dataframe
print(Stock_data)
print(Stock_data.describe(include='all'))
get_stock_data("VWS.co")
Edit:
Using escape characters get_stock_data(""VWS.co"") got the definition working. However, something is still wrong. When I run the script it still only works using "VWS.co" as the definition. See below code, the VWS_data_with_arg works. VWS_data does not. Am i missing something really obvious here?
def get_stock_data(Company):
Stock_data = yf.Ticker("VWS.co")
Stock_data_with_arg = yf.Ticker(Company)
VWS_data = Stock_data.history(period="5y")
VWS_data_with_arg = Stock_data_with_arg.history(period="5y")
print(VWS_data) #This returns the expected values
print(VWS_data_with_arg) #This returns an empty dataset
get_stock_data("\"VWS.co\"")
You should use escape characters.
get_stock_data("\"VWS.co\"")
You can use raw strings
get_stock_data(r'"VWS.co"')

Python code not fetching up to date sensor values

So I am trying to fetch for light sensor values using the light sensor that is part of GrovePi. When I run the sample script here (https://github.com/DexterInd/GrovePi/blob/master/Software/Python/grove_light_sensor.py) the code works perfectly so this leads me to conclude that the script I wrote is somehow only fetching for one value and just stores it and outputs it without fetching for the new updated value. Note: I am storing my values in a dictionary and posting to Dweet.io
If anyone can lead me to the right direction that would be great, my code is below :
import time
import grovepi
light_sensor = 0
grovepi.pinMode(light_sensor,"INPUT")
def getLight():
sensor_value = grovepi.analogRead(light_sensor)
s = sensor_value
#S seems to print just one number here?
print(s)
return s
def values():
dict = {}
dict["light"] = getLight()
return dict
while True:
dict = values()
print (dweepy.dweetfor(n, dict))
time.sleep(2)
Not an engineer, but why are you adding the whole dictionary part at all? Your sample code does not do that, and dweet certainly does not need it.
My guess is that is your issue, remove it.
While True:
print (dweepy.dweetfor(s))

Comparing tuple values

I'm quite new to Python/Flask and am writing a little script for some home automation I'm playing with.
At the moment, there's a route in my script that gets run by a cron job. This sniffs for bluetooth packets to see who's in and who's out of the house so I can control the heating. There's a row in my table for each person and a status which is either In or Out.
This works perfectly.
I've got another route to read the values back and display either a green or red bar on my dashboard depending on if they're in or out.
It's reading the values and doing some logic that I'm having problems with.
If I get the status for a person and display it on my dashboard (created with an HTML template), the value it displays is:
('In',)
In the MySQL table it's just In - no quotes or parentheses.
In my Python script I have:
conn = MySQLdb.connect(host="localhost", user = "*****", passwd = "*****", db = "mydb")
cursor = conn.cursor()
cursor.execute("select status from occupants WHERE id = '1'")
data = cursor.fetchone()
result = data
#result = str(result)
if (result == "In"):
result = "In"
else:
result = "Out"
This always returns Out.
I've tried various things in my if statement but I obviously haven't hit the right one. I've even tried:
if (result == "('In',)")
But even this returns Out.
Starting to tear my hair out now as I've been searching and playing for about 2 days just on this.
Any ideas gratefully received!
You need to get the value by index.
Python returns tuples for the rows.You need to get the first column.
Just get the value by index, data[0]
Then you go on with comparison.
Edit: when you use the "in" operators, you are just looping through the tuple.
It works buts not a good idea, when you already know for sure, the data you are looking for is at index 0.
You are using cursor.fetchone(), which returns a tuple or None(if element not found). So what you are receiving after executing the command is a tuple with only one element, which makes lesser sense in this context, but that is how this Python API returns data. So even after using fetchone() you need to access the first element explicitly, which can be done as lst[0]. So you need to change the line as:
result = ""
if data is not None:
result = data[0]
print result
You have more Data in "result" then just "In". For example:
a = ["yes", "hello"]
b = "no"
if "yes" == a:
print("yes yes yes")
else:
print("Something is wrong")
This gives you "Something is wrong" as output, but if you do:
a = ["yes", "hello"]
b = "no"
if "yes" in a:
print("yes yes yes")
else:
print("Something is wrong")
Now you get "yes yes yes" as output. Hope this helps a bit :)
Agree with Abhijith; indexing would be a better idea.
It's likely the result of you database query should look like this:
database_query_result = [('In',)]
If that's the case, you could just grab the occupants status like the below to get the answer you desire without a logical comparison.
result = database_query_result[0][0]
print(result)
Why this works:
database_query_result[0] gives you the tuple -> ('In', )
database_query_result[0][0] gives you the tuple's value. -> 'In'
Ok, as always, 5 minutes after posting, I try something different and get it working. However, I'm not sure if this is a fudge or if it's a valid thing to do:
if 'In' in result:
This now works.
For the purposes of this exercise, it doesn't really matter if it's a dirty workround but I'd like to know if there's a more elegant/conventional solution just for my learning.

OdooV8 - Why does it take so long to create a record in 'res_partner' in my case

I recently started to develop with odoo8 and I've met a problem.
My problem is that I have two classes : 'helpdesk' and 'res_partner' and I don't know why my code stuck for a long time when I create a new record in 'res_partner' but when I comment this block of codes (below) my code works great.
self.env['res.partner'].create({
'name': nameFmt,
'firstname': self.firstNameOfUser.strip().lower().title(),
'lastname': self.lastNameOfUser.strip().upper(),
'birthdate': newDateFmt,
'birth_place': self.pBirthOfUser,
'is_company': False
})
'helpdesk' class has several fields and methods to get information, and computes them from the user inputs. Once the information computed, I create my record which is a new partner.
How I tried to solve my problem, I :
Launched odoo in shell mode with '--debug' option and a pdb where the code is stuck (it's stuck at the 'create' method as I said)
Read some threads and documentations about my problem, but most are in v7 for the create method and anybody has been stuck like this for the creation of a record
Checked each value that I sent to create my new record
Saw the behavior of records and how they are stored with phpPgAdmin
For more information, this is my entire method definition :
#api.one
def addPartnerInDB(self):
if (not self.firstNameOfUser or
not self.lastNameOfUser or
not self.dobOfUser or
not self.pBirthOfUser):
raise ValidationError(u"Tous les champs sp\u00E9cifi\u00E9s pour "
u"cette demande doivent \u00EAtre remplis !")
# Avoid concurrent drop-down
self.dropDownList1 = False
self.dropDownList3 = False
# Get every partners
listOfPartners = self.env['res.partner'].search(
[
('is_company', '=', False)
]
)
# Avoid useless compute for each iteration
newDateFmt = u"".join(datetime.datetime\
.strptime(str(self.dobOfUser), "%Y-%m-%d")\
.strftime("%d/%m/%Y"))
newFNameFmt = self.firstNameOfUser.strip().replace(" ", "-").lower()
newLNameFmt = self.lastNameOfUser.strip().replace(" ", "-").lower()
newBPFmt = self.pBirthOfUser.strip().replace(" ", "-").lower()
matchedPartners = []
# Fetch partner specified by the user
for p in listOfPartners:
if (newFNameFmt == p.firstname.strip().replace(" ", "-").lower() and
newLNameFmt == p.lastname.strip().replace(" ", "-").lower()):
matchedPartners.append(p)
partnerAlreadyExist = False
# If the list is not empty, then the fetch is enhance
if (matchedPartners):
for m in matchedPartners:
partnerDOB = False
partnerBP = False
if (not isinstance(m.birthdate, bool)):
if (newDateFmt == m.birthdate):
partnerDOB = True
if (not isinstance(m.birth_place, bool)):
if ((newBPFmt
== m.birth_place.strip().replace(" ", "-").lower())):
partnerBP = True
# If one of them it's true, the user already exist
if (partnerDOB or partnerBP):
partnerAlreadyExist = True
# Avoid useless iteration
break
# If the user specified doesn't exist he's created
if (not partnerAlreadyExist):
# Encode the string to avoid UnicodeError and further string errors
nameFmt = (self.lastNameOfUser.strip().upper(),
+ u" "
+ self.firstNameOfUser.strip().lower().title())
self.env['res.partner'].create(
{
'name': nameFmt,
'firstname': self.firstNameOfUser.strip().lower().title(),
'lastname': self.lastNameOfUser.strip().upper(),
'birthdate': newDateFmt,
'birth_place': self.pBirthOfUser,
'is_company': False
}
)
else:
raise ValidationError(u"L'utilisateur renseign\u00E9 "
u"existe d\u00E9j\u00E0 !")
EDIT
After several attempts to debug my code with pdb, I noticed that something went wrong in the for statement when I compare firstnames and lastnames :
for p in listOfPartners:
if (newFNameFmt == p.firstname.strip().replace(" ", "-").lower()
and newLNameFmt == p.lastname.strip().replace(" ", "-").lower()):
# Append element
Indeed, pdb blocks (2/3 sec) for each start of for statement before it gives me the hand back.
For example :
(pdb) ->if (newFNameFmt == p.firstname.strip().replace(" ", "-").lower() and
# stuck 2-3 seconds
(pdb) -> newLNameFmt == p.lastname.strip().replace(" ", "-").lower()):
This behavior continues for about the first iterations of the for statement, after this amount of iterations, this behavior is no longer adopted for the rest of the iterations. Once I arrived at the create statement (with pdb), the creation record is miraculously unlocked and the code works.
I still don't know why this problem occurs and I still don't know how to solve it.
you got that issue because maybe you have compare 2 different type! In your case, you maybe try to compare between res_partner object and string type or another! That should be res.partner(2973,).id or res.partner(2973,).name ....
I've found an answer for my question, and I think to know where the problem came from.
Where was my problem
So the problem came from my first for statement which is :
listOfPartners = self.env['res.partner'].search(
[
('is_company', '=', False)
]
)
for p in listOfPartners:
if (newFNameFmt == p.firstname.strip().replace(" ", "-").lower()
and newLNameFmt == p.lastname.strip().replace(" ", "-").lower()):
matchedPartners.append(p)
Theoretically nothing could be wrong with the for and search statements since they do what I want to do. But the problem is that each iteration that the program did in this for was 'n' queries sent to the PostgresSQL server (where n corresponds to the number of time that p is used in each iteration. In my case n = 2). This issue escalated quickly since search returned me about a thousand of partners (which are represented by id of each record saved in res.partner that matched the search query). So in the for this corresponds to thousands of queries that I sent in a very short time to the PostgreSQL server, and it seems that this server couldn't handle this amount of requests in a very short time.
So the problem was not the code in himself, but the behavior that I gave to him. The result of that behavior gave another behavior to the PostgreSQL for the further queries that I will give via Odoo, like create.
How I solved it
The solution for me was to use the psycopg2 module. This module allowing communication with the postgreSQL server. The main difference between both in my case was that Odoo stayed in communication with the PostgreSQL server even if I used search to get only values that I wanted. While psycopg2 gived me a list (of tuples) that only contains "real" values and not an id like Odoo gave me with search.
Once again, I don't know if the solution that I choosed was the best or if the issue came from there like I said above but this solution works well for me and I hope it will help others users stuck in a problem with the same behavior.

Python check for null cursor using for

I have a python script that I want to perform an action for each row found in a table or report if no rows were found.
This is some dummy code for troubleshooting
cur_users = lv_pgsql.cursor()
cur_users.execute("select * from users where us_idno > 10")
for lr_users in cur_users:
print("ping")
I know I will be able to check if I attempt to store the results in an array like bellow
la_users = cur_users.fetchall()
if len(la_users) != 0:
print("ping")
But is it possible to check with the above code as well without using fetchall?
You can wrap your code in a try except block, thus if the cursor is None it will throw an error. Also by doing this you can capture other errors and handle them.
if cur_users.execute("select * from users where us_idno > 10").rowcount:
print "ping!"
should do what you want?

Categories