获取使用SQLAlchemy 0.7.8和Oracle XE生成的“错误”类型

时间:2012-08-21 17:25:51

标签: oracle oracle11g sqlalchemy

任何人都可以告诉我为什么下面的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

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:0)

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

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

虽然DateTime中的sqlalchemy只有在TIMEZONE设置为TRUE时才能获得带有TIMEZONE的TIMESTAMP。默认值为FALSE

  

class sqlalchemy.types.DateTime(timezone = False

     

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

     

参数:timezone - boolean。如果为True,并由后端支持,   将产生'TIMESTAMP WITH TIMEZONE'。对于没有的后端   支持时区感知时间戳,没有效果。

设置timezone=True应该有效,因为Oracle确实支持带时区的Timestamp,因此您可能需要设置它。