【问题标题】:SQLAlchemy boolean value is NoneSQLAlchemy 布尔值为 None
【发布时间】:2012-08-16 06:11:08
【问题描述】:

我的 Pyramid 应用中有这张桌子

class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    .....
    is_active = Column(Boolean, unique=False)
    def __init__(self, name, raw_password):
        is_active = True

当我进行测试时,它说is_active 是无。

def test_register_user(self):
    user = User('user1', '1234')
    self.sess.add(user)
    self.sess.flush()

    #print user
    #self.assertTrue(user.is_active, True)
    user_db_record = self.sess.query(User).filter_by(name=user.name).first()
    self.assertEqual(user_db_record.is_active, True)

从我的集成日志中,我看到当我们创建行时,is_active 设置为无。为什么?

【问题讨论】:

  • 如果有人来这里使用 SqlAlchemy 和 JetBrains 的 DataGrip 寻找答案,那么不要使用他们的可视化编辑器将值插入表中,它将忽略 default 关键字并设置列的值为<null>。而是使用控制台中的原始 SQL 语句,然后将正确设置值。

标签: python sqlalchemy pyramid


【解决方案1】:

您必须设置默认值,否则使用 None/NULL:

is_active = Column(Boolean, unique=False, default=True)

您想在__init__ 中执行此操作,但您使用了is_active = True(局部变量)而不是self.is_active = True

【讨论】:

  • 哦...self. 不见了。尴尬。谢谢!
  • 布尔值server_default 的值应该是多少?
  • @Hussain Postgres docs 列出了 True/False 值的有效文字列表,'t' / 'f' 也在其中。我选择了server_default='t',它对我有用。
  • 说真的,有 South/Django 迁移背景,有时我认为与 Alembic 相比,编写原始 SQL 迁移是一种更好的方法 - 至少它以可预测的方式工作......
  • @havelock SQLAlchemy ORM 的主要卖点之一是抽象实际的服务器/驱动程序实现(否则,除了迭代 Selectabletype(NamedTuple) 之外,何必做任何事情?)。因此在列 def 中设置 default 并在 __init__ 中分配默认值将在服务器上创建默认约束并在 ORM 对象实例化期间预先分配它。
【解决方案2】:

如果您使用的是 Flask-SQLAlchemy,则可以使用此命令创建服务器端默认值。

from sqlalchemy.sql import expression
active = db.Column(db.Boolean, server_default=expression.true(), nullable=False)

这将在数据库上创建一个默认值,以便任何人都可以对其进行写入,并且数据库将具有默认值。

【讨论】:

  • 那个 Flask 有什么关系?因为这似乎是常规的 SQLAlchemy 事情,我想你可能把 db.TYPE 的东西与 SQLAlchemy Columnserver_default arg 混淆了?
【解决方案3】:
is_active = Column(Boolean, server_default='t', default=True)

【讨论】:

  • 请在你的回答中添加一些解释!
  • @ρss Alembic 似乎不会单独从 default 的迁移代码中生成 SQL 级别的默认值子句,您必须明确提供 server_default。至于't'的值,请看my comment above
  • server_default="true" 也有效(注意它不是 Python 关键字 True 而是一个字符串 "true"
【解决方案4】:

如果有人正在寻找解决方案并使用 Flask,您会这样做。

请务必注意,服务器默认值应在迁移文件中使用,而不是在模型本身上。

一旦您使用 a 生成迁移

flask db migrate

您应该会在文件夹中看到新的迁移 (migrations/versions/XXXXXX.py)

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.add_column('users', sa.Column('confirmed', sa.Boolean(), nullable=True, server_default='f'))
    op.add_column('users', sa.Column('confirmed_on', sa.DateTime(), nullable=True))
    op.add_column('users', sa.Column('is_admin', sa.Boolean(), nullable=True, server_default='f'))

这是您要添加 server_default 的地方。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-29
    • 1970-01-01
    • 2016-09-16
    • 1970-01-01
    相关资源
    最近更新 更多