代码之家  ›  专栏  ›  技术社区  ›  soniccool

SQLAlchemy返回奇怪的数据

  •  0
  • soniccool  · 技术社区  · 6 年前

    我正试图从表中导出日期。我只想把原始创建的对象拉出来。

    我正在运行下面的查询:

    return model.Session.query(cls).filter(cls.issue_id == issue_id).order_by(desc("created")).first()
    

    但它也会返回整个记录,我不知道如何导出创建的记录。

    <IssueComment id=32 comment=ay user_id=578042a3-d879-4b32-96a9-10f9aabe152c issue_id=19 created=2018-07-17 20:17:09.653809 visibility=visible abuse_status=0>
    

    如果我尝试调用在cls.created as so中创建的

    return model.Session.query(cls.created).filter(cls.issue_id == issue_id).order_by(desc("created")).first()
    

    它还导出了一个奇怪的日期时间版本。我只想要原始版本

    (datetime.datetime(2018, 7, 17, 20, 17, 9, 653809),)
    

    如何将已创建输出的值导出为原始字符串?

    2 回复  |  直到 6 年前
        1
  •  3
  •   snakecharmerb    6 年前

    针对属性(而不是整个模型)的SQLAlchemy查询返回 KeyedTuples 表现得像 namedtuple . 和普通的python元组一样, tuple 有一个元素是由一个尾随的逗号构成的。这就是为什么你的结果 (datetime.datetime(2018, 7, 17, 20, 17, 9, 653809),) 显示日期时间对象,后跟逗号。

    >>> row = session.query(User.creation_timestamp).first()
    >>> row
    (datetime.datetime(2018, 4, 22, 9, 20, 56),)  # <- trailing comma because it's a tuple
    

    可以通过索引访问值

    >>> row[0]
    datetime.datetime(2018, 4, 22, 9, 20, 56)
    

    或者按名字

    >>> row.creation_timestamp
    datetime.datetime(2018, 4, 22, 9, 20, 56)
    

    这些值是具有所有常用方法的python对象

    >>> row.creation_timestamp.isoformat()
    '2018-04-22T09:20:56'
    >>> str(row.creation_timestamp)
    '2018-04-22 09:20:56'
    

    有点困惑的是 tutorial 说的是 .first()

    应用一个限制并以标量形式返回第一个结果

    示例显示了一个返回的对象,如下所示:

    >>> q = session.query(User).first()
    >>> q
    <User object at 0x7f97d8c6b590>
    

    而首先调用query by属性会返回一个用元组包装的值。如果您认为元组是结果集中的一行,这是有意义的。如果你打电话来 .all() 在您的查询中,您将得到一个元组(行)列表。如果你打电话来 .limit(1).all() 在您的查询中,您将得到一个包含单个元组的列表。所以当你打电话的时候 。第一个() 你得到的第一个结果是 .限制(1).all() ,这是一个元组。

    >>> row = session.query(User.creation_timestamp).all()
    >>> row
    [(datetime.datetime(2018, 4, 22, 9, 20, 56),), (datetime.datetime(2018, 4, 22, 9, 20, 56),), ...]
    
    >>> row = session.query(User.creation_timestamp).limit(1).all()
    >>> row
    [(datetime.datetime(2018, 4, 22, 9, 20, 56),)]
    
    >>> row = session.query(User.creation_timestamp).first()
    >>> row
    (datetime.datetime(2018, 4, 22, 9, 20, 56),)
    
        2
  •  3
  •   abarnert    6 年前

    如果列是datetime列,则原始值不是字符串,而是datetime。

    在大多数数据库引擎中,在封面下, 实际的 在数据库中为datetime列存储的原始值是某种类型的数字。例如,iirc,在Microsoft SQL Server中,它是自1901年以来的64位十进制整数。但你不想要那个号码。你会怎么处理它?

    如果您想要某个特定格式的字符串,您当然可以要求数据库将其格式化为它接受的任何字符串格式,但是为什么呢?

    您的引擎和/或sqlAlchemy已将datetime值表示为python datetime 对象。这比一个字符串更小,更快地从数据库中传递数据线,更灵活(例如,您可以使用它们进行比较和算术)。

    你可以把它格式化成你想要的任何字符串格式。例如:

    >>> d = datetime.datetime(2018, 7, 17, 20, 17, 9, 653809)
    >>> str(d)
    '2018-07-17 20:17:09.653809'
    >>> d.isoformat()
    '2018-07-17T20:17:09.653809'
    >>> d.strftime('%Y%m%d%H%M%S')
    '20180717201709'
    >>> d.strftime('%m/%d/%Y %I:%M %p%S')
    '07/17/18 08:18 PM'
    

    等等。