-
对于实时性要求高的数据,始终使用主库session进行查询访问,而非从库;
-
session在commit前,外部是看不到改变的;
-
使用 SQLAlchemy ORM 建立数据库模型时,统一使用
sqlalchemy.schma.index(name, *expressions, **kw)
方式建立索引,构建 tuple 传入数据表类的__table_args__
属性即可;
index("索引名", "索引列1", "索引列2", ... , [unique=True])
同时,索引名的命名需遵循以下规范:- 对于单列索引使用
ix_
为前缀,后跟列名:ix_索引列
- 对于复合索引使用
ix_
为前缀,后面依次跟各列名,列名合并为一个单词,不同列以“_”
分隔:ix_索引列1_索引列2_索引列n
- 对于唯一索引使用
uix_
为前缀,后面的规则同上:uix_索引列1_索引列2_索引列n
另外,增加、删除、修改数据库索引时,务必同步修改数据库模型(models.py)中的相应描述。
举例:
class Test(MapBase): __tablename__ = "test" __table_args__ = ( # t1 单索引 Index('ix_t1', 't1'), # t1, t2 联合索引 Index('ix_t1_t2', 't1', 't2'), # t2, t3 唯一索引 Index('uix_t2_t3', 't2', 't3', unique=True), ) id = Column(Integer, primary_key=True, nullable=False, autoincrement=True) t1 = Column(Integer, nullable=False, default=0) t2 = Column(Integer, nullable=False, default=0) t3 = Column(Integer, nullable=False, default=0)
- 对于单列索引使用
-
需要返回统一错误页面时,使用send_error(),不直接使用write_error();
-
Mysql 5.6版本在排序翻页时有相同值得数据取出来的顺序是不正确的,导致数据显示有问题,解决方法就是多加一个排序条件;
-
不得在可能传入用户输入数据的地方使用exec()或eval(),对字符串进行类型转换时,应使用更安全的ast.literal_eval();
-
models类里面移除一个字段,除了加上备注之外,在功能稳定后,在models里面删除该字段,并且在数据库里面把对应字段删掉,全局搜索将涉及的代码都进行优化。
-
使用 SQLAlchemy 中的
sqlalchemy.sql.operators.ColumnOperators.in_()
进行条件筛选时,如果传入in_()
中的list/tuple为空,那么可能无法有效的利用索引,造成严重性能问题,例如:q = self.session.query(models.Accountinfo).filter(models.Accountinfo.id.in_([]))
- 在旧版本的 SQLAlchemy (1.1.4) 中,空in查询会生成 “where id != id” 这样的查询语句,会造成索引失效,遍历全表
- 在新版本的 SQLAlchemy (>1.2) 中,空in查询会生成 “where 1 != 1” 这样的查询语句,此时sql分析器会认为这是无效的where语句,不会实际执行查询,所以不会有性能问题
我们生产环境中使用的是1.1.4版本的SQLAlchemy,所以编码时需要注意,对in_()中的list/tuple可能为空的情况进行判断处理。
如果你在shell打印信息中看到
SAWarning: The IN-predicate on "account_info.id" was invoked with an empty sequence. This results in a contradiction, which nonetheless can be expensive to evaluate. Consider alternative strategies for improved performance.
这样的警告信息,说明你没有对in_()中的list/tuple为空的情况进行正确的处理。 -
注意函数的默认参数陷阱:不要用可变对象和函数等作为函数的默认参数;函数的默认参数仅在这个函数对象生成时被执行一次,而不是在每次调用这个函数时执行(如同函数的静态变量一样);
-
注意-同名变量,循环里面的变量与外部的变量名一样会导致出现问题;(原因:Python变量的最小作用域为函数级:def foobar(): )
-
注意-对公共地方的修改,一定要注意对所有调用的地方都要做足测试;
-
前后端交互规范:
后端传给前端的数据应保持数据类型的一致:list应始终为list,字符串应始终为字符串,避免返回None对象或“None”字符串致使前端无法判空。
Python后端开发注意事项(Tornado)
最新推荐文章于 2024-09-27 10:37:00 发布