SQLAlchemy one(): No Results Found - python

I keep getting a Traceback complaining about the system not finding a result. This should not be the case given that the object is actually going through (I know this as I have a print command to confirm what is going through the query). I believe the issue is found in the method of create_category_rating(..).
When I use .one(), it throws the complaint I have below. When I use .all, it returns AttributeError: 'list' object has no attribute '_sa_instance_state' (some one else had this issue). The docs at SQLAlchemy does a good job defining these methods, but for some reason my code crashes.
The issue: What is causing the program to break if the object is going through the retrieve method? There is a bug somewhere and I have been struggling with squashing it.
I am using SQLAlchemy and python2.7:
Traceback:
ERROR: notssdb.test.test.test1
----------------------------------------------------------------------
Traceback (most recent call last):
File "/usr/local/lib/python2.7/site-packages/nose/case.py", line 197, in runTest
self.test(*self.arg)
File "/Users/ack/code/venv/NotssDB/notssdb/test/test.py", line 111, in test1
api.create_category_rating(2, 'Decision-Making', 'baseball', 'Becoming a Leader')
File "/Users/ack/code/venv/NotssDB/notssdb/api/convenience.py", line 41, in create_category_rating
assessment_results = self.retrieve_assessment_results(owner, assessment)
File "/Users/ack/code/venv/NotssDB/notssdb/api/object.py", line 324, in retrieve_assessment_results
filter(Assessment_Results.owner == owner).one()
File "/usr/local/lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 2478, in one
raise orm_exc.NoResultFound("No row was found for one()")
NoResultFound: No row was found for one()
# output from Traceback
Decision-Making
baseball
Becoming a Leader
Becoming a Leader
test1 <Assessment(name='Becoming a Leader', text='better decisions')>
convenience.py
(create method):
def create_category_rating(self, category_rating_int, category_name, username, name):
category = self.retrieve_category(category_name)
owner = self.retrieve_user(username) # added
assessment = self.retrieve_assessment(name) #added
assessment_results = self.retrieve_assessment_results(owner, assessment)
return super(ConvenienceAPI, self).create_category_rating(category_rating_int, category, assessment_results)
object.py
(retrieve method):
def retrieve_assessment_results(self, *args):
id, assessment, owner = None, None, None
if len(args) == 1:
id, = args[0]
elif len(args) == 2:
assessment, owner = args
else:
raise ValueError('Value being passed is an object')
if id is not None:
return self.session.query(Assessment_Results).\
filter(Assessment_Results.id == id).one()
elif owner is not None:
print 'test1', owner
return self.session.query(Assessment_Results).\
filter(Assessment_Results.owner == owner).one()
elif assessment is not None:
print 'test2', assessment
return self.session.query(Assessment_Results).\
filter(Assessment_Results.assessment == assessment).one()

You have the following:
self.retrieve_assessment_results(owner, assessment)
...but the arguments for "retrieve_assessment_results" is the following (with my comment added)...
def retrieve_assessment_results(self, *args):
id, assessment, owner = None, None, None
if len(args) == 1:
id, = args[0]
elif len(args) == 2:
assessment, owner = args # Note this line!
else:
raise ValueError('Value being passed is an object')
You pass owner, then assessment. But if you detect two objects, you will read assessment, then owner. In other words, you are calling the method with one order of objects, and retrieve assuming the reverse order. You can even see this occur in the debug line:
print 'test1', owner
You'd expect this to print something like test1 <User(...)>, but instead it printed...
test1 <Assessment(name='Becoming a Leader', text='better decisions')>
Also, consider using Python keyword arguments instead:
def retrieve_assessment_results(self, id=None, assessment=None, owner=None):
...
Then your call becomes less ambiguous:
self.retrieve_assessment_results(owner=owner, assessment=assessment)

one() will throw an exception if the result set is empty. Use first() and you will get the first result or Python None if no results are present.
Ditto about all() because the question does not contain relevant traceback and code.

Related

TypeError: 'bool' object is not callable using filter function

