| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- """OA 审批应用列表:避免按应用 N+1 拉取版本大字段。"""
- import json
- import unittest
- from datetime import datetime
- from sqlalchemy import create_engine, event
- from sqlalchemy.orm import sessionmaker
- class TestListAppsPerf(unittest.TestCase):
- def setUp(self):
- from app.models.models import OaApp, OaAppGroup, OaAppVersion
- self.engine = create_engine("sqlite:///:memory:")
- OaAppGroup.__table__.create(self.engine)
- OaApp.__table__.create(self.engine)
- OaAppVersion.__table__.create(self.engine)
- Session = sessionmaker(bind=self.engine, autoflush=False, autocommit=False)
- self.db = Session()
- self.OaApp = OaApp
- self.OaAppGroup = OaAppGroup
- self.OaAppVersion = OaAppVersion
- self.now = datetime.now()
- self.query_count = 0
- @event.listens_for(self.engine, "before_cursor_execute")
- def _count(_conn, _cursor, _statement, _parameters, _context, _executemany):
- self.query_count += 1
- self._listener = _count
- def tearDown(self):
- event.remove(self.engine, "before_cursor_execute", self._listener)
- self.db.close()
- self.engine.dispose()
- def _seed_apps(self, n: int = 8):
- bulky = json.dumps({"rule": [{"x": "y" * 2000}] * 50}, ensure_ascii=False)
- self.db.add(
- self.OaAppGroup(
- id="g1",
- group_name="人事",
- tenant_no="zkxw",
- create_dept_id="",
- create_time=self.now,
- update_time=self.now,
- del_flag=0,
- )
- )
- for i in range(n):
- app_id = f"app{i}"
- self.db.add(
- self.OaApp(
- id=app_id,
- group_id="g1",
- app_name=f"应用{i}",
- initiator_scope="all",
- admin_scope="all_oa_admin",
- status="1",
- tenant_no="zkxw",
- order_num=i,
- create_dept_id="",
- create_time=self.now,
- update_time=self.now,
- del_flag=0,
- )
- )
- self.db.add(
- self.OaAppVersion(
- id=f"draft{i}",
- app_id=app_id,
- version_no=0,
- status="draft",
- is_latest_published="0",
- form_schema_json=bulky,
- flow_tree_json=bulky,
- advanced_settings_json="{}",
- tenant_no="zkxw",
- create_dept_id="",
- create_time=self.now,
- update_time=self.now,
- del_flag=0,
- )
- )
- self.db.add(
- self.OaAppVersion(
- id=f"pub{i}",
- app_id=app_id,
- version_no=i + 1,
- status="published",
- is_latest_published="1",
- form_schema_json=bulky,
- flow_tree_json=bulky,
- advanced_settings_json="{}",
- tenant_no="zkxw",
- create_dept_id="",
- create_time=self.now,
- update_time=self.now,
- del_flag=0,
- )
- )
- self.db.commit()
- def test_list_apps_query_count_bounded_and_fields_correct(self):
- from app.crud.oa_approval import list_apps
- n = 8
- self._seed_apps(n)
- self.query_count = 0
- items = list_apps(self.db, tenant_no="zkxw")
- self.assertEqual(len(items), n)
- self.assertTrue(all(it["hasDraft"] for it in items))
- self.assertEqual(
- {it["id"]: it["latestPublishedVersion"] for it in items},
- {f"app{i}": i + 1 for i in range(n)},
- )
- self.assertEqual(items[0]["groupName"], "人事")
- # apps + groups + drafts batch + published batch(不应随应用数线性增长)
- self.assertLessEqual(self.query_count, 5)
- self.assertLess(self.query_count, 2 + 2 * n)
- if __name__ == "__main__":
- unittest.main()
|