Переопределить значение по умолчанию в таблицах, отражаемых sqlalchemy
-
06-09-2019 - |
Вопрос
Я отражаю множество таблиц в существующей базе данных MySQL.Я хочу выразить, что любые столбцы с определенным именем в любой таблице по умолчанию имеют значение datetime.now().Однако наивный цикл по таблицам и столбцам и просто установка по умолчанию для тех, которые, как я обнаружил, имеют определенное имя, не работает. При выполнении session.add();session.flush() я получаю следующую ошибку:
AttributeError: 'builtin_function_or_method' object has no attribute '__visit_name__'
Казалось бы, это связано с вызовом _set_parent (и this self._init_items(*toinit)
в строке 721 в sqlalchemy.schema.
Кто-нибудь знает, есть ли способ сделать это, не просматривая все мои отраженные таблицы и не добавляя строки Column(..) везде, где все делают одно и то же, или не прибегая к действительно уродливым хакам?
Решение
Пять лет спустя вы можете использовать прослушиватели событий[1].Вы можете зарегистрировать прослушиватель с функцией для запуска:
def do_this_on_column_reflect(inspector, table, column_info):
column_name = column_info.get("name")
if column_name == "create_datetime":
column_info["default"] = datetime.now()
event.listen(Table, "column_reflect", do_this_on_column_reflect)
[1] http://docs.sqlalchemy.org/en/latest/core/events.html#sqlalchemy.events.DDLEvents.column_reflect [2] http://docs.sqlalchemy.org/en/latest/core/event.html#sqlalchemy.event.listen
Другие советы
Другой вариант — переопределить столбцы, для которых требуются значения по умолчанию, при отображении:
Table('some_table', metadata,
Column('create_time', DateTime, default=datetime.now),
autoload=True)
К сожалению, в настоящее время вы не можете одновременно отразить тип данных и установить значение по умолчанию для стороны SQLAlchemy.Однако можно возразить, что тип данных является частью определения интерфейса, и поэтому избыточность не создает проблем с обслуживанием - если тип данных столбцов изменится, вам, скорее всего, придется изменить и функцию значения по умолчанию.
Хорошо, я это исправил, и это довольно ужасный хак, поскольку я использовал внутренний метод.Вам нужно сделать:
from sqlalchemy.schema import ColumnDefault
#....
ColumnDefault(callable)._set_parent(column)
Это приводит к требуемому поведению.Обратите внимание, что вы также можете передать ColumnDefault параметр kwarg for_update=True, и это изменит поведение так, чтобы оно менялось при UPDATE, а не при вставке.
Я чувствую себя грязным :-(