2009-06-02 3 views
1

Я отражаю нагрузку таблиц в выходящей mysql db. Я хочу выразить, что любые столбцы определенного имени в любой таблице по умолчанию равны datetime.now(). Однако наивно зацикливание по таблицам и столбцам и просто установка по умолчанию для тех, которые я нахожу, которые имеют определенное имя, не работают, когда вы делаете session.add(); session.flush() я получаю следующее сообщение об ошибке:.Переопределить значение по умолчанию в квадратных таблицах sqlalchemy

AttributeError: 'builtin_function_or_method' object has no attribute '__visit_name__' 

Это, казалось бы, связали в вызове _set_parent (и это self._init_items(*toinit) по линии 721 в sqlalchemy.schema

Кто-нибудь знает если есть способ сделать это без прохождения всех моих отраженных таблиц и добавления строк столбца (..), где все делает то же самое или прибегает к действительно уродливым взломам?

ответ

2

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

5

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

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

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

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

5

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

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

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

+0

Благодарности Муравьев, это определенно был бы мой Предпочтительнее подход на каждой из таблиц баз, однако я отражая сразу несколько таблиц, и я хочу, чтобы правило применялось ко всей таблице с этим конкретным именем столбца, поэтому я отмечаю свой ответ ниже как предпочтительный (если нечеткий) ответ. –

+0

См. Также [extend_existing = True] (http://docs.sqlalchemy.org/en/latest/core/metadata.html#sqlalchemy.schema.Table.params.extend_existing) – michaell