I m trying to filter out only valid emails addresses,but I getting the below error.
Traceback (most recent call last):
File "C:/Python27/ghhs.py", line 20, in <module>
valid=list(filter(a,email)) TypeError: 'bool' object is not callable
Here is the code:
def fun(email):
for i in email:
if ('#'and'.') in i:
user,url=i.split('#')
web,domain=url.split(".")
if user.replace('-','').replace('_','').isalnum() is False:
return False
elif web.isalnum() is False:
return False
elif len(domain)>3:
return False
else:
return True
else:
return True
if __name__=="__main__":
n=int(input())
email=[raw_input() for i in range(n)]
a=fun(email)
valid=list(filter(a,email))
valid.sort()
print (valid)
The first argument to filter should be a function that will get called for each item in the second argument, but you are calling the function first and passing in the return value. Change your filter call to something like this:
valid=list(filter(fun, email))
ETA
As pointed out in the comments below fun has some other problems. From one, since the function passed to filter gets called for each item, it shouldn't been attempting to loop over its input but just accept a single email address and not a list of addresses.
Also your initial test for characters in the address is broken. Something like this will work better:
def fun(email):
if ('#' in email) and ('.' in email):
user, url = i.split('#')
web, domain = url.split(".")
if user.replace('-','').replace('_','').isalnum() is False:
return False
elif web.isalnum() is False:
return False
elif len(domain)>3:
return False
else:
return True
But better yet, don't reinvent the wheel:
from validate_email import validate_email
valid = list(filter(validate_email, email))

Python: how to print detailed error messages about errors?

I'd like to get detailed info about each variable treatment error.
Example 1:
user = User()
print(user.name)
...
AttributeError: variable 'user' (class User) doesn't have field 'name', there are only: full_name, address, telephone, email
Example 2:
some_nums = [1, 2, 3]
print(some_nums[3])
...
IndexError: attempt to get #4 'some_nums' list's elem; it has only 3 elems
I known i can wrap each method in my program in individual try-expect block and print such message in the except clause in each of them.
But it there any way to collect local variables data, automatically pass it to top single try-except block and print such messages there?
I saw something like in py.test library. It overrides builtin python assert's and prints detailed message in stack trace when assert falls
https://pytest.org/latest/assert.html
You can override the magic method __getattribute__ if you want to
class HelpfulErrors(object):
def __getattribute__(self, name):
try:
return object.__getattribute__(self, name)
except:
raise AttributeError("class {} doesn't have field '{}', there are only: {}".format(self.__class__.__name__, name, ", ".join(self.__dict__.keys())))
class User(HelpfulErrors):
def __init__(self, age=21):
self.age = age
self.can_drink = self.age >= 21
u = User()
print(u.age)
print(u.can_drink)
print(u.name)
OUTPUT
21
True
Traceback (most recent call last):
File "mes.py", line 18, in <module>
print(u.name)
File "mes.py", line 6, in __getattribute__
raise AttributeError("class {} doesn't have field '{}', there are only: {}".format(self.__class__.__name__, name, ", ".join(self.__dict__.keys())))
AttributeError: class User doesn't have field 'name', there are only: can_drink, age
This really only tells you what is currently in the classes __dict__ though, so this could change over time unless all instance members that will ever be available are defined by the time __init__ is finished.

Python Class and Attribute Error

Please look at the code below and the Attribute error I get. Thanks for your help.
This is the error I get.
Traceback (most recent call last):
File "ClassError.py", line 45, in <module>
if __name__ == '__main__':Main()
File "ClassError.py", line 43, in Main
printTest(i)
File "ClassError.py", line 38, in printTest
print f.FirstName
AttributeError: 'str' object has no attribute 'FirstName'
CODE
class CompKeyData():
def __init__(self,
FirstName,\
MiddleName,\
LastName):
self.FirstName = FirstName
self.MiddleName = MiddleName
self.LastName = LastName
def __repr__(self):
return repr((self.FirstName,\
self.MiddleName,\
self.LastName))
def __iter__(self):
return iter((self.FirstName,\
self.MiddleName,\
self.LastName))
def ckDataClassList(dataList):
dataObjects = []
for FirstName,\
MiddleName,\
LastName in dataList:
dataObjects.append(CompKeyData(
FirstName,\
MiddleName,\
LastName))
return dataObjects
ckData = [['John', 'Ralph', 'DuMont'], ['Jack', 'Lowry', 'Matern']]
ckClassData = ckDataClassList(ckData)
def printTest(classData):
for f in classData:
print f.FirstName
return None
def Main():
for i in ckClassData:
printTest(i)
if __name__ == '__main__':Main()
When you do
for i in ckClassData:
Each i is a CompKeyData instance. You then do:
printTest(i)
Which calls:
for f in classData:
where classData is the i you passed in.
This iterates through the individual CompKeyData instance, which (due to your implementation of __iter__) assigns FirstName, MiddleName and LastName in turn to f- each of these is a string, and doesn't have FirstName.
Instead, printTest should be:
printTest(classData):
print classData.FirstName
You don't need to explicitly return None, this happens automatically if you don't explicitly return anything else.
Also, it is worth reading PEP-0008; following this will make your code more readable.
You need to change your printTest function to the following:
def printTest(classData):
print classData.FirstName
classData is not a list of CompKeyData instances, but rather a single CompKeyData instance.
PEP8 is also certainly worth a look for python style.

