【问题标题】:AttributeError: Neither 'InstrumentedAttribute' object nor 'Comparator' object associated with User.password_hash has an attribute 'count'AttributeError:与 User.password_hash 关联的“InstrumentedAttribute”对象和“Comparator”对象都没有属性“count”
【发布时间】:2021-01-02 08:07:01
【问题描述】:

我在 models.py 文件中创建了一个用户表,其中包含

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

然后我使用我在 functions.py 文件中编写的 check_password 函数:

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

我还在数据库中添加了一些用户:

数据库

+--------+-------------+----------+--------+------+-----------+--------------+------------------------------------------------------------------------------------------------+
| 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 |
+--------+-------------+----------+--------+------+-----------+--------------+------------------------------------------------------------------------------------------------+

现在,当我尝试使用以下方法测试检查密码功能时:

print(password_checking("testing123", "ashish01"))

它给了我以下错误:

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'  

我也曾尝试在 function.py 文件中定义的 add_user 函数中使用该函数,以检查重新输入的密码是否运行良好,但我不明白为什么这种方式不起作用并给了我一个错误。

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

注意:我正在使用 werkzeug.security 来创建密码哈希。

【问题讨论】:

  • This GitHub issue 是我通过在线查找得到的最佳匹配。我自己不能轻易测试它,但您的password_hash 可能实际上不是Column 对象,不知何故。但是,您的代码对我来说似乎很好,除了 password_hashUser 模型中的奇怪重新定义(它首先无缘无故地设置为 None
  • 为什么check_password 是一个类方法?您希望它是一个实例方法,因此它检查用户的 password 属性的值,而不是类的值,它是一个列。
  • @snakecharmerb 我最初是这样做的,但那会产生 TypeError。
  • @OctaveL 我尝试使用session.execute(select([models.User.password_hash])) 来检查password_hash 是否是一个列对象,并且运行良好。在对象上运行一个循环给了我所有的哈希键行。

标签: python sqlalchemy


【解决方案1】:

通过使用存储的哈希键查询用户名列表来解决问题。然后我将输入的用户名与列表中显示的用户名进行比较,并提取了我接下来在 password_checking 函数中使用的相关哈希键。

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

【讨论】:

    猜你喜欢
    • 2021-08-31
    • 1970-01-01
    • 2017-01-04
    • 2021-02-12
    • 1970-01-01
    • 2015-05-29
    • 2021-04-13
    • 2016-02-22
    • 1970-01-01
    相关资源
    最近更新 更多