我正在尝试从在 Oracle 和 MSSQL 环境中执行的代码中包含多个日期和日期时间列的选择执行插入。切换环境时只是连接中的方言发生了变化。
我以为我可以传入 Python date
和 datetime
对象,但这不起作用。
以下代码适用于 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 的表达式,这就是为什么我只是传递所需的值。
答案 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'
)
)