1

我已经反映了现有 mysql 数据库中的大量表。我想表达的是,任何表中具有特定名称的任何列都默认为 datetime.now()。然而,天真地循环遍历表和列,只是在我发现有特定名称的那些上设置默认值是行不通的,当做 session.add(); session.flush() 我收到以下错误:

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

这似乎与对 _set_parent 的调用有关(以及 sqlalchemy.schemaself._init_items(*toinit)中第 721 行的 this。

有谁知道是否有一种方法可以做到这一点,而无需遍历我所有的反射表并在每个地方添加 Column(..) 行都做同样的事情或诉诸非常丑陋的黑客?

4

3 回答 3

6

另一种选择是在反映时覆盖需要默认值的列:

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

不幸的是,您目前无法反映数据类型并同时设置 SQLAlchemy 端默认值。有人可能会争辩说,数据类型是接口定义的一部分,因此冗余不会造成维护问题 - 如果列数据类型发生更改,您很可能也需要更改默认值函数。

于 2009-06-04T12:41:27.363 回答
5

好的,我已经解决了这个问题,这是一个相当可怕的黑客,因为我使用了一种内部方法。你需要做:

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

这会产生所需的行为。请注意,您还可以将 ColumnDefault 传递给 kwarg for_update=True,这将更改行为以更改 UPDATE 而不是插入。

我觉得脏:-(

于 2009-06-02T14:50:02.317 回答
3

五年后,您可以使用事件侦听器[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

于 2014-06-02T17:04:01.040 回答