【问题标题】:Getting the "wrong" type generated with SQLAlchemy 0.7.8 and Oracle XE使用 SQLAlchemy 0.7.8 和 Oracle XE 生成“错误”类型
【发布时间】:2012-08-17 02:24:15
【问题描述】:

谁能告诉我为什么下面的 DateTime 类型会创建一个“DATE”对象而不是 DateTime(或更恰当地说,是一个 TIMESTAMP 类型),因为我必须强制如下行中的类型:

#!/bin/python

import sqlalchemy

from sqlalchemy import Column, Integer, String, DateTime, Index, MetaData
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship
from sqlalchemy.orm import sessionmaker
from sqlalchemy.dialects import oracle

Base = declarative_base()

import logging

logging.basicConfig()
logging.getLogger('sqlalchemy.engine').setLevel(logging.INFO)

class TypeTest(Base):
    __tablename__ = "TYPETESTZ"
    thisisinteger = Column(Integer, primary_key = True)
    thisisnotadatetime = Column(DateTime)
    thisisdatetime = Column(oracle.TIMESTAMP)    

if __name__ == "__main__":
    engine = sqlalchemy.create_engine('oracle://richard:password@xe')
    metadata = Base.metadata
    metadata.create_all(engine)

日志输出:

INFO:sqlalchemy.engine.base.Engine:SELECT USER FROM DUAL
INFO:sqlalchemy.engine.base.Engine:{}
INFO:sqlalchemy.engine.base.Engine:SELECT table_name FROM all_tables WHERE table_name = :name AND owner = :schema_name
INFO:sqlalchemy.engine.base.Engine:{'name': u'TYPETESTZ', 'schema_name': u'RICHARD'}
INFO:sqlalchemy.engine.base.Engine:
CREATE TABLE "TYPETESTZ" (
    thisisinteger INTEGER NOT NULL, 
    thisisnotadatetime DATE, 
    thisisdatetime TIMESTAMP, 
    PRIMARY KEY (thisisinteger)
)


INFO:sqlalchemy.engine.base.Engine:{}
INFO:sqlalchemy.engine.base.Engine:COMMIT

【问题讨论】:

    标签: oracle oracle11g sqlalchemy


    【解决方案1】:

    Oracle 没有DateTime 数据类型。在 Oracle 中,Date 包含日期(即 2012 年 8 月 21 日)和时间(即下午 1:30),粒度为 1 秒。 Timestamp,没有额外的限定符,仅允许您将粒度增加到纳秒(10^-9 秒)。 SQLAlchemy 将DateTime 转换为Oracle Date 似乎是合理的,除非有一些要求DateTime 支持小数秒(在这种情况下您需要Timestamp)或时区(在这种情况下您需要Timestamp with [local] time zone)。

    【讨论】:

    • 我同意你的说法,但我不确定结论......如果我想存储粒度为 0.01(无论单位)的东西,我希望默认值会是把它放在一个可以存储至少 0.01,而不是四舍五入到 100 的数据类型中。有趣的是,当我手动创建表时,SQLAlchemy 使用时间戳代替 DateTime 对象没有问题,但是当我当我遇到这个问题时,决定通过 SQLAlchemy 删除/重新创建。如何强制 SQLA 为所有事件映射 DateTime -> Timestamp?
    【解决方案2】:

    要创建TIMESTAMP 对象,您可能需要使用Time 之类的

    from sqlalchemy import Column, Integer, String, Time, Index, MetaData
    

    尽管,只有当 TIMEZONE 设置为 TRUE 时,sqlalchemy 中的 DateTime 才会获得带有 TIMEZONE 的 TIMESTAMP。默认为FALSE。

    类 sqlalchemy.types.DateTime(timezone=False)

    init(timezone=False) 构造一个新的 DateTime。

    参数:时区——布尔值。如果为真,并且受后端支持, 将产生“TIMESTAMP WITH TIMEZONE”。对于不支持的后端 支持时区感知时间戳,无效。

    设置 timezone=True 应该可以工作,因为 Oracle 确实支持带时区的时间戳,所以您可能需要设置它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-03-10
      • 2019-01-24
      • 2020-09-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多