代码之家  ›  专栏  ›  技术社区  ›  bear

Sqalchemy postgres:AttributeError:无法设置属性

  •  3
  • bear  · 技术社区  · 8 年前

    使用sqalchemy初始化postgres数据库时,我得到一个AttributeError:无法设置属性错误:

    Traceback (most recent call last):
      File "manage.py", line 567, in <module>
        manager.run()
      File "/usr/local/lib/python3.6/site-packages/flask_script/__init__.py", line 417, in run
        result = self.handle(argv[0], argv[1:])
      File "/usr/local/lib/python3.6/site-packages/flask_script/__init__.py", line 386, in handle
        res = handle(*args, **config)
      File "/usr/local/lib/python3.6/site-packages/flask_script/commands.py", line 216, in __call__
        return self.run(*args, **kwargs)
      File "manage.py", line 26, in initdb
        password="passwo",
      File "<string>", line 4, in __init__
      File "/usr/local/lib/python3.6/site-packages/sqlalchemy/orm/state.py", line 417, in _initialize_instance
        manager.dispatch.init_failure(self, args, kwargs)
      File "/usr/local/lib/python3.6/site-packages/sqlalchemy/util/langhelpers.py", line 66, in __exit__
        compat.reraise(exc_type, exc_value, exc_tb)
      File "/usr/local/lib/python3.6/site-packages/sqlalchemy/util/compat.py", line 187, in reraise
        raise value
      File "/usr/local/lib/python3.6/site-packages/sqlalchemy/orm/state.py", line 414, in _initialize_instance
        return manager.original_init(*mixed[1:], **kwargs)
      File "/usr/local/lib/python3.6/site-packages/sqlalchemy/ext/declarative/base.py", line 700, in _declarative_constructor
        setattr(self, k, kwargs[k])
      File "/usr/local/lib/python3.6/site-packages/sqlalchemy/ext/hybrid.py", line 873, in __set__
        raise AttributeError("can't set attribute") AttributeError: can't set attribute
    

    该表定义如下:

    class User(db.Model, UserMixin):
        """
        A user who has an account on the website.
        """
    
        __tablename__ = 'user'
    
        id = db.Column(db.Integer,
                       primary_key=True,
                       nullable=False,
                       unique=True,
                       autoincrement=True)
        first_name = db.Column(db.String)
        last_name = db.Column(db.String)
        phone = db.Column(db.String)
        email = db.Column(db.String, unique=True)
        photo = db.Column(db.String, default="No Picture")
        _password = db.Column(db.Binary(60))
    

    初始化如下:

    def initdb():
        ''' Create the SQL database. '''
        db.create_all()
        print(colored('The SQL database has been created', 'green'))
    
        user2 = models.User(
            first_name="Jane",
            last_name="Doe",
            phone="123",
            email="test@test.test",
            password="passwo",
        )
        db.session.add(user2)
    

    如何正确初始化数据库?

    更新1: 我将SQLAlchemy从1.2.5降级到1.1.15(遵循中的建议 https://github.com/puckel/docker-airflow/issues/160 错误消失。是否有办法避免1.2.5中的错误?

    2 回复  |  直到 8 年前
        1
  •  3
  •   mirth23    7 年前

    可能的问题是,您正在为密码和自定义setter使用混合属性,这在Flask示例中很常见,看起来像:

    Class User(db.Model)
    ...
        @hybrid_property
        def password(self):
            return self._password
    
        @password.setter
        def _set_password(self, plaintext):
            self._password = bcrypt.generate_password_hash(plaintext).decode('utf-8')
    

    为了与Python属性保持一致,SQLAlchemy决定不允许使用被称为函数的函数,而不是它们所影响的混合属性的名称。因此,现在需要:

        @hybrid_property
        def password(self):
            return self._password
    
        @password.setter
        def password(self, plaintext):
            self._password = bcrypt.generate_password_hash(plaintext).decode('utf-8')
    

    看见 https://docs.sqlalchemy.org/en/latest/orm/extensions/hybrid.html 了解更多详细信息。

        2
  •  1
  •   Metalstorm    8 年前

    在您的班级中,您有:

    _密码=db。列(分贝二进制(60))

    在对象初始化中,您有:

    密码=“passwo”

    他们应该匹配