python - Alembic 的 server_default 和 Postgres

标签 python postgresql sqlalchemy alembic

我想使用 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 会更好地处理这种操作,我现在应该切换到它吗?

在此先感谢您的帮助/建议

最佳答案

如果有人再来这里,我就用这个

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.execute("ALTER TABLE {table_name} ALTER COlUMN {column_name} set DEFAULT {new_default_value};")
    # ### end Alembic commands ###


def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.execute("ALTER TABLE {table_name} ALTER COlUMN {column_name} set DEFAULT {old_default_value};")
    # ### end Alembic commands ###

关于python - Alembic 的 server_default 和 Postgres,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52530690/

相关文章:

python - 重新索引具有重复索引值的数据框

python - Postgres : is set_config(). current_setting() 应用程序变量的私有(private)/稳健堆栈?

python - Scapy 奇怪的 Python 内存使用

sql - 匹配值列表中的字符串并创建新行

python - Flask sqlalchemy - 最小应用程序

python - 如何使用 alembic/SQLAlchemy 将表对象实例化为 bulk_insert 行

python - 鸡蛋碎片的 Pip 安装问题导致包的未知安装

python - 从 Google DataStore 打印多个二进制数据字段?

python - Pytest 找不到 Lambda 层中定义的函数

json - 如何更新存储在 PostgreSQL 文本字段中的 json 数据?