我想使用alembic从sqlalchemy模型迁移到另一个模型。 初始模型如下:
from sqlalchemy.dialects.postgresql import JSONB
from sqlalchemy_utils import UUIDType
class Foo(db.Model):
__tablename__ = 'foo'
id = db.Column(UUIDType(binary=True), primary_key=True)
foo_field = db.Column(JSONB)
并且我想使foo_field
不可为空:
class Foo(db.Model):
__tablename__ = 'foo'
id = db.Column(UUIDType(binary=True), primary_key=True)
foo_field = db.Column(JSONB, nullable=False)
我想运行一个Alembic脚本来更改列,但是由于我现有的某些foo_field
为空,因此我想在更改时使用server_default
来应用默认值(一个空字典)
op.alter_column('foo',
'foo_field',
existing_type=postgresql.JSONB(astext_type=sa.Text()),
nullable=False,
server_default="{}")
我尝试了其他选项传递给此server_default
,例如text("{}")
,lambda: {}
,{}
,text("SELECT '{}'")
。但这似乎被忽略了,运行升级时,我得到的只是一个IntegrityError
:
sqlalchemy.exc.IntegrityError: (psycopg2.IntegrityError) column "foo_field" contains null values [SQL: 'ALTER TABLE foo ALTER COLUMN foo_field SET NOT NULL'] (Background on this error at: http://sqlalche.me/e/gkpj)
表示空字典的字符串是否被视为非空?该server_default
应该传递什么?在将字段设置为不可为空之前,我是否应该分多步对代码进行填充以填充默认值(不是首选选项,我有一堆要对其应用的列)?
我使用的是postgres 10.5,我read认为postgres 11可以更好地处理这种操作,我现在应该切换到它吗?
提前感谢您的帮助/建议
答案 0 :(得分:1)
您可以使用Rewriter
,然后自己动手操作。
覆盖ops.AlterColumnOp
操作并返回两个操作,第一个是具有服务器默认值的更新列操作,第二个是原始的op
。