Я хотел бы выполнить миграцию с помощью перегонного куба из модели 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)
Я хочу запустить сценарий перегонного куба, чтобы изменить столбец, но, поскольку некоторые из моих существующих 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)
Считается ли строка, представляющая пустой dict, не нулевой? Что нужно передать этому server_default
? Должен ли я разделить код на несколько шагов, чтобы заполнить значение по умолчанию, прежде чем установить поле, не допускающее значение NULL (не предпочтительный вариант, у меня есть куча столбцов, к которым я хочу применить это)?
Я использую postgres 10.5, я прочитал что postgres 11 лучше справится с такого рода операциями, стоит ли мне переходить на него сейчас?
Заранее спасибо за помощь/советы
NOT NULL DEFAULT something
в pg10 и старше. В pg11 вы по-прежнему не сможете изменить столбцы таким образом, поэтому нет смысла переключаться. - person Łukasz Kamiński   schedule 27.09.2018