【问题标题】:Default value ignored in non-nullable column在不可为空的列中忽略默认值
【发布时间】:2013-04-12 09:44:28
【问题描述】:

我正在尝试使用以下 SQL alchemy 脚本在表中创建一个新的布尔型、不可为空的列(默认值=True):

from sqlalchemy import MetaData, Table, Boolean, Column

def upgrade(migrate_engine):
    meta = MetaData(bind=migrate_engine)
    message_table = Table('message', meta, autoload=True)
    col = Column('include_signature', Boolean(), default=True, nullable=False)
    col.create(message_table)

这导致了一个相当令人费解的错误:

  File "src/adhocracy/migration/versions/061_optional_massmessage_signature.py", line 7, in upgrade
    col.create(message_table)
  File "eggs/sqlalchemy_migrate-0.7.2-py2.6.egg/migrate/changeset/schema.py", line 528, in create
    engine._run_visitor(visitorcallable, self, connection, **kwargs)
  File "eggs/SQLAlchemy-0.7.10-py2.6-linux-x86_64.egg/sqlalchemy/engine/base.py", line 2302, in _run_visitor
    conn._run_visitor(visitorcallable, element, **kwargs)
  File "eggs/SQLAlchemy-0.7.10-py2.6-linux-x86_64.egg/sqlalchemy/engine/base.py", line 1972, in _run_visitor
    **kwargs).traverse_single(element)
  File "eggs/sqlalchemy_migrate-0.7.2-py2.6.egg/migrate/changeset/ansisql.py", line 53, in traverse_single
    ret = super(AlterTableVisitor, self).traverse_single(elem)
  File "eggs/SQLAlchemy-0.7.10-py2.6-linux-x86_64.egg/sqlalchemy/sql/visitors.py", line 106, in traverse_single
    return meth(obj, **kw)
  File "eggs/sqlalchemy_migrate-0.7.2-py2.6.egg/migrate/changeset/databases/sqlite.py", line 75, in visit_column
    super(SQLiteColumnGenerator,self).visit_column(column)
  File "eggs/sqlalchemy_migrate-0.7.2-py2.6.egg/migrate/changeset/ansisql.py", line 101, in visit_column
    self.execute()
  File "eggs/sqlalchemy_migrate-0.7.2-py2.6.egg/migrate/changeset/ansisql.py", line 42, in execute
    return self.connection.execute(self.buffer.getvalue())
  File "eggs/SQLAlchemy-0.7.10-py2.6-linux-x86_64.egg/sqlalchemy/engine/base.py", line 1449, in execute
    params)
  File "eggs/SQLAlchemy-0.7.10-py2.6-linux-x86_64.egg/sqlalchemy/engine/base.py", line 1628, in _execute_text
    statement, parameters
  File "eggs/SQLAlchemy-0.7.10-py2.6-linux-x86_64.egg/sqlalchemy/engine/base.py", line 1698, in _execute_context
    context)
  File "eggs/SQLAlchemy-0.7.10-py2.6-linux-x86_64.egg/sqlalchemy/engine/base.py", line 1691, in _execute_context
    context)
  File "eggs/SQLAlchemy-0.7.10-py2.6-linux-x86_64.egg/sqlalchemy/engine/default.py", line 331, in do_execute
    cursor.execute(statement, parameters)
sqlalchemy.exc.OperationalError: (OperationalError) Cannot add a NOT NULL column
with default value NULL '\nALTER TABLE message ADD include_signature BOOLEAN NOT NULL' ()

据我了解,sqlalchemy 缺少默认值,但我确实包含了default=True!这里有什么问题?

【问题讨论】:

    标签: sqlite sqlalchemy sqlalchemy-migrate


    【解决方案1】:

    使用server_default="true",像这样:

    col = Column('include_signature', Boolean(), default=True,
                 server_default="true", nullable=False)
    

    其中default 用于类实例,server_default 用于数据库列定义。

    【讨论】:

    • 谢谢!我没有意识到default 只是 sqlalchemy 的纯 Python 创建(如果没有给出值,它就是 sqlalchemy inserts 的内容),并且与底层数据库无关。
    • 太奇怪了,不应该是False(大写F)来匹配python语法吗?
    • server_default 类似于 sql 表达式而不是 python 表达式 docs.sqlalchemy.org/en/rel_1_0/core/…
    • 小心这一点,因为当使用不支持 true 作为文字的 SQL 方言时,它会中断,例如 SQLite。更好的方法是使用sqlalchemy.sql.expression.literal(True),因为 SQLAlchemy 将在生成 DDL 时执行必要的转换,例如使用 SQLite 时将 True 映射到 1
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-05
    相关资源
    最近更新 更多