sqlalchemy join返回的结果比mysql查询少

时间:2018-06-13 13:31:10

标签: python mysql orm sqlalchemy

我有两个表之间有关系,第一个表是报警表,第二个表用于记录每个报警的变化。

class Alarm(Base):

    __tablename__ = 'alarms'

    alarm_id = Column(String(128), primary_key=True, nullable=False)
    start_timestamp = Column(DateTime, index=True, nullable=False)
    end_timestamp = Column(DateTime, index=True, nullable=False)
    alarm_name = Column(String(128), nullable=False)
    alarm_type = Column(String(128), nullable=False)
    resource_type = Column(String(128), nullable=False)
    resource_id = Column(String(128), nullable=False)
    resource_name = Column(String(128), nullable=False)
    severity = Column(String(128), nullable=False)
    payload = Column(JSONEncodedDict())


class Change(Base):

    __tablename__ = 'changes'

    id = Column(INTEGER, primary_key=True)
    alarm_id = Column(String(128), ForeignKey('alarms.alarm_id'), nullable=False)
    start_timestamp = Column(DateTime, index=True, nullable=False)
    end_timestamp = Column(DateTime, nullable=False)
    severity = Column(String(128),  index=True, nullable=False)
    payload = Column(JSONEncodedDict())
    alarm = relationship("Alarm", foreign_keys=[alarm_id])

我创建了100个警报的虚拟数据集,并在一个警报中进行了更改并将其插入表中:

报警:

+---------------------+------------+------------+---------------------+---------------------+------------+------------+---------------+-------------+---------------+----------+---------+
| created_at          | updated_at | alarm_id | start_timestamp     | end_timestamp       | alarm_name | alarm_type | resource_type | resource_id | resource_name | severity | payload |
+---------------------+------------+------------+---------------------+---------------------+------------+------------+---------------+-------------+---------------+----------+---------+
| 2018-06-13 09:21:59 | NULL       | 0          | 2018-06-13 09:21:59 | 2038-06-08 09:21:59 | test0      | test       | bla           | 0           | R0            | error    | NULL    |
| 2018-06-13 09:21:59 | NULL       | 1          | 2018-06-13 09:21:59 | 2038-06-08 09:21:59 | test1      | test       | bla           | 1           | R1            | error    | NULL    |
| 2018-06-13 09:21:59 | NULL       | 10         | 2018-06-13 09:21:59 | 2038-06-08 09:21:59 | test10     | test       | bla           | 10          | R10           | error    | NULL    |
| 2018-06-13 09:21:59 | NULL       | 11         | 2018-06-13 09:21:59 | 2038-06-08 09:21:59 | test11     | test       | bla           | 11          | R11           | error    | NULL    |
| 2018-06-13 09:21:59 | NULL       | 12         | 2018-06-13 09:21:59 | 2038-06-08 09:21:59 | test12     | test       | bla           | 12          | R12           | error    | NULL    |
| 2018-06-13 09:21:59 | NULL       | 13         | 2018-06-13 09:21:59 | 2038-06-08 09:21:59 | test13     | test       | bla           | 13          | R13           | error    | NULL    |
| 2018-06-13 09:21:59 | NULL       | 14         | 2018-06-13 09:21:59 | 2038-06-08 09:21:59 | test14     | test       | bla           | 14          | R14           | error    | NULL    |

的变化:

+---------------------+------------+-----+------------+---------------------+---------------------+----------+---------+
| created_at          | updated_at | id  | vitrage_id | start_timestamp     | end_timestamp       | severity | payload |
+---------------------+------------+-----+------------+---------------------+---------------------+----------+---------+
| 2018-06-13 09:21:59 | NULL       |   1 | 0          | 2018-06-13 09:21:59 | 2038-06-08 09:21:59 | error    | NULL    |
| 2018-06-13 09:21:59 | NULL       |   2 | 1          | 2018-06-13 09:21:59 | 2038-06-08 09:21:59 | error    | NULL    |
| 2018-06-13 09:23:07 | NULL       | 101 | 1          | 2018-06-13 09:23:07 | 2038-06-08 09:23:07 | WARNING  | NULL    |
| 2018-06-13 09:21:59 | NULL       |  11 | 10         | 2018-06-13 09:21:59 | 2038-06-08 09:21:59 | error    | NULL    |
| 2018-06-13 09:21:59 | NULL       |  12 | 11         | 2018-06-13 09:21:59 | 2038-06-08 09:21:59 | error    | NULL    |
| 2018-06-13 09:21:59 | NULL       |  13 | 12         | 2018-06-13 09:21:59 | 2038-06-08 09:21:59 | error    | NULL    |
| 2018-06-13 09:21:59 | NULL       |  14 | 13         | 2018-06-13 09:21:59 | 2038-06-08 09:21:59 | error    | NULL    |
| 2018-06-13 09:21:59 | NULL       |  15 | 14         | 2018-06-13 09:21:59 | 2038-06-08 09:21:59 | error    | NULL    |

我写了ORM查询,如下:

def my_query():

    query = session.query(models.Alarm).filter(
        or_(and_(func.date(models.Alarm.start_timestamp) >= start, func.date(models.Alarm.start_timestamp) <= end),
            and_(func.date(models.Alarm.end_timestamp) >= start, func.date(models.Alarm.end_timestamp) <= end))
        ).join(models.Change.alarm_id)
    return query.all()

这会返回100个结果,当我使用以下参数运行它时:

start = 2018-06-11 12:39:49
end = 2038-06-08 12:39:49

当我运行query.count()而不是query.all()(使用相同的参数)时,我得到了101,正如所料。

这是由sqlalchemy生成的查询:

SELECT alarms.created_at AS alarms_created_at, alarms.updated_at AS alarms_updated_at, alarms.alarm_id AS alarms_alarm_id, alarms.start_timestamp AS alarms_start_timestamp, alarms.end_timestamp AS alarms_end_timestamp, alarms.alarm_name AS alarms_alarm_name, alarms.alarm_type AS alarms_alarm_type, alarms.resource_type AS alarms_resource_type, alarms.resource_id AS alarms_resource_id, alarms.resource_name AS alarms_resource_name, alarms.severity AS alarms_severity, alarms.payload AS alarms_payload 
FROM changes INNER JOIN alarms ON alarms.alarm_id = changes.alarm_id 
WHERE date(alarms.start_timestamp) >= %(date_1)s AND date(alarms.start_timestamp) <= %(date_2)s OR date(alarms.end_timestamp) >= %(date_3)s AND date(alarms.end_timestamp) <= %(date_4)s

当我将date_1,date_2,date_3,date_4替换为:

start = 2018-06-11 12:39:49
end = 2038-06-08 12:39:49

直接在mysql中运行,得到101个结果。

我的ORM查询有什么问题?

0 个答案:

没有答案