Как я могу превратить литерал в выражение в SQLAlchemy для MYSQL?

Я использую 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 ('{}')?

Кажется, что любое значение по умолчанию работает с MariaDB - отличается ли поведение в MySQL?

snakecharmerb 08.05.2024 15:53

можешь попробовать sqlalchemy.literal_column("('{}')")

python_user 08.05.2024 16:20

@python_user Я попробовал, что получилось '(\'{}\')'

snakecharmerb 08.05.2024 16:43

это странно, я понимаю mycolumn JSON NOT NULL DEFAULT ('{}') @snakecharmerb

python_user 08.05.2024 17:05

Возможно, это водитель? Я использовал mariadb+pymysql

snakecharmerb 08.05.2024 17:09
mysql+pymysql должно быть одинаково? кстати, это все определение mapped_column(MutableDict.as_mutable(JSON), server_default=literal_column("('{}')"))
python_user 08.05.2024 17:10

Я ошибся, извините, я использовал только literal. literal_column производит DEFAULT '{}' для меня.

snakecharmerb 08.05.2024 17:12
sqlalchemy.literal_column("('{}')") у меня работает, производит DEFAULT ('{}'), спасибо за ответ.
mazalan01 08.05.2024 22:23

@python_user извините за путаницу — literal_column выдаёт нужный DDL, но по какой-то причине SHOW CREATE TABLE показывает DEFAULT '{}'.

snakecharmerb 09.05.2024 08:10

@snakecharmerb спасибо за разъяснения, да, я вижу то же самое в mariadb, в MySQL почему-то понимаю mycolumn json NOT NULL DEFAULT (_utf8mb4'{}')

python_user 09.05.2024 08:57
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
1
10
64
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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() будет отображаться как есть, без кавычек.

Другие вопросы по теме