在 Oracle 和 MSSQL 兼容查询中插入日期和日期时间值

时间:2021-06-16 23:07:29

标签: python sqlalchemy

我正在尝试从在 Oracle 和 MSSQL 环境中执行的代码中包含多个日期和日期时间列的选择执行插入。切换环境时只是连接中的方言发生了变化。

我以为我可以传入 Python datedatetime 对象,但这不起作用。

以下代码适用于 MSSQL,但不适用于 Oracle。如何为 Oracle 和 MSSQL 生成与供应商无关的代码?

下面的代码等效于我正在运行的代码,为简洁起见,删除了几个不相关的字段。

timestamp = datetime.utcnow()
query = insert(MyModel).from_select(
    [
        MyModel.name,
        MyModel.date,
        MyModel.timestamp
    ],
    select(
        MyModel.name,
        cast(timestamp.today().strftime('%Y-%m-%d'), Date),
        cast(timestamp.strftime('%Y-%m-%d %H:%M:%S'), DateTime)
    ).where(
        MyModel.name == 'John'
    )
)

如果我直接提供一个 datetime 对象,例如下面显示的 MyModel.date 列的情况:

timestamp = datetime.utcnow()
query = insert(MyModel).from_select(
    [
        MyModel.name,
        MyModel.date,
        MyModel.timestamp
    ],
    select(
        MyModel.name,
        timestamp.today(),
        cast(timestamp.strftime('%Y-%m-%d %H:%M:%S'), DateTime)
    ).where(
        MyModel.name == 'John'
    )
)

我收到以下异常:

sqlalchemy.exc.ArgumentError: Column expression or FROM clause expected, got datetime.datetime(2021, 6, 17, 0, 54, 57, 568623).

我已阅读有关创建列表达式的文档,但我不清楚如何提供该值。表达式更合适是有道理的,但我无法想出一个既适用于 Oracle 又适用于 mssql 的表达式,这就是为什么我只是传递所需的值。

1 个答案:

答案 0 :(得分:0)

我想最明显的方法是使用与在普通 SQL 中相同的方式,使用绑定(内联或查询外部)。

以下适用于两种必需的方言。

timestamp = datetime.utcnow()
query = insert(MyModel).from_select(
    [
        MyModel.name,
        MyModel.date,
        MyModel.timestamp
    ],
    select(
        MyModel.name,
        bindparam('date', timestamp.date(), type_=Date),
        bindparam('timestamp', timestamp, type_=DateTime)
    ).where(
        MyModel.name == 'John'
    )
)
相关问题