Unbound method TypeError

I've just been reading an article that talks about implementing a parser in python:
http://effbot.org/zone/simple-top-down-parsing.htm
The general idea behind the code is described in this paper: http://mauke.hopto.org/stuff/papers/p41-pratt.pdf
Being fairly new to writing parsers in python so I'm trying to write something similar as a learning exercise. However when I attempted to try to code up something similar to what was found in the article I am getting an TypeError: unbound method TypeError. This is the first time I've encountered such an error and I've spent all day trying to figure this out but I haven't solved the issue. Here is a minimal code example (in it's entirety) that has this problem:
import re
class Symbol_base(object):
""" A base class for all symbols"""
id = None # node/token type name
value = None #used by literals
first = second = third = None #used by tree nodes
def nud(self):
""" A default implementation for nud """
raise SyntaxError("Syntax error (%r)." % self.id)
def led(self,left):
""" A default implementation for led """
raise SyntaxError("Unknown operator (%r)." % self.id)
def __repr__(self):
if self.id == "(name)" or self.id == "(literal)":
return "(%s %s)" % (self.id[1:-1], self.value)
out = [self.id, self.first, self.second, self.third]
out = map(str, filter(None,out))
return "(" + " ".join(out) + ")"
symbol_table = {}
def symbol(id, bindingpower=0):
""" If a given symbol is found in the symbol_table return it.
If the symblo cannot be found theni create the appropriate class
and add that to the symbol_table."""
try:
s = symbol_table[id]
except KeyError:
class s(Symbol_base):
pass
s.__name__ = "symbol:" + id #for debugging purposes
s.id = id
s.lbp = bindingpower
symbol_table[id] = s
else:
s.lbp = max(bindingpower,s.lbp)
return s
def infix(id, bp):
""" Helper function for defining the symbols for infix operations """
def infix_led(self, left):
self.first = left
self.second = expression(bp)
return self
symbol(id, bp).led = infix_led
#define all the symbols
infix("+", 10)
symbol("(literal)").nud = lambda self: self #literal values must return the symbol itself
symbol("(end)")
token_pat = re.compile("\s*(?:(\d+)|(.))")
def tokenize(program):
for number, operator in token_pat.findall(program):
if number:
symbol = symbol_table["(literal)"]
s = symbol()
s.value = number
yield s
else:
symbol = symbol_table.get(operator)
if not symbol:
raise SyntaxError("Unknown operator")
yield symbol
symbol = symbol_table["(end)"]
yield symbol()
def expression(rbp = 0):
global token
t = token
token = next()
left = t.nud()
while rbp < token.lbp:
t = token
token = next()
left = t.led(left)
return left
def parse(program):
global token, next
next = tokenize(program).next
token = next()
return expression()
def __main__():
print parse("1 + 2")
if __name__ == "__main__":
__main__()
When I try to run this with pypy:
Traceback (most recent call last):
File "app_main.py", line 72, in run_toplevel
File "parser_code_issue.py", line 93, in <module>
__main__()
File "parser_code_issue.py", line 90, in __main__
print parse("1 + 2")
File "parser_code_issue.py", line 87, in parse
return expression()
File "parser_code_issue.py", line 81, in expression
left = t.led(left)
TypeError: unbound method infix_led() must be called with symbol:+ instance as first argument (got symbol:(literal) instance instead)
I'm guessing this happens because I don't create an instance for the infix operations but I'm not really wanting to create an instance at that point. Is there some way I can change those methods without creating instances?
Any help explaining why this is happening and what I can do to fix the code is greatly appreciated!
Also is this behaviour going to change in python 3?
You forgot to create an instance of the symbol in your tokenize() function; when not a number, yield symbol(), not symbol:
else:
symbol = symbol_table.get(operator)
if not symbol:
raise SyntaxError("Unknown operator")
yield symbol()
With that one change your code prints:
(+ (literal 1) (literal 2))
You haven't bound new function to the instance of your object.
import types
obj = symbol(id, bp)
obj.led = types.MethodType(infix_led, obj)
See accepted answer to another SO question

Query filtering on property with validator setted

I have model User and property username with validator which validates username for available chars, non-empty and existence in DB. So, I don't need any other checks when handling registration form for example - I just assign form's username value to model's property and catching validation error if entered username already exists...
But, it isn't work.
Because NDB validates property's comparison arguments too (see Property._comparison method in ndb/model.py) and it goes to endless reqursion in Query.filter(User.username == [somevalue]) and finally raises RuntimeError: maximum recursion depth exceeded. NDB trying to validate [somevalue] with validate_username and go to this query again and again...
It's possible to assign username to entity's ID and use User.get_by_id(), but it's needed username to be changeable, so I need to use Query.get().
So it is my User model:
class User(ndb.Model):
def validate_username(self, value):
value = str(value).strip()
# Other useful checks - length, available symbols, etc
if User.get_user(value):
raise ValueError('Username already exists')
return value
#classmethod
def get_user(cls, username):
username = str(username)
user_q = User.query()
user_q = user_q.filter(User.username == username) # Here is the problem
return user_q.get()
username = ndb.StringProperty(validator=validate_username)
For example:
# Trying to add user, get RuntimeError exception
u = User()
u.username = 'John'
What I'm doing wrong? What's the best way to solve such problem?
UPDATE to Tim Hoffman:
Thanks. Yes, I've missed prop argument, but method received prop in self and val in val arguments - thus I didn't mention this mistake. But, you've missed the key issue - you don't use query with filter in validator (User.get_user method). Try this, there is no sense function or method validator is:
def validate_username2(prop, value):
if User.get_user(value):
raise Exception('User exists!')
return value
class User(ndb.Model):
def validate_username(self, value):
if User.get_user(value):
raise Exception('User exists!')
return value
#classmethod
def get_user(self, username):
user_q = User.query()
user_q = user_q.filter(User.username == username)
return user_q.get()
# Try both please
username = ndb.StringProperty(validator=validate_username)
#username = ndb.StringProperty(validator=validate_username2)
I believe you problem is due to incorrectly defining you validator as a method and not accepting the correct arguments. See the quick example below, does work with filters.
The db, ndb, users, urlfetch, and memcache modules are imported.
dev~cash-drawer> def vla(prop,val):
... if val == "X":
... raise ValueError
... return val
...
dev~cash-drawer>
dev~cash-drawer>
dev~cash-drawer> class X(ndb.Model):
... name = ndb.StringProperty(validator=vla)
...
dev~cash-drawer> y = X()
dev~cash-drawer> y.name = "X"
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/home/timh/google_appengine/google/appengine/ext/ndb/model.py", line 1258, in __set__
self._set_value(entity, value)
File "/home/timh/google_appengine/google/appengine/ext/ndb/model.py", line 1004, in _set_value
value = self._do_validate(value)
File "/home/timh/google_appengine/google/appengine/ext/ndb/model.py", line 953, in _do_validate
newvalue = self._validator(self, value)
File "<console>", line 3, in vla
ValueError
dev~cash-drawer> y.name = "aaa"
dev~cash-drawer> y.put()
Key('X', 5060638606280884224)
dev~cash-drawer> z=X.query().filter(X.name == "aaa")
dev~cash-drawer> list(z)
[X(key=Key('X', 5060638606280884224), name=u'aaa')]
dev~cash-drawer> z=X.query().filter(X.name == "X")
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/home/timh/google_appengine/google/appengine/ext/ndb/model.py", line 859, in __eq__
return self._comparison('=', value)
File "/home/timh/google_appengine/google/appengine/ext/ndb/model.py", line 847, in _comparison
value = self._do_validate(value)
File "/home/timh/google_appengine/google/appengine/ext/ndb/model.py", line 953, in _do_validate
newvalue = self._validator(self, value)
File "<console>", line 3, in vla
ValueError
dev~cash-drawer>

Categories