即使实体存在,SQLAlchemy ORM get()也返回None

时间:2016-04-18 15:24:42

标签: python mysql orm sqlalchemy flask-restful

基本上我有两个API端点,一个用于创建规则,另一个用于将查询分配给这些规则。将查询分配给规则的过程通常紧跟在创建规则之后。例如,API调用如下所示:

POST /api/rules/
PATCH /api/rules/<id>/queries/

第一个端点创建一个新的规则并将其存储在数据库中。该方法如下所示(暂时忽略print语句):

# POST /api/rules/
def post(self, data, id):
    rule = Rule(**data)

    db.session.add(rule)
    db.session.commit()

    print 'Rule: {}'.format(
        db.engine.execute(
            'select * from rule where id = ?', rule.id)
        ).first())

    return rule, 201, location('rule', id=rule.id)

使用创建的规则的ID 调用第二个端点,但是,出于某种原因,API调用有时但不总是以404 Not Found结尾:< / p>

# PATCH /api/rules/<id>/queries/
def patch(self, data, id):
    print 'Got rule: {}'.format(
        db.engine.execute(
            'select * from rule where id = ?', id).first())
    print 'Does SQLAlchemy see this? {}'.format(
        db.session.query(Rule).get(id) is not None)

    rule = db.session.query(Rule).get_or_404(id)
    # ... the rest ...

我创建了一个简单的for循环,它试图创建10个规则并为它们分配10个查询。有时,第二个API调用(分配查询)会返回404状态。这个问题似乎只发生在生产中(可能是由于更高的负载)。当time.sleep(1)置于第一次和第二次API调用之间时,问题也会消失。

这似乎是SQLAlchemy的ORM中的一个问题,它有时没有最新的数据库状态(?),请参阅print语句的以下输出:

[1/POST] : Rule: (54374L, u'WBB multiplication rule')
[1/PATCH]: Got rule: (54374L, u'WBB multiplication rule')
[1/PATCH]: Does SQLAlchemy see this? True
[2/POST] : Rule: (54375L, u'WBB multiplication rule')
[2/PATCH]: Got rule: (54375L, u'WBB multiplication rule')
[2/PATCH]: Does SQLAlchemy see this? False
[3/POST] : Rule: (54376L, u'WBB multiplication rule')
[3/PATCH]: Got rule: (54376L, u'WBB multiplication rule')
[3/PATCH]: Does SQLAlchemy see this? True

其他信息

服务器在带有Maria DB 10.0.21的CentOS 7上运行。以下是一些相关Python包的列表:

  • 的SQLAlchemy == 1.0.6
  • 的MySQL-蟒== 1.2.5
  • 烧瓶== 0.10.1
  • 合剂的RESTful == 0.3.5

请注意,我没有使用Flask-SQLAlchemy,虽然db.session包含范围的会话对象,但我已经实现了自己的first_or_404get_or_404方法。

使用以下配置创建引擎:

engine = create_engine(
    'mysql://{username}:{password}@{host}/{database}?charset=utf8'.format(
        **self.config),
    pool_size=50,
    pool_recycle=3600,
)

使用echo ='debug'

创建规则的第一个请求:

[2016-04-18 20:51:25,665: INFO/green1c0ea50 > green4196370] INSERT INTO rule (name, project_id, project_element_id, type, priority, applies, deletable) VALUES (%s, %s, %s, %s, %s, %s, %s)
[2016-04-18 20:51:25,667: INFO/green1c0ea50 > green4196370] (u'WBB multiplication rule', 7013L, u'50745006', u'calc', 255, 1, 1)
[2016-04-18 20:51:25,669: INFO/green1c0ea50 > green4196370] INSERT INTO rule_calc (id, expression) VALUES (%s, %s)
[2016-04-18 20:51:25,670: INFO/green1c0ea50 > green4196370] (54625L, u'%MAX_CPC_SEARCH%*2')
[2016-04-18 20:51:25,673: INFO/green1c0ea50 > green4196370] COMMIT
[2016-04-18 20:51:25,678: INFO/green1c0ea50 > green4196370] BEGIN (implicit)
[2016-04-18 20:51:25,680: INFO/green1c0ea50 > green4196370] SELECT rule.id AS rule_id, rule.name AS rule_name, rule.project_id AS rule_project_id, rule.project_element_id AS rule_project_element_id, rule.type AS rule_type, rule.priority AS rule_priority, rule.applies AS rule_applies, rule.deletable AS rule_deletable 
FROM rule 
WHERE rule.id = %s
[2016-04-18 20:51:25,681: INFO/green1c0ea50 > green4196370] (54625L,)
[2016-04-18 20:51:25,682: INFO/MainProcess]

尝试使用404 失败时尝试获取规则的第二个请求:

[2016-04-18 20:51:25,832: INFO/green1c0fa50 > green31f1e10] SELECT rule.id AS rule_id, rule.name AS rule_name, rule.project_id AS rule_project_id, rule.project_element_id AS rule_project_element_id, rule.type AS rule_type, rule.priority AS rule_priority, rule.applies AS rule_applies, rule.deletable AS rule_deletable 
FROM rule 
WHERE rule.id = %s
[2016-04-18 20:51:25,832: INFO/green1c0fa50 > green31f1e10] (u'54625',)

0 个答案:

没有答案