基本上我有两个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包的列表:
请注意,我没有使用Flask-SQLAlchemy,虽然db.session
包含范围的会话对象,但我已经实现了自己的first_or_404
和get_or_404
方法。
使用以下配置创建引擎:
engine = create_engine(
'mysql://{username}:{password}@{host}/{database}?charset=utf8'.format(
**self.config),
pool_size=50,
pool_recycle=3600,
)
创建规则的第一个请求:
[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',)