Переопределить значение по умолчанию в отраженных таблицах sqlalchemy - PullRequest
1 голос
/ 02 июня 2009

Я отражаю загрузку таблиц в выходящей базе данных 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 (..), где все делают одно и то же, или прибегая к действительно безобразным хакерам?

Ответы [ 3 ]

6 голосов
/ 04 июня 2009

Другой вариант - переопределить столбцы, для которых требуются значения по умолчанию, при отражении:

Table('some_table', metadata,
    Column('create_time', DateTime, default=datetime.now),
    autoload=True)

К сожалению, в настоящее время вы не можете отразить тип данных и установить сторону SQLAlchemy по умолчанию одновременно. Можно, однако, утверждать, что тип данных является частью определения интерфейса, и поэтому избыточность не создает проблем с обслуживанием - если тип данных столбцов изменяется, вам, скорее всего, потребуется также изменить функцию значения по умолчанию.

5 голосов
/ 02 июня 2009

ОК, я исправил это, и это умеренно ужасный хак, в котором я использовал внутренний метод. Вам нужно сделать:

from sqlalchemy.schema import ColumnDefault
#....
ColumnDefault(callable)._set_parent(column)

Это производит требуемое поведение. Обратите внимание, что вы также можете передать ColumnDefault kwarg for_update = True, и вы измените поведение, изменив UPDATE вместо вставки.

Я чувствую себя грязным: - (

3 голосов
/ 02 июня 2014

Пять лет спустя вы можете использовать прослушиватели событий [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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...