AttributeError: Neither 'InstrumentedAttribute' object nor 'Comparator' object associated with User.password_hash has attribute 'count'
I have created a user table in the models.py file with the following content
models.py
class User(Base):
__tablename__ = "users"
userid = Column(Integer, primary_key=True)
username = Column(String(15), unique=True)
usertype = Column(Boolean)
gender = Column(String(1))
age = Column(Integer)
phone = Column(VARCHAR(15))
password_hash = Column(VARCHAR(128))
@classmethod
def create_password(cls, password):
cls.password_hash = generate_password_hash(password)
return cls.password_hash
@classmethod
def check_password(cls, password):
return check_password_hash(cls.password_hash, password)
def __repr__(self):
return str(self.userid) + ":" + self.username
Then, I use the check_password function written in the functions.py file:
functions.py
def search_user(username):
return session.query(models.User).filter_by(username=username).all()
def password_checking(password, username):
usr = search_user(username)[0]
while True:
if usr.check_password(password) == False:
print("Passwords do not match.")
else:
break
Also, I added some users to the database:
D b
+--------+-------------+----------+--------+------+-----------+--------------+------------------------------------------------------------------------------------------------+
| userid | username | usertype | gender | age | phone | ticket_price | password_hash |
+--------+-------------+----------+--------+------+-----------+--------------+------------------------------------------------------------------------------------------------+
| 1 | ashishadmin | 1 | M | 24 | 750792699 | NULL | pbkdf2:sha256:150000$scvDUqJm$8dd6cf55b182391e2558134383d6e91befec40a9e4176a860f3e2158ebaae161 |
| 2 | ashish01 | 0 | M | 24 | 123456789 | NULL | pbkdf2:sha256:150000$ZTSGjGMh$21bb1cab7ea515865645031c993bce532d787f9b2c402246d0387f921ccf0ba8 |
| 3 | ashish02 | 0 | M | 24 | 963852741 | NULL | pbkdf2:sha256:150000$ZDajskIw$f27e76c5d1bcfb2019ffe01d74ddf2381fa61df72cdf830ca689a2aa057ff60c |
+--------+-------------+----------+--------+------+-----------+--------------+------------------------------------------------------------------------------------------------+
Now when I try to check the "check password" function using:
print(password_checking("testing123", "ashish01"))
It gives me the following error:
Traceback (most recent call last):
File "c:\myenv\ticket_booking\lib\site-packages\sqlalchemy\sql\elements.py", line 747, in __getattr__
return getattr(self.comparator, key)
AttributeError: 'Comparator' object has no attribute 'count'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "c:\myenv\ticket_booking\functions.py", line 95, in <module>
print(password_checking("testing123", "ashish01"))
File "c:\myenv\ticket_booking\functions.py", line 83, in password_checking
if usr.check_password(password) == False:
File "c:\myenv\ticket_booking\models.py", line 47, in check_password
return check_password_hash(cls.password_hash, password)
File "c:\myenv\ticket_booking\lib\site-packages\werkzeug\security.py", line 218, in check_password_hash
if pwhash.count("$") < 2:
File "c:\myenv\ticket_booking\lib\site-packages\sqlalchemy\orm\attributes.py", line 238, in __getattr__
util.raise_(
File "c:\myenv\ticket_booking\lib\site-packages\sqlalchemy\util\compat.py", line 182, in raise_
raise exception
AttributeError: Neither 'InstrumentedAttribute' object nor 'Comparator' object associated with User.password_hash has an attribute 'count'
I've also tried using the function in the add_user function defined in the function.py file in order to check that the re-entered password is working fine, but I don't understand why this doesn't work and gives me an error.
functions.py
password = getpass("Enter password: ")
pass_len = len(password)
while pass_len < 8:
print("Password length should be greater or equal to 8, please enter again.")
password = getpass("Enter password: ")
pass_len = len(password)
password_hash = models.User.create_password(password)
while True:
re_password = getpass("Re-enter password: ")
if models.User.check_password(re_password) == False:
print("Passwords do not match.")
else:
break
Note : I am using werkzeug.security to create password hashes.
This is solved by querying the list of usernames using the stored hash key. I then compared the entered username with the username shown in the list and extracted the relevant hash key, which I then used in the password_checking function.
models.py *
@classmethod
def check_password_after_signup(cls, password, password_hash):
return check_password_hash(password_hash, password)
@classmethod
def check_password_before_signup(cls, password):
return check_password_hash(cls.password_hash, password)
functions.py
def password_checking(username, password):
while True:
usr = search_user(username)[0]
status = session.execute(
select([models.User.username, models.User.password_hash])
)
for row in status:
if row[0] == username:
result = models.User.check_password_after_signup(password, row[1])
if result == False:
print("Passwords do not match.")
password = getpass("Re-enter password: ")
else:
break