Я использую sqlalchemy для создания таблицы в MySQL. Я хотел бы иметь столбец JSON со значением по умолчанию, но mysql не позволяет использовать литералы в качестве значения по умолчанию, а только выражения.
Если я создам столбец следующим образом:
mycolumn = sqlalchemy.Column(
MutableDict.as_mutable(mysql.JSON),
server_default='{}'
)
Строка создания столбца в SQL-запросе будет выглядеть так:
mycolumn JSON DEFAULT '{}'
Но это не работает, мне нужно это:
mycolumn JSON DEFAULT ('{}')
Я также попробовал использовать json_object()
:
mycolumn = sqlalchemy.Column(
MutableDict.as_mutable(mysql.JSON),
server_default=func.json_object('{}', type_=JSON)
)
но это создает:
mycolumn JSON DEFAULT json_object()
и снова это не работает.
Как я могу поместить значение по умолчанию в выражение, например mycolumn JSON DEFAULT ('{}')
?
можешь попробовать sqlalchemy.literal_column("('{}')")
@python_user Я попробовал, что получилось '(\'{}\')'
это странно, я понимаю mycolumn JSON NOT NULL DEFAULT ('{}')
@snakecharmerb
Возможно, это водитель? Я использовал mariadb+pymysql
mysql+pymysql
должно быть одинаково? кстати, это все определение mapped_column(MutableDict.as_mutable(JSON), server_default=literal_column("('{}')"))
Я ошибся, извините, я использовал только literal
. literal_column
производит DEFAULT '{}'
для меня.
sqlalchemy.literal_column("('{}')")
у меня работает, производит DEFAULT ('{}')
, спасибо за ответ.
@python_user извините за путаницу — literal_column
выдаёт нужный DDL, но по какой-то причине SHOW CREATE TABLE
показывает DEFAULT '{}'
.
@snakecharmerb спасибо за разъяснения, да, я вижу то же самое в mariadb, в MySQL почему-то понимаю mycolumn json NOT NULL DEFAULT (_utf8mb4'{}')
https://dev.mysql.com/doc/refman/8.0/en/data-type-defaults.html говорит:
Типам данных BLOB, TEXT, GEOMETRY и JSON можно присвоить значение по умолчанию, только если значение записано как выражение, даже если значение выражения является литералом.
Это означает, что вы не можете использовать пустой литерал (без круглых скобок) в качестве значения по умолчанию для столбца JSON. Вы должны сделать это выражением, т. е. поместить его в круглые скобки, поскольку вы нашли произведения. Выражение в круглых скобках может быть простым литералом.
Я заставил это работать для модели в SQLAlchemy следующим образом:
from sqlalchemy import Table, Column, Integer, String, JSON, text
user_table = Table(
"user_account",
meta,
Column("id", Integer, primary_key=True),
Column("properties", JSON, server_default=text("('{}')"))
)
https://docs.sqlalchemy.org/en/20/core/metadata.html#sqlalchemy.schema.Column.params.server_default говорит:
Выражение text() будет отображаться как есть, без кавычек.
Кажется, что любое значение по умолчанию работает с MariaDB - отличается ли поведение в MySQL?