有没有人知道在单元测试期间设置(模拟)FLask(Werkzeug)提供的请求对象的User-Agent的方法?
就目前而言,当我尝试获取诸如request.headers ['User-Agent']之类的细节时,会引发KeyError,因为Flask test_client()没有设置它们.(参见下面的部分堆栈跟踪)
在单元测试期间尝试从Flask项目中的请求对象获取User-Agent时,会引发KeyError.
File "/Users/me/app/rest/app.py", line 515, in login
if request.headers['User-Agent']:
File "/Users/me/.virtualenvs/app/lib/python2.7/site-packages/werkzeug/datastructures.py", line 1229, in __getitem__
return self.environ['HTTP_' + key]
KeyError: 'HTTP_USER_AGENT'
Run Code Online (Sandbox Code Playgroud)
- 更新 -
除了以下(接受)解决方案之外,environ_base提示引导我使用其他SO解决方案.此解决方案的前提是为Flask应用程序创建一个包装类,并覆盖调用方法以自动设置环境变量.这样,就为所有调用设置了变量.所以,我最终实现的解决方案是创建这个代理类:
class FlaskTestClientProxy(object):
def __init__(self, app):
self.app = app
def __call__(self, environ, start_response):
environ['REMOTE_ADDR'] = environ.get('REMOTE_ADDR', '127.0.0.1')
environ['HTTP_USER_AGENT'] = environ.get('HTTP_USER_AGENT', 'Chrome')
return self.app(environ, start_response)
Run Code Online (Sandbox Code Playgroud)
然后用该代理包装WSGI容器:
app.wsgi_app = FlaskTestClientProxy(app.wsgi_app)
test_client = app.test_client()
Run Code Online (Sandbox Code Playgroud) 我有一个关于SQLAlchemy,数据库分片和UUID的问题,对你来说很好.
我目前正在使用MySQL,其中有一个表格表:
CREATE TABLE foo (
added_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
id BINARY(16) NOT NULL,
... other stuff ...
UNIQUE KEY(id)
);
Run Code Online (Sandbox Code Playgroud)
这张桌子上的一点背景.我从不关心'added_id',我只是用来确保插入的项目在磁盘上聚集在一起(因为用于索引MySQL中的表的B-Tree使用主键作为集群索引).'id'列包含UUID的二进制表示 - 这是我实际关注的列,所有其他内容都引用此ID.同样,我不希望UUID成为主键,因为UUID是随机的,因此创建用于索引表的B树具有可怕的IO特性(至少在其他地方已经说过).此外,尽管UUID1包含确保以"顺序"顺序生成ID的时间戳,但在ID中包含MAC地址使我更愿意避免使用.因此,我想使用UUID4s.
好的,现在转到SQLAlchemy部分.在SQLAlchemy中,可以通过执行以下操作,使用ORM为上表定义模型:
# The SQL Alchemy ORM base class
Base = declerative_base()
# The model for table 'foo'
class Foo(Base):
__table__ = 'foo'
add_id = Column(Integer, primary_key=True, nullable=False)
id = Column(Binary, index=True, unique=True, nullable=False)
...
Run Code Online (Sandbox Code Playgroud)
同样,这与上面的SQL基本相同.
现在回答这个问题.假设该数据库将被分片(水平分区)为2个(或更多个)单独的数据库.现在,(假设没有删除)这些数据库中的每一个都将具有表foo中的added_id为1,2,3等的记录.由于SQLAlchemy使用会话来管理正在处理的对象,使得每个对象仅由其主键标识,所以似乎可能会出现这样的情况:我可以尝试从两个对象访问两个Foo对象具有相同added_id的分片导致托管会话中的某些冲突.
有人遇到过这个问题吗?你做了什么来解决它?或者,我很可能会遗漏SQLAlchemy文档中的某些内容,以确保不会发生这种情况.但是,查看SQLAlchemy下载(examples/sharding/attribute_shard.py)提供的分片示例,他们似乎通过将其中一个数据库分片指定为ID生成器来解决这个问题...创建一个隐含的瓶颈,因为所有INSERTS必须针对该单个数据库来获取ID.(他们还提到使用UUID,但显然会导致索引的性能问题.)
或者,有没有办法将UUID设置为主键,并使用added_id将数据集群在磁盘上?如果在MySQL中不可能在Postgres这样的另一个数据库中可行吗?
提前感谢任何和所有输入!
---更新----我只是想在这个问题上添加一个带外答案.以下文字不是我写的,我只想在这里包含它以防有人发现它有用.
使用MySQL和自动增量键避免这种情况的最简单方法是为每个数据库使用不同的自动增量偏移,例如:
ALTER TABLE foo AUTO_INCREMENT = 100000;
缺点是您需要注意如何配置每个分片,并且需要计划一些您使用的分片总数.
没有任何方法可以说服MySQL使用非主键作为聚簇索引.如果您不关心使用SQLAlchemy来管理数据库模式(尽管您可能应该这样做),您只需将UUID设置为SQLAlchemy模式中的主键,并将add_id保留为实际表中的pk.
我还看到了仅使用外部服务器(例如redis)来维护行ID的替代解决方案.
database ×1
flask ×1
performance ×1
python ×1
sharding ×1
sqlalchemy ×1
unit-testing ×1
uuid ×1