【问题标题】:Sqalchemy postgres: AttributeError: can't set attributeSqlalchemy postgres:AttributeError:无法设置属性
【发布时间】:2018-03-12 16:53:50
【问题描述】:

使用 sqalchemy 初始化我的 postgres 数据库时,我收到一个 AttributeError: can't set attribute error:

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 中的错误?

【问题讨论】:

  • 这个问题仍然存在,将列名更改为“_password”对我不起作用我不得不从 1.4.0 降级到 1.1.15,然后我能够使用 db 创建数据库。 create_all() @bear 感谢您的更新 1 干杯

标签: python python-3.x postgresql sqlalchemy flask-sqlalchemy


【解决方案1】:

可能的问题是您正在使用混合属性作为密码和自定义设置器,这在 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】:

    在你的课堂上你有:

    _password = db.Column(db.Binary(60))

    在你的对象初始化中你有:

    password="passwo"

    它们应该匹配

    【讨论】:

    • 为什么这在以前的 sqlalchemy 版本中有效?
    • @bear 以前的版本可能允许您设置任意/未定义的列,现在他们已经阻止了。
    猜你喜欢
    • 2021-06-14
    • 2021-06-14
    • 2021-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-06
    • 2016-03-17
    相关资源
    最近更新 更多