Browse Source

no message

ck 4 years ago
commit
a8b7dbf0fc
50 changed files with 3896 additions and 0 deletions
  1. 8 0
      .idea/.gitignore
  2. 8 0
      .idea/QcWebServer.iml
  3. 11 0
      .idea/dataSources.xml
  4. 1435 0
      .idea/dataSources/ddcbd9b5-5958-4096-b260-7d9f40c7feb7.xml
  5. 2 0
      .idea/dataSources/ddcbd9b5-5958-4096-b260-7d9f40c7feb7/storage_v2/_src_/schema/system.L3Icyw.meta
  6. 14 0
      .idea/inspectionProfiles/Project_Default.xml
  7. 6 0
      .idea/inspectionProfiles/profiles_settings.xml
  8. 4 0
      .idea/misc.xml
  9. 8 0
      .idea/modules.xml
  10. 20 0
      Pipfile
  11. 353 0
      Pipfile.lock
  12. 2 0
      README.markdown
  13. 48 0
      ServerWrapper.py
  14. BIN
      __pycache__/urls.cpython-36.pyc
  15. 13 0
      config/__init__.py
  16. 6 0
      config/db_config.yaml
  17. 0 0
      config/global_config.yaml
  18. 0 0
      data_manage/__init__.py
  19. BIN
      data_manage/__pycache__/__init__.cpython-36.pyc
  20. BIN
      data_manage/__pycache__/pitcher_panel.cpython-36.pyc
  21. 90 0
      data_manage/pitcher_panel.py
  22. 65 0
      handlers/HandlerBase.py
  23. 49 0
      handlers/PitcherPanel.py
  24. 0 0
      handlers/__init__.py
  25. BIN
      handlers/__pycache__/HandlerBase.cpython-36.pyc
  26. BIN
      handlers/__pycache__/PitcherPanel.cpython-36.pyc
  27. BIN
      handlers/__pycache__/__init__.cpython-36.pyc
  28. 485 0
      logs/runlog20201223.log
  29. 89 0
      logs/runlog20201224.log
  30. 12 0
      model/CommonUtils.py
  31. 621 0
      model/DataBaseOperation.py
  32. 114 0
      model/DataBaseUtils.py
  33. 273 0
      model/DateUtils.py
  34. 48 0
      model/DingTalkUtils.py
  35. 0 0
      model/__init__.py
  36. BIN
      model/__pycache__/CommonUtils.cpython-36.pyc
  37. BIN
      model/__pycache__/DataBaseOperation.cpython-36.pyc
  38. BIN
      model/__pycache__/DataBaseUtils.cpython-36.pyc
  39. BIN
      model/__pycache__/DateUtils.cpython-36.pyc
  40. BIN
      model/__pycache__/__init__.cpython-36.pyc
  41. BIN
      model/__pycache__/log.cpython-36.pyc
  42. 0 0
      model/common/__init__.py
  43. BIN
      model/common/__pycache__/__init__.cpython-36.pyc
  44. BIN
      model/common/__pycache__/errors.cpython-36.pyc
  45. BIN
      model/common/__pycache__/file_pid.cpython-36.pyc
  46. 12 0
      model/common/errors.py
  47. 22 0
      model/common/file_pid.py
  48. 67 0
      model/log.py
  49. 1 0
      pid
  50. 10 0
      urls.py

+ 8 - 0
.idea/.gitignore

@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Datasource local storage ignored files
+/../../../../:\code\QcWebServer\.idea/dataSources/
+/dataSources.local.xml
+# Editor-based HTTP Client requests
+/httpRequests/

+ 8 - 0
.idea/QcWebServer.iml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="PYTHON_MODULE" version="4">
+  <component name="NewModuleRootManager">
+    <content url="file://$MODULE_DIR$" />
+    <orderEntry type="jdk" jdkName="Python 3.6 (QcWebServer-LLP_2JqD)" jdkType="Python SDK" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>

+ 11 - 0
.idea/dataSources.xml

@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="DataSourceManagerImpl" format="xml" multifile-model="true">
+    <data-source source="LOCAL" name="ck" uuid="ddcbd9b5-5958-4096-b260-7d9f40c7feb7">
+      <driver-ref>clickhouse</driver-ref>
+      <synchronize>true</synchronize>
+      <jdbc-driver>ru.yandex.clickhouse.ClickHouseDriver</jdbc-driver>
+      <jdbc-url>jdbc:clickhouse://cc-bp1h3yc7o3g3o7k64o.ads.aliyuncs.com:8123</jdbc-url>
+    </data-source>
+  </component>
+</project>

+ 1435 - 0
.idea/dataSources/ddcbd9b5-5958-4096-b260-7d9f40c7feb7.xml

@@ -0,0 +1,1435 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<dataSource name="ck">
+  <database-model serializer="dbm" dbms="CLICKHOUSE" family-id="CLICKHOUSE" format-version="4.19">
+    <root id="1">
+      <ServerVersion>20.3.10.75</ServerVersion>
+    </root>
+    <schema id="2" parent="1" name="default">
+      <Current>1</Current>
+    </schema>
+    <schema id="3" parent="1" name="system"/>
+    <routine id="4" parent="1" name="BIT_AND">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="5" parent="1" name="BIT_OR">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="6" parent="1" name="BIT_XOR">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="7" parent="1" name="CAST"/>
+    <routine id="8" parent="1" name="CHARACTER_LENGTH"/>
+    <routine id="9" parent="1" name="CHAR_LENGTH"/>
+    <routine id="10" parent="1" name="COVAR_POP">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="11" parent="1" name="COVAR_SAMP">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="12" parent="1" name="CRC32"/>
+    <routine id="13" parent="1" name="CRC32IEEE"/>
+    <routine id="14" parent="1" name="CRC64"/>
+    <routine id="15" parent="1" name="FQDN"/>
+    <routine id="16" parent="1" name="IPv4CIDRToRange"/>
+    <routine id="17" parent="1" name="IPv4NumToString"/>
+    <routine id="18" parent="1" name="IPv4NumToStringClassC"/>
+    <routine id="19" parent="1" name="IPv4StringToNum"/>
+    <routine id="20" parent="1" name="IPv4ToIPv6"/>
+    <routine id="21" parent="1" name="IPv6CIDRToRange"/>
+    <routine id="22" parent="1" name="IPv6NumToString"/>
+    <routine id="23" parent="1" name="IPv6StringToNum"/>
+    <routine id="24" parent="1" name="JSONExtract"/>
+    <routine id="25" parent="1" name="JSONExtractArrayRaw"/>
+    <routine id="26" parent="1" name="JSONExtractBool"/>
+    <routine id="27" parent="1" name="JSONExtractFloat"/>
+    <routine id="28" parent="1" name="JSONExtractInt"/>
+    <routine id="29" parent="1" name="JSONExtractKeysAndValues"/>
+    <routine id="30" parent="1" name="JSONExtractRaw"/>
+    <routine id="31" parent="1" name="JSONExtractString"/>
+    <routine id="32" parent="1" name="JSONExtractUInt"/>
+    <routine id="33" parent="1" name="JSONHas"/>
+    <routine id="34" parent="1" name="JSONKey"/>
+    <routine id="35" parent="1" name="JSONLength"/>
+    <routine id="36" parent="1" name="JSONType"/>
+    <routine id="37" parent="1" name="MACNumToString"/>
+    <routine id="38" parent="1" name="MACStringToNum"/>
+    <routine id="39" parent="1" name="MACStringToOUI"/>
+    <routine id="40" parent="1" name="MD5"/>
+    <routine id="41" parent="1" name="SHA1"/>
+    <routine id="42" parent="1" name="SHA224"/>
+    <routine id="43" parent="1" name="SHA256"/>
+    <routine id="44" parent="1" name="STDDEV_POP">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="45" parent="1" name="STDDEV_SAMP">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="46" parent="1" name="URLHash"/>
+    <routine id="47" parent="1" name="URLHierarchy"/>
+    <routine id="48" parent="1" name="URLPathHierarchy"/>
+    <routine id="49" parent="1" name="UUIDNumToString"/>
+    <routine id="50" parent="1" name="UUIDStringToNum"/>
+    <routine id="51" parent="1" name="VAR_POP">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="52" parent="1" name="VAR_SAMP">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="53" parent="1" name="__bitBoolMaskAnd"/>
+    <routine id="54" parent="1" name="__bitBoolMaskOr"/>
+    <routine id="55" parent="1" name="__bitSwapLastTwo"/>
+    <routine id="56" parent="1" name="__bitWrapperFunc"/>
+    <routine id="57" parent="1" name="__getScalar"/>
+    <routine id="58" parent="1" name="abs"/>
+    <routine id="59" parent="1" name="acos"/>
+    <routine id="60" parent="1" name="addDays"/>
+    <routine id="61" parent="1" name="addHours"/>
+    <routine id="62" parent="1" name="addMinutes"/>
+    <routine id="63" parent="1" name="addMonths"/>
+    <routine id="64" parent="1" name="addQuarters"/>
+    <routine id="65" parent="1" name="addSeconds"/>
+    <routine id="66" parent="1" name="addWeeks"/>
+    <routine id="67" parent="1" name="addYears"/>
+    <routine id="68" parent="1" name="addressToLine"/>
+    <routine id="69" parent="1" name="addressToSymbol"/>
+    <routine id="70" parent="1" name="aggThrow">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="71" parent="1" name="all"/>
+    <routine id="72" parent="1" name="alphaTokens"/>
+    <routine id="73" parent="1" name="and"/>
+    <routine id="74" parent="1" name="any">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="75" parent="1" name="anyHeavy">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="76" parent="1" name="anyLast">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="77" parent="1" name="appendTrailingCharIfAbsent"/>
+    <routine id="78" parent="1" name="argMax">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="79" parent="1" name="argMin">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="80" parent="1" name="array"/>
+    <routine id="81" parent="1" name="arrayAll"/>
+    <routine id="82" parent="1" name="arrayCompact"/>
+    <routine id="83" parent="1" name="arrayConcat"/>
+    <routine id="84" parent="1" name="arrayCount"/>
+    <routine id="85" parent="1" name="arrayCumSum"/>
+    <routine id="86" parent="1" name="arrayCumSumNonNegative"/>
+    <routine id="87" parent="1" name="arrayDifference"/>
+    <routine id="88" parent="1" name="arrayDistinct"/>
+    <routine id="89" parent="1" name="arrayElement"/>
+    <routine id="90" parent="1" name="arrayEnumerate"/>
+    <routine id="91" parent="1" name="arrayEnumerateDense"/>
+    <routine id="92" parent="1" name="arrayEnumerateDenseRanked"/>
+    <routine id="93" parent="1" name="arrayEnumerateUniq"/>
+    <routine id="94" parent="1" name="arrayEnumerateUniqRanked"/>
+    <routine id="95" parent="1" name="arrayExists"/>
+    <routine id="96" parent="1" name="arrayFill"/>
+    <routine id="97" parent="1" name="arrayFilter"/>
+    <routine id="98" parent="1" name="arrayFirst"/>
+    <routine id="99" parent="1" name="arrayFirstIndex"/>
+    <routine id="100" parent="1" name="arrayFlatten"/>
+    <routine id="101" parent="1" name="arrayIntersect"/>
+    <routine id="102" parent="1" name="arrayJoin"/>
+    <routine id="103" parent="1" name="arrayMap"/>
+    <routine id="104" parent="1" name="arrayPopBack"/>
+    <routine id="105" parent="1" name="arrayPopFront"/>
+    <routine id="106" parent="1" name="arrayPushBack"/>
+    <routine id="107" parent="1" name="arrayPushFront"/>
+    <routine id="108" parent="1" name="arrayReduce"/>
+    <routine id="109" parent="1" name="arrayResize"/>
+    <routine id="110" parent="1" name="arrayReverse"/>
+    <routine id="111" parent="1" name="arrayReverseFill"/>
+    <routine id="112" parent="1" name="arrayReverseSort"/>
+    <routine id="113" parent="1" name="arrayReverseSplit"/>
+    <routine id="114" parent="1" name="arraySlice"/>
+    <routine id="115" parent="1" name="arraySort"/>
+    <routine id="116" parent="1" name="arraySplit"/>
+    <routine id="117" parent="1" name="arrayStringConcat"/>
+    <routine id="118" parent="1" name="arraySum"/>
+    <routine id="119" parent="1" name="arrayUniq"/>
+    <routine id="120" parent="1" name="arrayWithConstant"/>
+    <routine id="121" parent="1" name="arrayZip"/>
+    <routine id="122" parent="1" name="asin"/>
+    <routine id="123" parent="1" name="assumeNotNull"/>
+    <routine id="124" parent="1" name="atan"/>
+    <routine id="125" parent="1" name="avg">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="126" parent="1" name="avgWeighted">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="127" parent="1" name="bar"/>
+    <routine id="128" parent="1" name="base64Decode"/>
+    <routine id="129" parent="1" name="base64Encode"/>
+    <routine id="130" parent="1" name="basename"/>
+    <routine id="131" parent="1" name="bitAnd"/>
+    <routine id="132" parent="1" name="bitCount"/>
+    <routine id="133" parent="1" name="bitNot"/>
+    <routine id="134" parent="1" name="bitOr"/>
+    <routine id="135" parent="1" name="bitRotateLeft"/>
+    <routine id="136" parent="1" name="bitRotateRight"/>
+    <routine id="137" parent="1" name="bitShiftLeft"/>
+    <routine id="138" parent="1" name="bitShiftRight"/>
+    <routine id="139" parent="1" name="bitTest"/>
+    <routine id="140" parent="1" name="bitTestAll"/>
+    <routine id="141" parent="1" name="bitTestAny"/>
+    <routine id="142" parent="1" name="bitXor"/>
+    <routine id="143" parent="1" name="bitmapAnd"/>
+    <routine id="144" parent="1" name="bitmapAndCardinality"/>
+    <routine id="145" parent="1" name="bitmapAndnot"/>
+    <routine id="146" parent="1" name="bitmapAndnotCardinality"/>
+    <routine id="147" parent="1" name="bitmapBuild"/>
+    <routine id="148" parent="1" name="bitmapCardinality"/>
+    <routine id="149" parent="1" name="bitmapContains"/>
+    <routine id="150" parent="1" name="bitmapHasAll"/>
+    <routine id="151" parent="1" name="bitmapHasAny"/>
+    <routine id="152" parent="1" name="bitmapMax"/>
+    <routine id="153" parent="1" name="bitmapMin"/>
+    <routine id="154" parent="1" name="bitmapOr"/>
+    <routine id="155" parent="1" name="bitmapOrCardinality"/>
+    <routine id="156" parent="1" name="bitmapSubsetInRange"/>
+    <routine id="157" parent="1" name="bitmapSubsetLimit"/>
+    <routine id="158" parent="1" name="bitmapToArray"/>
+    <routine id="159" parent="1" name="bitmapTransform"/>
+    <routine id="160" parent="1" name="bitmapXor"/>
+    <routine id="161" parent="1" name="bitmapXorCardinality"/>
+    <routine id="162" parent="1" name="bitmaskToArray"/>
+    <routine id="163" parent="1" name="bitmaskToList"/>
+    <routine id="164" parent="1" name="blockNumber"/>
+    <routine id="165" parent="1" name="blockSerializedSize"/>
+    <routine id="166" parent="1" name="blockSize"/>
+    <routine id="167" parent="1" name="boundingRatio">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="168" parent="1" name="caseWithExpr"/>
+    <routine id="169" parent="1" name="caseWithExpression"/>
+    <routine id="170" parent="1" name="caseWithoutExpr"/>
+    <routine id="171" parent="1" name="caseWithoutExpression"/>
+    <routine id="172" parent="1" name="categoricalInformationValue">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="173" parent="1" name="cbrt"/>
+    <routine id="174" parent="1" name="ceil"/>
+    <routine id="175" parent="1" name="ceiling"/>
+    <routine id="176" parent="1" name="char"/>
+    <routine id="177" parent="1" name="cityHash64"/>
+    <routine id="178" parent="1" name="coalesce"/>
+    <routine id="179" parent="1" name="concat"/>
+    <routine id="180" parent="1" name="concatAssumeInjective"/>
+    <routine id="181" parent="1" name="convertCharset"/>
+    <routine id="182" parent="1" name="corr">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="183" parent="1" name="corrStable">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="184" parent="1" name="cos"/>
+    <routine id="185" parent="1" name="count">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="186" parent="1" name="countEqual"/>
+    <routine id="187" parent="1" name="covarPop">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="188" parent="1" name="covarPopStable">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="189" parent="1" name="covarSamp">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="190" parent="1" name="covarSampStable">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="191" parent="1" name="currentDatabase"/>
+    <routine id="192" parent="1" name="currentQuota"/>
+    <routine id="193" parent="1" name="currentQuotaID"/>
+    <routine id="194" parent="1" name="currentQuotaKey"/>
+    <routine id="195" parent="1" name="currentResourceQueue"/>
+    <routine id="196" parent="1" name="currentRowPolicies"/>
+    <routine id="197" parent="1" name="currentRowPolicyIDs"/>
+    <routine id="198" parent="1" name="currentUser"/>
+    <routine id="199" parent="1" name="cutFragment"/>
+    <routine id="200" parent="1" name="cutIPv6"/>
+    <routine id="201" parent="1" name="cutQueryString"/>
+    <routine id="202" parent="1" name="cutQueryStringAndFragment"/>
+    <routine id="203" parent="1" name="cutToFirstSignificantSubdomain"/>
+    <routine id="204" parent="1" name="cutURLParameter"/>
+    <routine id="205" parent="1" name="cutWWW"/>
+    <routine id="206" parent="1" name="dateDiff"/>
+    <routine id="207" parent="1" name="decodeURLComponent"/>
+    <routine id="208" parent="1" name="defaultValueOfArgumentType"/>
+    <routine id="209" parent="1" name="demangle"/>
+    <routine id="210" parent="1" name="dictGet"/>
+    <routine id="211" parent="1" name="dictGetDate"/>
+    <routine id="212" parent="1" name="dictGetDateOrDefault"/>
+    <routine id="213" parent="1" name="dictGetDateTime"/>
+    <routine id="214" parent="1" name="dictGetDateTimeOrDefault"/>
+    <routine id="215" parent="1" name="dictGetFloat32"/>
+    <routine id="216" parent="1" name="dictGetFloat32OrDefault"/>
+    <routine id="217" parent="1" name="dictGetFloat64"/>
+    <routine id="218" parent="1" name="dictGetFloat64OrDefault"/>
+    <routine id="219" parent="1" name="dictGetHierarchy"/>
+    <routine id="220" parent="1" name="dictGetInt16"/>
+    <routine id="221" parent="1" name="dictGetInt16OrDefault"/>
+    <routine id="222" parent="1" name="dictGetInt32"/>
+    <routine id="223" parent="1" name="dictGetInt32OrDefault"/>
+    <routine id="224" parent="1" name="dictGetInt64"/>
+    <routine id="225" parent="1" name="dictGetInt64OrDefault"/>
+    <routine id="226" parent="1" name="dictGetInt8"/>
+    <routine id="227" parent="1" name="dictGetInt8OrDefault"/>
+    <routine id="228" parent="1" name="dictGetOrDefault"/>
+    <routine id="229" parent="1" name="dictGetString"/>
+    <routine id="230" parent="1" name="dictGetStringOrDefault"/>
+    <routine id="231" parent="1" name="dictGetUInt16"/>
+    <routine id="232" parent="1" name="dictGetUInt16OrDefault"/>
+    <routine id="233" parent="1" name="dictGetUInt32"/>
+    <routine id="234" parent="1" name="dictGetUInt32OrDefault"/>
+    <routine id="235" parent="1" name="dictGetUInt64"/>
+    <routine id="236" parent="1" name="dictGetUInt64OrDefault"/>
+    <routine id="237" parent="1" name="dictGetUInt8"/>
+    <routine id="238" parent="1" name="dictGetUInt8OrDefault"/>
+    <routine id="239" parent="1" name="dictGetUUID"/>
+    <routine id="240" parent="1" name="dictGetUUIDOrDefault"/>
+    <routine id="241" parent="1" name="dictHas"/>
+    <routine id="242" parent="1" name="dictIsIn"/>
+    <routine id="243" parent="1" name="divide"/>
+    <routine id="244" parent="1" name="domain"/>
+    <routine id="245" parent="1" name="domainWithoutWWW"/>
+    <routine id="246" parent="1" name="dumpColumnStructure"/>
+    <routine id="247" parent="1" name="e"/>
+    <routine id="248" parent="1" name="empty"/>
+    <routine id="249" parent="1" name="emptyArrayDate"/>
+    <routine id="250" parent="1" name="emptyArrayDateTime"/>
+    <routine id="251" parent="1" name="emptyArrayFloat32"/>
+    <routine id="252" parent="1" name="emptyArrayFloat64"/>
+    <routine id="253" parent="1" name="emptyArrayInt16"/>
+    <routine id="254" parent="1" name="emptyArrayInt32"/>
+    <routine id="255" parent="1" name="emptyArrayInt64"/>
+    <routine id="256" parent="1" name="emptyArrayInt8"/>
+    <routine id="257" parent="1" name="emptyArrayString"/>
+    <routine id="258" parent="1" name="emptyArrayToSingle"/>
+    <routine id="259" parent="1" name="emptyArrayUInt16"/>
+    <routine id="260" parent="1" name="emptyArrayUInt32"/>
+    <routine id="261" parent="1" name="emptyArrayUInt64"/>
+    <routine id="262" parent="1" name="emptyArrayUInt8"/>
+    <routine id="263" parent="1" name="endsWith"/>
+    <routine id="264" parent="1" name="entropy">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="265" parent="1" name="equals"/>
+    <routine id="266" parent="1" name="erf"/>
+    <routine id="267" parent="1" name="erfc"/>
+    <routine id="268" parent="1" name="evalMLMethod"/>
+    <routine id="269" parent="1" name="exp"/>
+    <routine id="270" parent="1" name="exp10"/>
+    <routine id="271" parent="1" name="exp2"/>
+    <routine id="272" parent="1" name="extract"/>
+    <routine id="273" parent="1" name="extractAll"/>
+    <routine id="274" parent="1" name="extractURLParameter"/>
+    <routine id="275" parent="1" name="extractURLParameterNames"/>
+    <routine id="276" parent="1" name="extractURLParameters"/>
+    <routine id="277" parent="1" name="farmHash64"/>
+    <routine id="278" parent="1" name="filesystemAvailable"/>
+    <routine id="279" parent="1" name="filesystemCapacity"/>
+    <routine id="280" parent="1" name="filesystemFree"/>
+    <routine id="281" parent="1" name="finalizeAggregation"/>
+    <routine id="282" parent="1" name="firstSignificantSubdomain"/>
+    <routine id="283" parent="1" name="flatten"/>
+    <routine id="284" parent="1" name="floor"/>
+    <routine id="285" parent="1" name="format"/>
+    <routine id="286" parent="1" name="formatDateTime"/>
+    <routine id="287" parent="1" name="formatReadableSize"/>
+    <routine id="288" parent="1" name="fragment"/>
+    <routine id="289" parent="1" name="fullHostName"/>
+    <routine id="290" parent="1" name="gccMurmurHash"/>
+    <routine id="291" parent="1" name="gcd"/>
+    <routine id="292" parent="1" name="generateUUIDv4"/>
+    <routine id="293" parent="1" name="geoDistance"/>
+    <routine id="294" parent="1" name="geoToH3"/>
+    <routine id="295" parent="1" name="geohashDecode"/>
+    <routine id="296" parent="1" name="geohashEncode"/>
+    <routine id="297" parent="1" name="geohashesInBox"/>
+    <routine id="298" parent="1" name="getMacro"/>
+    <routine id="299" parent="1" name="getSizeOfEnumType"/>
+    <routine id="300" parent="1" name="globalIn"/>
+    <routine id="301" parent="1" name="globalNotIn"/>
+    <routine id="302" parent="1" name="greatCircleAngle"/>
+    <routine id="303" parent="1" name="greatCircleDistance"/>
+    <routine id="304" parent="1" name="greater"/>
+    <routine id="305" parent="1" name="greaterOrEquals"/>
+    <routine id="306" parent="1" name="greatest"/>
+    <routine id="307" parent="1" name="groupArray">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="308" parent="1" name="groupArrayInsertAt">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="309" parent="1" name="groupArrayMovingAvg">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="310" parent="1" name="groupArrayMovingSum">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="311" parent="1" name="groupArraySample">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="312" parent="1" name="groupBitAnd">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="313" parent="1" name="groupBitOr">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="314" parent="1" name="groupBitXor">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="315" parent="1" name="groupBitmap">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="316" parent="1" name="groupBitmapAnd">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="317" parent="1" name="groupBitmapOr">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="318" parent="1" name="groupBitmapXor">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="319" parent="1" name="groupUniqArray">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="320" parent="1" name="h3EdgeAngle"/>
+    <routine id="321" parent="1" name="h3EdgeLengthM"/>
+    <routine id="322" parent="1" name="h3GetBaseCell"/>
+    <routine id="323" parent="1" name="h3GetResolution"/>
+    <routine id="324" parent="1" name="h3HexAreaM2"/>
+    <routine id="325" parent="1" name="h3IndexesAreNeighbors"/>
+    <routine id="326" parent="1" name="h3IsValid"/>
+    <routine id="327" parent="1" name="h3ToChildren"/>
+    <routine id="328" parent="1" name="h3ToParent"/>
+    <routine id="329" parent="1" name="h3ToString"/>
+    <routine id="330" parent="1" name="h3kRing"/>
+    <routine id="331" parent="1" name="halfMD5"/>
+    <routine id="332" parent="1" name="has"/>
+    <routine id="333" parent="1" name="hasAll"/>
+    <routine id="334" parent="1" name="hasAny"/>
+    <routine id="335" parent="1" name="hasColumnInTable"/>
+    <routine id="336" parent="1" name="hasToken"/>
+    <routine id="337" parent="1" name="hasTokenCaseInsensitive"/>
+    <routine id="338" parent="1" name="hex"/>
+    <routine id="339" parent="1" name="histogram">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="340" parent="1" name="hiveHash"/>
+    <routine id="341" parent="1" name="identity"/>
+    <routine id="342" parent="1" name="if"/>
+    <routine id="343" parent="1" name="ifNotFinite"/>
+    <routine id="344" parent="1" name="ifNull"/>
+    <routine id="345" parent="1" name="ignore"/>
+    <routine id="346" parent="1" name="ignoreExceptNull"/>
+    <routine id="347" parent="1" name="in"/>
+    <routine id="348" parent="1" name="indexOf"/>
+    <routine id="349" parent="1" name="intDiv"/>
+    <routine id="350" parent="1" name="intDivOrZero"/>
+    <routine id="351" parent="1" name="intExp10"/>
+    <routine id="352" parent="1" name="intExp2"/>
+    <routine id="353" parent="1" name="intHash32"/>
+    <routine id="354" parent="1" name="intHash64"/>
+    <routine id="355" parent="1" name="isConstant"/>
+    <routine id="356" parent="1" name="isFinite"/>
+    <routine id="357" parent="1" name="isInfinite"/>
+    <routine id="358" parent="1" name="isNaN"/>
+    <routine id="359" parent="1" name="isNotNull"/>
+    <routine id="360" parent="1" name="isNull"/>
+    <routine id="361" parent="1" name="isValidJSON"/>
+    <routine id="362" parent="1" name="isValidUTF8"/>
+    <routine id="363" parent="1" name="javaHash"/>
+    <routine id="364" parent="1" name="javaHashUTF16LE"/>
+    <routine id="365" parent="1" name="joinGet"/>
+    <routine id="366" parent="1" name="jumpConsistentHash"/>
+    <routine id="367" parent="1" name="kurtPop">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="368" parent="1" name="kurtSamp">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="369" parent="1" name="lcase"/>
+    <routine id="370" parent="1" name="lcm"/>
+    <routine id="371" parent="1" name="least"/>
+    <routine id="372" parent="1" name="length"/>
+    <routine id="373" parent="1" name="lengthUTF8"/>
+    <routine id="374" parent="1" name="less"/>
+    <routine id="375" parent="1" name="lessOrEquals"/>
+    <routine id="376" parent="1" name="lgamma"/>
+    <routine id="377" parent="1" name="like"/>
+    <routine id="378" parent="1" name="ln"/>
+    <routine id="379" parent="1" name="locate"/>
+    <routine id="380" parent="1" name="log"/>
+    <routine id="381" parent="1" name="log10"/>
+    <routine id="382" parent="1" name="log2"/>
+    <routine id="383" parent="1" name="lowCardinalityIndices"/>
+    <routine id="384" parent="1" name="lowCardinalityKeys"/>
+    <routine id="385" parent="1" name="lower"/>
+    <routine id="386" parent="1" name="lowerUTF8"/>
+    <routine id="387" parent="1" name="match"/>
+    <routine id="388" parent="1" name="materialize"/>
+    <routine id="389" parent="1" name="max">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="390" parent="1" name="maxIntersections">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="391" parent="1" name="maxIntersectionsPosition">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="392" parent="1" name="median">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="393" parent="1" name="medianDeterministic">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="394" parent="1" name="medianExact">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="395" parent="1" name="medianExactWeighted">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="396" parent="1" name="medianTDigest">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="397" parent="1" name="medianTDigestWeighted">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="398" parent="1" name="medianTiming">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="399" parent="1" name="medianTimingWeighted">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="400" parent="1" name="metroHash64"/>
+    <routine id="401" parent="1" name="mid"/>
+    <routine id="402" parent="1" name="min">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="403" parent="1" name="minus"/>
+    <routine id="404" parent="1" name="modelEvaluate"/>
+    <routine id="405" parent="1" name="modulo"/>
+    <routine id="406" parent="1" name="moduloOrZero"/>
+    <routine id="407" parent="1" name="multiFuzzyMatchAllIndices"/>
+    <routine id="408" parent="1" name="multiFuzzyMatchAny"/>
+    <routine id="409" parent="1" name="multiFuzzyMatchAnyIndex"/>
+    <routine id="410" parent="1" name="multiIf"/>
+    <routine id="411" parent="1" name="multiMatchAllIndices"/>
+    <routine id="412" parent="1" name="multiMatchAny"/>
+    <routine id="413" parent="1" name="multiMatchAnyIndex"/>
+    <routine id="414" parent="1" name="multiSearchAllPositions"/>
+    <routine id="415" parent="1" name="multiSearchAllPositionsCaseInsensitive"/>
+    <routine id="416" parent="1" name="multiSearchAllPositionsCaseInsensitiveUTF8"/>
+    <routine id="417" parent="1" name="multiSearchAllPositionsUTF8"/>
+    <routine id="418" parent="1" name="multiSearchAny"/>
+    <routine id="419" parent="1" name="multiSearchAnyCaseInsensitive"/>
+    <routine id="420" parent="1" name="multiSearchAnyCaseInsensitiveUTF8"/>
+    <routine id="421" parent="1" name="multiSearchAnyUTF8"/>
+    <routine id="422" parent="1" name="multiSearchFirstIndex"/>
+    <routine id="423" parent="1" name="multiSearchFirstIndexCaseInsensitive"/>
+    <routine id="424" parent="1" name="multiSearchFirstIndexCaseInsensitiveUTF8"/>
+    <routine id="425" parent="1" name="multiSearchFirstIndexUTF8"/>
+    <routine id="426" parent="1" name="multiSearchFirstPosition"/>
+    <routine id="427" parent="1" name="multiSearchFirstPositionCaseInsensitive"/>
+    <routine id="428" parent="1" name="multiSearchFirstPositionCaseInsensitiveUTF8"/>
+    <routine id="429" parent="1" name="multiSearchFirstPositionUTF8"/>
+    <routine id="430" parent="1" name="multiply"/>
+    <routine id="431" parent="1" name="murmurHash2_32"/>
+    <routine id="432" parent="1" name="murmurHash2_64"/>
+    <routine id="433" parent="1" name="murmurHash3_128"/>
+    <routine id="434" parent="1" name="murmurHash3_32"/>
+    <routine id="435" parent="1" name="murmurHash3_64"/>
+    <routine id="436" parent="1" name="negate"/>
+    <routine id="437" parent="1" name="neighbor"/>
+    <routine id="438" parent="1" name="ngramDistance"/>
+    <routine id="439" parent="1" name="ngramDistanceCaseInsensitive"/>
+    <routine id="440" parent="1" name="ngramDistanceCaseInsensitiveUTF8"/>
+    <routine id="441" parent="1" name="ngramDistanceUTF8"/>
+    <routine id="442" parent="1" name="ngramSearch"/>
+    <routine id="443" parent="1" name="ngramSearchCaseInsensitive"/>
+    <routine id="444" parent="1" name="ngramSearchCaseInsensitiveUTF8"/>
+    <routine id="445" parent="1" name="ngramSearchUTF8"/>
+    <routine id="446" parent="1" name="not"/>
+    <routine id="447" parent="1" name="notEmpty"/>
+    <routine id="448" parent="1" name="notEquals"/>
+    <routine id="449" parent="1" name="notIn"/>
+    <routine id="450" parent="1" name="notLike"/>
+    <routine id="451" parent="1" name="now"/>
+    <routine id="452" parent="1" name="now64"/>
+    <routine id="453" parent="1" name="nullIf"/>
+    <routine id="454" parent="1" name="or"/>
+    <routine id="455" parent="1" name="parseDateTime64BestEffort"/>
+    <routine id="456" parent="1" name="parseDateTime64BestEffortOrNull"/>
+    <routine id="457" parent="1" name="parseDateTime64BestEffortOrZero"/>
+    <routine id="458" parent="1" name="parseDateTimeBestEffort"/>
+    <routine id="459" parent="1" name="parseDateTimeBestEffortOrNull"/>
+    <routine id="460" parent="1" name="parseDateTimeBestEffortOrZero"/>
+    <routine id="461" parent="1" name="path"/>
+    <routine id="462" parent="1" name="pathFull"/>
+    <routine id="463" parent="1" name="pi"/>
+    <routine id="464" parent="1" name="plus"/>
+    <routine id="465" parent="1" name="pointInEllipses"/>
+    <routine id="466" parent="1" name="pointInPolygon"/>
+    <routine id="467" parent="1" name="position"/>
+    <routine id="468" parent="1" name="positionCaseInsensitive"/>
+    <routine id="469" parent="1" name="positionCaseInsensitiveUTF8"/>
+    <routine id="470" parent="1" name="positionUTF8"/>
+    <routine id="471" parent="1" name="pow"/>
+    <routine id="472" parent="1" name="power"/>
+    <routine id="473" parent="1" name="protocol"/>
+    <routine id="474" parent="1" name="quantile">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="475" parent="1" name="quantileDeterministic">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="476" parent="1" name="quantileExact">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="477" parent="1" name="quantileExactExclusive">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="478" parent="1" name="quantileExactInclusive">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="479" parent="1" name="quantileExactWeighted">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="480" parent="1" name="quantileTDigest">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="481" parent="1" name="quantileTDigestWeighted">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="482" parent="1" name="quantileTiming">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="483" parent="1" name="quantileTimingWeighted">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="484" parent="1" name="quantiles">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="485" parent="1" name="quantilesDeterministic">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="486" parent="1" name="quantilesExact">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="487" parent="1" name="quantilesExactExclusive">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="488" parent="1" name="quantilesExactInclusive">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="489" parent="1" name="quantilesExactWeighted">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="490" parent="1" name="quantilesTDigest">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="491" parent="1" name="quantilesTDigestWeighted">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="492" parent="1" name="quantilesTiming">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="493" parent="1" name="quantilesTimingWeighted">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="494" parent="1" name="queryString"/>
+    <routine id="495" parent="1" name="queryStringAndFragment"/>
+    <routine id="496" parent="1" name="rand"/>
+    <routine id="497" parent="1" name="rand64"/>
+    <routine id="498" parent="1" name="randConstant"/>
+    <routine id="499" parent="1" name="randomPrintableASCII"/>
+    <routine id="500" parent="1" name="range"/>
+    <routine id="501" parent="1" name="regexpQuoteMeta"/>
+    <routine id="502" parent="1" name="regionHierarchy"/>
+    <routine id="503" parent="1" name="regionIn"/>
+    <routine id="504" parent="1" name="regionToArea"/>
+    <routine id="505" parent="1" name="regionToCity"/>
+    <routine id="506" parent="1" name="regionToContinent"/>
+    <routine id="507" parent="1" name="regionToCountry"/>
+    <routine id="508" parent="1" name="regionToDistrict"/>
+    <routine id="509" parent="1" name="regionToName"/>
+    <routine id="510" parent="1" name="regionToPopulation"/>
+    <routine id="511" parent="1" name="regionToTopContinent"/>
+    <routine id="512" parent="1" name="reinterpretAsDate"/>
+    <routine id="513" parent="1" name="reinterpretAsDateTime"/>
+    <routine id="514" parent="1" name="reinterpretAsFixedString"/>
+    <routine id="515" parent="1" name="reinterpretAsFloat32"/>
+    <routine id="516" parent="1" name="reinterpretAsFloat64"/>
+    <routine id="517" parent="1" name="reinterpretAsInt16"/>
+    <routine id="518" parent="1" name="reinterpretAsInt32"/>
+    <routine id="519" parent="1" name="reinterpretAsInt64"/>
+    <routine id="520" parent="1" name="reinterpretAsInt8"/>
+    <routine id="521" parent="1" name="reinterpretAsString"/>
+    <routine id="522" parent="1" name="reinterpretAsUInt16"/>
+    <routine id="523" parent="1" name="reinterpretAsUInt32"/>
+    <routine id="524" parent="1" name="reinterpretAsUInt64"/>
+    <routine id="525" parent="1" name="reinterpretAsUInt8"/>
+    <routine id="526" parent="1" name="repeat"/>
+    <routine id="527" parent="1" name="replace"/>
+    <routine id="528" parent="1" name="replaceAll"/>
+    <routine id="529" parent="1" name="replaceOne"/>
+    <routine id="530" parent="1" name="replaceRegexpAll"/>
+    <routine id="531" parent="1" name="replaceRegexpOne"/>
+    <routine id="532" parent="1" name="replicate"/>
+    <routine id="533" parent="1" name="retention">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="534" parent="1" name="reverse"/>
+    <routine id="535" parent="1" name="reverseUTF8"/>
+    <routine id="536" parent="1" name="round"/>
+    <routine id="537" parent="1" name="roundAge"/>
+    <routine id="538" parent="1" name="roundBankers"/>
+    <routine id="539" parent="1" name="roundDown"/>
+    <routine id="540" parent="1" name="roundDuration"/>
+    <routine id="541" parent="1" name="roundToExp2"/>
+    <routine id="542" parent="1" name="rowNumberInAllBlocks"/>
+    <routine id="543" parent="1" name="rowNumberInBlock"/>
+    <routine id="544" parent="1" name="runningAccumulate"/>
+    <routine id="545" parent="1" name="runningDifference"/>
+    <routine id="546" parent="1" name="runningDifferenceStartingWithFirstValue"/>
+    <routine id="547" parent="1" name="sequenceCount">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="548" parent="1" name="sequenceMatch">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="549" parent="1" name="sigmoid"/>
+    <routine id="550" parent="1" name="simpleLinearRegression">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="551" parent="1" name="sin"/>
+    <routine id="552" parent="1" name="sipHash128"/>
+    <routine id="553" parent="1" name="sipHash64"/>
+    <routine id="554" parent="1" name="skewPop">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="555" parent="1" name="skewSamp">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="556" parent="1" name="sleep"/>
+    <routine id="557" parent="1" name="sleepEachRow"/>
+    <routine id="558" parent="1" name="splitByChar"/>
+    <routine id="559" parent="1" name="splitByString"/>
+    <routine id="560" parent="1" name="sqrt"/>
+    <routine id="561" parent="1" name="startsWith"/>
+    <routine id="562" parent="1" name="stddevPop">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="563" parent="1" name="stddevPopStable">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="564" parent="1" name="stddevSamp">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="565" parent="1" name="stddevSampStable">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="566" parent="1" name="stochasticLinearRegression">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="567" parent="1" name="stochasticLogisticRegression">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="568" parent="1" name="stringToH3"/>
+    <routine id="569" parent="1" name="substr"/>
+    <routine id="570" parent="1" name="substring"/>
+    <routine id="571" parent="1" name="substringUTF8"/>
+    <routine id="572" parent="1" name="subtractDays"/>
+    <routine id="573" parent="1" name="subtractHours"/>
+    <routine id="574" parent="1" name="subtractMinutes"/>
+    <routine id="575" parent="1" name="subtractMonths"/>
+    <routine id="576" parent="1" name="subtractQuarters"/>
+    <routine id="577" parent="1" name="subtractSeconds"/>
+    <routine id="578" parent="1" name="subtractWeeks"/>
+    <routine id="579" parent="1" name="subtractYears"/>
+    <routine id="580" parent="1" name="sum">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="581" parent="1" name="sumKahan">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="582" parent="1" name="sumMap">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="583" parent="1" name="sumMapFiltered">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="584" parent="1" name="sumMapFilteredWithOverflow">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="585" parent="1" name="sumMapWithOverflow">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="586" parent="1" name="sumWithOverflow">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="587" parent="1" name="sumburConsistentHash"/>
+    <routine id="588" parent="1" name="tan"/>
+    <routine id="589" parent="1" name="tanh"/>
+    <routine id="590" parent="1" name="tgamma"/>
+    <routine id="591" parent="1" name="throwIf"/>
+    <routine id="592" parent="1" name="timeSeriesGroupRateSum">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="593" parent="1" name="timeSeriesGroupSum">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="594" parent="1" name="timeSlot"/>
+    <routine id="595" parent="1" name="timeSlots"/>
+    <routine id="596" parent="1" name="timezone"/>
+    <routine id="597" parent="1" name="toColumnTypeName"/>
+    <routine id="598" parent="1" name="toDate"/>
+    <routine id="599" parent="1" name="toDateOrNull"/>
+    <routine id="600" parent="1" name="toDateOrZero"/>
+    <routine id="601" parent="1" name="toDateTime"/>
+    <routine id="602" parent="1" name="toDateTime64"/>
+    <routine id="603" parent="1" name="toDateTime64OrNull"/>
+    <routine id="604" parent="1" name="toDateTime64OrZero"/>
+    <routine id="605" parent="1" name="toDateTimeOrNull"/>
+    <routine id="606" parent="1" name="toDateTimeOrZero"/>
+    <routine id="607" parent="1" name="toDayOfMonth"/>
+    <routine id="608" parent="1" name="toDayOfWeek"/>
+    <routine id="609" parent="1" name="toDayOfYear"/>
+    <routine id="610" parent="1" name="toDecimal128"/>
+    <routine id="611" parent="1" name="toDecimal128OrNull"/>
+    <routine id="612" parent="1" name="toDecimal128OrZero"/>
+    <routine id="613" parent="1" name="toDecimal32"/>
+    <routine id="614" parent="1" name="toDecimal32OrNull"/>
+    <routine id="615" parent="1" name="toDecimal32OrZero"/>
+    <routine id="616" parent="1" name="toDecimal64"/>
+    <routine id="617" parent="1" name="toDecimal64OrNull"/>
+    <routine id="618" parent="1" name="toDecimal64OrZero"/>
+    <routine id="619" parent="1" name="toFixedString"/>
+    <routine id="620" parent="1" name="toFloat32"/>
+    <routine id="621" parent="1" name="toFloat32OrNull"/>
+    <routine id="622" parent="1" name="toFloat32OrZero"/>
+    <routine id="623" parent="1" name="toFloat64"/>
+    <routine id="624" parent="1" name="toFloat64OrNull"/>
+    <routine id="625" parent="1" name="toFloat64OrZero"/>
+    <routine id="626" parent="1" name="toHour"/>
+    <routine id="627" parent="1" name="toIPv4"/>
+    <routine id="628" parent="1" name="toIPv6"/>
+    <routine id="629" parent="1" name="toISOWeek"/>
+    <routine id="630" parent="1" name="toISOYear"/>
+    <routine id="631" parent="1" name="toInt16"/>
+    <routine id="632" parent="1" name="toInt16OrNull"/>
+    <routine id="633" parent="1" name="toInt16OrZero"/>
+    <routine id="634" parent="1" name="toInt32"/>
+    <routine id="635" parent="1" name="toInt32OrNull"/>
+    <routine id="636" parent="1" name="toInt32OrZero"/>
+    <routine id="637" parent="1" name="toInt64"/>
+    <routine id="638" parent="1" name="toInt64OrNull"/>
+    <routine id="639" parent="1" name="toInt64OrZero"/>
+    <routine id="640" parent="1" name="toInt8"/>
+    <routine id="641" parent="1" name="toInt8OrNull"/>
+    <routine id="642" parent="1" name="toInt8OrZero"/>
+    <routine id="643" parent="1" name="toIntervalDay"/>
+    <routine id="644" parent="1" name="toIntervalHour"/>
+    <routine id="645" parent="1" name="toIntervalMinute"/>
+    <routine id="646" parent="1" name="toIntervalMonth"/>
+    <routine id="647" parent="1" name="toIntervalQuarter"/>
+    <routine id="648" parent="1" name="toIntervalSecond"/>
+    <routine id="649" parent="1" name="toIntervalWeek"/>
+    <routine id="650" parent="1" name="toIntervalYear"/>
+    <routine id="651" parent="1" name="toLowCardinality"/>
+    <routine id="652" parent="1" name="toMinute"/>
+    <routine id="653" parent="1" name="toMonday"/>
+    <routine id="654" parent="1" name="toMonth"/>
+    <routine id="655" parent="1" name="toNullable"/>
+    <routine id="656" parent="1" name="toQuarter"/>
+    <routine id="657" parent="1" name="toRelativeDayNum"/>
+    <routine id="658" parent="1" name="toRelativeHourNum"/>
+    <routine id="659" parent="1" name="toRelativeMinuteNum"/>
+    <routine id="660" parent="1" name="toRelativeMonthNum"/>
+    <routine id="661" parent="1" name="toRelativeQuarterNum"/>
+    <routine id="662" parent="1" name="toRelativeSecondNum"/>
+    <routine id="663" parent="1" name="toRelativeWeekNum"/>
+    <routine id="664" parent="1" name="toRelativeYearNum"/>
+    <routine id="665" parent="1" name="toSecond"/>
+    <routine id="666" parent="1" name="toStartOfDay"/>
+    <routine id="667" parent="1" name="toStartOfFifteenMinutes"/>
+    <routine id="668" parent="1" name="toStartOfFiveMinute"/>
+    <routine id="669" parent="1" name="toStartOfHour"/>
+    <routine id="670" parent="1" name="toStartOfISOYear"/>
+    <routine id="671" parent="1" name="toStartOfInterval"/>
+    <routine id="672" parent="1" name="toStartOfMinute"/>
+    <routine id="673" parent="1" name="toStartOfMonth"/>
+    <routine id="674" parent="1" name="toStartOfQuarter"/>
+    <routine id="675" parent="1" name="toStartOfTenMinutes"/>
+    <routine id="676" parent="1" name="toStartOfWeek"/>
+    <routine id="677" parent="1" name="toStartOfYear"/>
+    <routine id="678" parent="1" name="toString"/>
+    <routine id="679" parent="1" name="toStringCutToZero"/>
+    <routine id="680" parent="1" name="toTime"/>
+    <routine id="681" parent="1" name="toTimeZone"/>
+    <routine id="682" parent="1" name="toTypeName"/>
+    <routine id="683" parent="1" name="toUInt16"/>
+    <routine id="684" parent="1" name="toUInt16OrNull"/>
+    <routine id="685" parent="1" name="toUInt16OrZero"/>
+    <routine id="686" parent="1" name="toUInt32"/>
+    <routine id="687" parent="1" name="toUInt32OrNull"/>
+    <routine id="688" parent="1" name="toUInt32OrZero"/>
+    <routine id="689" parent="1" name="toUInt64"/>
+    <routine id="690" parent="1" name="toUInt64OrNull"/>
+    <routine id="691" parent="1" name="toUInt64OrZero"/>
+    <routine id="692" parent="1" name="toUInt8"/>
+    <routine id="693" parent="1" name="toUInt8OrNull"/>
+    <routine id="694" parent="1" name="toUInt8OrZero"/>
+    <routine id="695" parent="1" name="toUUID"/>
+    <routine id="696" parent="1" name="toUnixTimestamp"/>
+    <routine id="697" parent="1" name="toValidUTF8"/>
+    <routine id="698" parent="1" name="toWeek"/>
+    <routine id="699" parent="1" name="toYYYYMM"/>
+    <routine id="700" parent="1" name="toYYYYMMDD"/>
+    <routine id="701" parent="1" name="toYYYYMMDDhhmmss"/>
+    <routine id="702" parent="1" name="toYear"/>
+    <routine id="703" parent="1" name="toYearWeek"/>
+    <routine id="704" parent="1" name="today"/>
+    <routine id="705" parent="1" name="topK">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="706" parent="1" name="topKWeighted">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="707" parent="1" name="topLevelDomain"/>
+    <routine id="708" parent="1" name="transform"/>
+    <routine id="709" parent="1" name="trimBoth"/>
+    <routine id="710" parent="1" name="trimLeft"/>
+    <routine id="711" parent="1" name="trimRight"/>
+    <routine id="712" parent="1" name="trunc"/>
+    <routine id="713" parent="1" name="truncate"/>
+    <routine id="714" parent="1" name="tryBase64Decode"/>
+    <routine id="715" parent="1" name="tuple"/>
+    <routine id="716" parent="1" name="tupleElement"/>
+    <routine id="717" parent="1" name="ucase"/>
+    <routine id="718" parent="1" name="unhex"/>
+    <routine id="719" parent="1" name="uniq">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="720" parent="1" name="uniqCombined">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="721" parent="1" name="uniqCombined64">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="722" parent="1" name="uniqExact">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="723" parent="1" name="uniqHLL12">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="724" parent="1" name="uniqUpTo">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="725" parent="1" name="upper"/>
+    <routine id="726" parent="1" name="upperUTF8"/>
+    <routine id="727" parent="1" name="user"/>
+    <routine id="728" parent="1" name="varPop">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="729" parent="1" name="varPopStable">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="730" parent="1" name="varSamp">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="731" parent="1" name="varSampStable">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="732" parent="1" name="version"/>
+    <routine id="733" parent="1" name="visibleWidth"/>
+    <routine id="734" parent="1" name="visitParamExtractBool"/>
+    <routine id="735" parent="1" name="visitParamExtractFloat"/>
+    <routine id="736" parent="1" name="visitParamExtractInt"/>
+    <routine id="737" parent="1" name="visitParamExtractRaw"/>
+    <routine id="738" parent="1" name="visitParamExtractString"/>
+    <routine id="739" parent="1" name="visitParamExtractUInt"/>
+    <routine id="740" parent="1" name="visitParamHas"/>
+    <routine id="741" parent="1" name="week"/>
+    <routine id="742" parent="1" name="windowFunnel">
+      <Aggregate>1</Aggregate>
+    </routine>
+    <routine id="743" parent="1" name="xor"/>
+    <routine id="744" parent="1" name="xxHash32"/>
+    <routine id="745" parent="1" name="xxHash64"/>
+    <routine id="746" parent="1" name="yandexConsistentHash"/>
+    <routine id="747" parent="1" name="yearweek"/>
+    <routine id="748" parent="1" name="yesterday"/>
+    <table id="749" parent="2" name="dm_pitcher_daily_page_total">
+      <Engine>MergeTree</Engine>
+      <EngineParams>() PARTITION BY dt PRIMARY KEY (dt, pitcher) ORDER BY (dt, pitcher) SETTINGS index_granularity = 8192</EngineParams>
+    </table>
+    <table id="750" parent="2" name="dw_daily_channel">
+      <Engine>MergeTree</Engine>
+      <EngineParams>() PRIMARY KEY (dt, channel) ORDER BY (dt, channel) SETTINGS index_granularity = 8192</EngineParams>
+    </table>
+    <table id="751" parent="2" name="dw_daily_channel_cost">
+      <Engine>MergeTree</Engine>
+      <EngineParams>() PARTITION BY dt PRIMARY KEY (dt, channel) ORDER BY (dt, channel) SETTINGS index_granularity = 8192</EngineParams>
+    </table>
+    <table id="752" parent="2" name="dw_daily_channel_plus">
+      <Engine>MergeTree</Engine>
+      <EngineParams>() PRIMARY KEY (dt, channel) ORDER BY (dt, channel) SETTINGS index_granularity = 8192</EngineParams>
+    </table>
+    <table id="753" parent="2" name="order">
+      <Engine>MergeTree</Engine>
+      <EngineParams>() PARTITION BY date PRIMARY KEY (order_id, platform) ORDER BY (order_id, platform, order_time) SETTINGS index_granularity = 8192</EngineParams>
+    </table>
+    <column id="754" parent="749" name="dt">
+      <Position>1</Position>
+      <DataType>Date|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="755" parent="749" name="pitcher">
+      <Position>2</Position>
+      <DataType>String|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="756" parent="749" name="cost">
+      <Position>3</Position>
+      <DataType>Float32|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="757" parent="749" name="amount">
+      <Position>4</Position>
+      <DataType>Float32|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="758" parent="749" name="roi">
+      <Position>5</Position>
+      <DataType>Float32|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="759" parent="749" name="channel_count">
+      <Position>6</Position>
+      <DataType>Int32|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="760" parent="749" name="on_channel_count">
+      <Position>7</Position>
+      <DataType>Int32|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="761" parent="749" name="off_channel_count">
+      <Position>8</Position>
+      <DataType>Int32|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="762" parent="749" name="this_month_cost">
+      <Position>9</Position>
+      <DataType>Float32|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="763" parent="749" name="this_month_amount">
+      <Position>10</Position>
+      <DataType>Float32|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="764" parent="749" name="this_month_roi">
+      <Position>11</Position>
+      <DataType>Float32|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="765" parent="749" name="last_month_cost">
+      <Position>12</Position>
+      <DataType>Float32|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="766" parent="749" name="last_month_amount">
+      <Position>13</Position>
+      <DataType>Float32|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="767" parent="749" name="last_month_roi">
+      <Position>14</Position>
+      <DataType>Float32|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="768" parent="749" name="last_month_far_amount">
+      <Position>15</Position>
+      <DataType>Float32|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="769" parent="749" name="follow_user">
+      <Position>16</Position>
+      <DataType>Int32|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="770" parent="750" name="dt">
+      <Position>1</Position>
+      <DataType>Date|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="771" parent="750" name="channel">
+      <Position>2</Position>
+      <DataType>String|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="772" parent="750" name="pitcher">
+      <Position>3</Position>
+      <DataType>String|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="773" parent="750" name="stage">
+      <Position>4</Position>
+      <DataType>String|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="774" parent="750" name="platform">
+      <Position>5</Position>
+      <DataType>String|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="775" parent="750" name="book">
+      <Position>6</Position>
+      <DataType>String|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="776" parent="750" name="order_count">
+      <Position>7</Position>
+      <DataType>Int32|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="777" parent="750" name="order_user">
+      <Position>8</Position>
+      <DataType>Int32|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="778" parent="750" name="order_amount">
+      <Position>9</Position>
+      <DataType>Float32|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="779" parent="750" name="first_order_count">
+      <Position>10</Position>
+      <DataType>Int32|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="780" parent="750" name="first_order_user">
+      <Position>11</Position>
+      <DataType>Int32|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="781" parent="750" name="first_order_amount">
+      <Position>12</Position>
+      <DataType>Float32|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="782" parent="750" name="view_count">
+      <Position>13</Position>
+      <DataType>Int32|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="783" parent="750" name="click_count">
+      <Position>14</Position>
+      <DataType>Int32|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="784" parent="750" name="follow_user">
+      <Position>15</Position>
+      <DataType>Int32|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="785" parent="750" name="cost">
+      <Position>16</Position>
+      <DataType>Float32|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="786" parent="750" name="reg_order_count">
+      <Position>17</Position>
+      <DataType>Int32|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="787" parent="750" name="reg_order_user">
+      <Position>18</Position>
+      <DataType>Int32|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="788" parent="750" name="reg_order_amount">
+      <Position>19</Position>
+      <DataType>Float32|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="789" parent="750" name="reg_order_amount30">
+      <Position>20</Position>
+      <DataType>Float32|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="790" parent="750" name="web_view_count">
+      <Position>21</Position>
+      <DataType>Int32|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="791" parent="750" name="platform_view_count">
+      <Position>22</Position>
+      <DataType>Int32|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="792" parent="750" name="web_order_count">
+      <Position>23</Position>
+      <DataType>Int32|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="793" parent="750" name="total_cost">
+      <Position>24</Position>
+      <DataType>Float32|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="794" parent="750" name="total_amount">
+      <Position>25</Position>
+      <DataType>Float32|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="795" parent="751" name="dt">
+      <Position>1</Position>
+      <DataType>Date|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="796" parent="751" name="channel">
+      <Position>2</Position>
+      <DataType>String|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="797" parent="751" name="pitcher">
+      <Position>3</Position>
+      <DataType>String|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="798" parent="751" name="stage">
+      <Position>4</Position>
+      <DataType>String|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="799" parent="751" name="platform">
+      <Position>5</Position>
+      <DataType>String|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="800" parent="751" name="book">
+      <Position>6</Position>
+      <DataType>String|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="801" parent="751" name="view_count">
+      <Position>7</Position>
+      <DataType>Int32|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="802" parent="751" name="click_count">
+      <Position>8</Position>
+      <DataType>Int32|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="803" parent="751" name="follow_user">
+      <Position>9</Position>
+      <DataType>Int32|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="804" parent="751" name="cost">
+      <Position>10</Position>
+      <DataType>Decimal(10,4 digit)|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="805" parent="751" name="web_view_count">
+      <Position>11</Position>
+      <DataType>Int32|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="806" parent="751" name="platform_view_count">
+      <Position>12</Position>
+      <DataType>Int32|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="807" parent="751" name="web_order_count">
+      <Position>13</Position>
+      <DataType>Int32|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="808" parent="752" name="dt">
+      <Position>1</Position>
+      <DataType>Date|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="809" parent="752" name="channel">
+      <Position>2</Position>
+      <DataType>String|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="810" parent="752" name="pitcher">
+      <Position>3</Position>
+      <DataType>String|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="811" parent="752" name="stage">
+      <Position>4</Position>
+      <DataType>String|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="812" parent="752" name="platform">
+      <Position>5</Position>
+      <DataType>String|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="813" parent="752" name="book">
+      <Position>6</Position>
+      <DataType>String|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="814" parent="752" name="order_count">
+      <Position>7</Position>
+      <DataType>Int32|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="815" parent="752" name="order_user">
+      <Position>8</Position>
+      <DataType>Int32|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="816" parent="752" name="order_amount">
+      <Position>9</Position>
+      <DataType>Decimal(10,4 digit)|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="817" parent="752" name="first_order_count">
+      <Position>10</Position>
+      <DataType>Int32|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="818" parent="752" name="first_order_user">
+      <Position>11</Position>
+      <DataType>Int32|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="819" parent="752" name="first_order_amount">
+      <Position>12</Position>
+      <DataType>Decimal(10,4 digit)|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="820" parent="752" name="view_count">
+      <Position>13</Position>
+      <DataType>Int32|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="821" parent="752" name="click_count">
+      <Position>14</Position>
+      <DataType>Int32|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="822" parent="752" name="follow_user">
+      <Position>15</Position>
+      <DataType>Int32|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="823" parent="752" name="cost">
+      <Position>16</Position>
+      <DataType>Decimal(10,4 digit)|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="824" parent="752" name="reg_order_count">
+      <Position>17</Position>
+      <DataType>Int32|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="825" parent="752" name="reg_order_user">
+      <Position>18</Position>
+      <DataType>Int32|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="826" parent="752" name="reg_order_amount">
+      <Position>19</Position>
+      <DataType>Decimal(10,4 digit)|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="827" parent="752" name="reg_order_amount30">
+      <Position>20</Position>
+      <DataType>Decimal(10,4 digit)|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="828" parent="752" name="web_view_count">
+      <Position>21</Position>
+      <DataType>Int32|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="829" parent="752" name="platform_view_count">
+      <Position>22</Position>
+      <DataType>Int32|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="830" parent="752" name="web_order_count">
+      <Position>23</Position>
+      <DataType>Decimal(10,4 digit)|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="831" parent="753" name="date">
+      <Position>1</Position>
+      <DataType>Date|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="832" parent="753" name="stage">
+      <Position>2</Position>
+      <DataType>String|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="833" parent="753" name="platform">
+      <Position>3</Position>
+      <DataType>String|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="834" parent="753" name="channel">
+      <Position>4</Position>
+      <DataType>String|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="835" parent="753" name="channel_id">
+      <Position>5</Position>
+      <DataType>String|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="836" parent="753" name="user_id">
+      <Position>6</Position>
+      <DataType>String|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="837" parent="753" name="order_time">
+      <Position>7</Position>
+      <DataType>DateTime|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="838" parent="753" name="reg_time">
+      <Position>8</Position>
+      <DataType>DateTime|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="839" parent="753" name="amount">
+      <Position>9</Position>
+      <DataType>Decimal(10,2 digit)|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="840" parent="753" name="from_novel">
+      <Position>10</Position>
+      <DataType>String|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+    <column id="841" parent="753" name="order_id">
+      <Position>11</Position>
+      <DataType>String|0s</DataType>
+      <NotNull>1</NotNull>
+    </column>
+  </database-model>
+</dataSource>

+ 2 - 0
.idea/dataSources/ddcbd9b5-5958-4096-b260-7d9f40c7feb7/storage_v2/_src_/schema/system.L3Icyw.meta

@@ -0,0 +1,2 @@
+#n:system
+!<md> [null, 0, null, null, -2147483648, -2147483648]

+ 14 - 0
.idea/inspectionProfiles/Project_Default.xml

@@ -0,0 +1,14 @@
+<component name="InspectionProjectProfileManager">
+  <profile version="1.0">
+    <option name="myName" value="Project Default" />
+    <inspection_tool class="PyPackageRequirementsInspection" enabled="true" level="WARNING" enabled_by_default="true">
+      <option name="ignoredPackages">
+        <value>
+          <list size="1">
+            <item index="0" class="java.lang.String" itemvalue="numpy" />
+          </list>
+        </value>
+      </option>
+    </inspection_tool>
+  </profile>
+</component>

+ 6 - 0
.idea/inspectionProfiles/profiles_settings.xml

@@ -0,0 +1,6 @@
+<component name="InspectionProjectProfileManager">
+  <settings>
+    <option name="USE_PROJECT_PROFILE" value="false" />
+    <version value="1.0" />
+  </settings>
+</component>

+ 4 - 0
.idea/misc.xml

@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.6" project-jdk-type="Python SDK" />
+</project>

+ 8 - 0
.idea/modules.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/.idea/QcWebServer.iml" filepath="$PROJECT_DIR$/.idea/QcWebServer.iml" />
+    </modules>
+  </component>
+</project>

+ 20 - 0
Pipfile

@@ -0,0 +1,20 @@
+[[source]]
+url = "https://mirrors.aliyun.com/pypi/simple/"
+verify_ssl = true
+name = "pypi"
+
+[packages]
+pymysql = "*"
+tornado = "*"
+simplejson = "*"
+pyyaml = "*"
+torndb = "*"
+requests = "*"
+pandas = "*"
+clickhouse-driver = "*"
+numpy = "==1.19.3"
+
+[dev-packages]
+
+[requires]
+python_version = "3.6"

+ 353 - 0
Pipfile.lock

@@ -0,0 +1,353 @@
+{
+    "_meta": {
+        "hash": {
+            "sha256": "d59b814a995386d9f753871a81c428b79ef56d24cc27ac54ae4ed527d422935d"
+        },
+        "pipfile-spec": 6,
+        "requires": {
+            "python_version": "3.6"
+        },
+        "sources": [
+            {
+                "name": "pypi",
+                "url": "https://mirrors.aliyun.com/pypi/simple/",
+                "verify_ssl": true
+            }
+        ]
+    },
+    "default": {
+        "certifi": {
+            "hashes": [
+                "sha256:1a4995114262bffbc2413b159f2a1a480c969de6e6eb13ee966d470af86af59c",
+                "sha256:719a74fb9e33b9bd44cc7f3a8d94bc35e4049deebe19ba7d8e108280cfd59830"
+            ],
+            "version": "==2020.12.5"
+        },
+        "chardet": {
+            "hashes": [
+                "sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa",
+                "sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5"
+            ],
+            "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
+            "version": "==4.0.0"
+        },
+        "clickhouse-driver": {
+            "hashes": [
+                "sha256:01dfd4fbba3dee10437d4c9534159e556691b029f18860d999aef6686bc978a2",
+                "sha256:0696fcc9b4a05c926b770ab08e04b083c93abfb3f7f0316d1bce20a5894901c5",
+                "sha256:17b30703e4390366181642f7fa866853d7134134ebeb681a1776a0abe61a93cf",
+                "sha256:195656ae622901e166cde6d338d4a13a54e3a38e255793777bdf56130858eef5",
+                "sha256:1f0335d98d6a86a4f0505cd4f98f96e08906619fd8fdf6a5de05fb5ee6976521",
+                "sha256:1fdb4640166deccf8c6745970681267030064cfd7caedf79060e832f25287217",
+                "sha256:27cd2cd032b52f2cbcbaf064aa71805c70fe91247821ac91bf2ae71e224e6fd8",
+                "sha256:2b24d0e927d17ad3245044f79032058b8c3fa6dddc3192f75fdce32632073e43",
+                "sha256:2ccf58a6e1eefc4d5833b68c40716ff1294b20bd7c40a09e5d65afafade43e9d",
+                "sha256:2dda28cb424f8d449271a0eeaa6dbbfe112cfb650a3936ee2ff06359cbc7d6ad",
+                "sha256:315103ab8c10f9b1a547b7ec7c1a7a668fce8c89dfc350439949edad3d986074",
+                "sha256:51e8d9d6199f2ade571b72827a8088b46931768d7c0d67c1a4b6ad8aabff75eb",
+                "sha256:5719e9e10e64426e193042f0ba5bd4927aaeb83ed063511f8f586448b9725d89",
+                "sha256:5be3f6dda0e12553a40f71fd13fdf60c66c91452c0ec6bf513128441d0073ed0",
+                "sha256:5efb241dac6c69c9a26275c409b2a81141c993b37bb7a1ac7d9a38207276c3a4",
+                "sha256:612421bc789ec1bd4f3c0b0792a2fb9a8b97fd5138960dedba60783b5e8b28ec",
+                "sha256:62d37f93872d5a13eb6b0d52bab2b593ed0e14cf9200949aa2d02f9801064c0f",
+                "sha256:6a20570eff4119f11c5b458d4860afdcb510f5c397d9e9bd12f2bf196ebbd846",
+                "sha256:6c48ebb3be0b0cb6cb7dcfce9f8ec078f3d9ce74f86606edfc58444ee9523096",
+                "sha256:6db2322f7ecdd2481d2a3d34ac11d71fbe6b4a407a44617acbd058c92ae3a08a",
+                "sha256:7a9425f741df899453f6e8382d1d6168f1acb4d72a0ca001e23453a451dd712d",
+                "sha256:82161e12771ebcd2f9b4078f9653331aab3898b183302ae307183983d15335ff",
+                "sha256:869e3796b61aa75988a7951ce4d8365c2e382309b9a7af2d5e98213644a5ee7a",
+                "sha256:87a7fef364b510abb5344533a394ad3ec06047af28b9272087b28e6570617183",
+                "sha256:8c2d8575fa82190ffa8bd3c6d0d2a2f483a9a7eb0303d2b65404b2e4367b1c43",
+                "sha256:8fd90935d914384f39aca714b60bfa1fa59fe135dd19c99ccf8f5b1271aed78d",
+                "sha256:9055e329affa8c221479b2375a0e23cf9238cd79be66daea7bcec8b2ba60196a",
+                "sha256:929983db1d9b47d156d850e88831f5d85a8043b5ac877b6251d79491afb05ba4",
+                "sha256:96dc46adc6e2441d4f76b401f38bc57de7dd810a5fb8604767d96a2d239f6634",
+                "sha256:97d0f3e0094bfad555a83d6c6efef4ca14607cf045ae0124933578f2ccdfcd4e",
+                "sha256:9fc14485e178186c27107a12805640000b7973d6756f1675a46478d6e9734920",
+                "sha256:9fef38a3d23a9c2d4f5fac2227bfb2fbe606138506aa10a4a2b563b879b995d5",
+                "sha256:a88fad262d2b833e073eaeca3d054cdbbf06ec78a1f1b0e978420f53ba42b90e",
+                "sha256:a904f4c04011a90419f4488f607f1fcf973814b0f9f6f93ca0015578922cc0e4",
+                "sha256:ac2410ef71e72cc67585260c18587693f4dad4fc288d7bf4850649eaf0eef1fa",
+                "sha256:b1a13fc73faba77aec75101e190d22253b125e08c3abd5cb1b8727fa4e4b8e67",
+                "sha256:b55aa541eb2ebcbcbd25df5203942f19d778efbc7ec43c33f0620d0347d87e04",
+                "sha256:b6f62c226cbfaa6fd336ca5d80898f0100ea116e67cacd94fa0967afc60c6b0f",
+                "sha256:c454a9053feb8b4fd21af24a79128d87662a49dbaaa2d5eb612d29d3f139d3ae",
+                "sha256:cedc6fb30303012fbb5dec6605ea7694784d806291958367984fe1a333aff687",
+                "sha256:cf015d17c9c8369d75310c4388c832300b311004180849eea342a282e09c0111",
+                "sha256:d3195c9f5343149dfffd729daac72e0ca7030c87a10ba2cbb41df7348e547eed",
+                "sha256:d4a6f63bde2bab0c0beb0a47bb3318cdfe34398298e0a94f5f3588e460376b90",
+                "sha256:d5c5aecc58a8b71492368ebd1adb3016e122692e8a31b2ea3aa219c6a4e224a3",
+                "sha256:dcce87611c7f75671a768e83ac51e6ad1363199fe0bf7f74b7babb5254426e3e",
+                "sha256:de0142b1600e2cf76de708c96eaad583b01249911300ff7ac83ef8e643062a7e",
+                "sha256:ec863a80600a9c7d8cab60e1bc051b0fa525e712a141cb66c6e6a66cf83faa74",
+                "sha256:edbdcbb7c32e0efb1eda143b21383172e2d709837c2d09e036edcf41b770df8e",
+                "sha256:eed8f7214751c870624d68c30ac9f2233fbeee300caae1748b0f86501314cc61",
+                "sha256:f3bb0128d72db0081fbaba1acb852ecb8ed9ee8983c5b57556e3bdcb45fe487c",
+                "sha256:f415be3571967ca42a4c2836826b203030c53e739b9e2b4a79ed213706ef6924",
+                "sha256:f69cd1a0981c257e48ae0f4bc602632e0b5fa24aa163d3042337f04db75d29e3",
+                "sha256:f789ed03d1c7aefc6e7a626c51fec9048efc076d0326751614b48a0857331b99",
+                "sha256:fc4aaa52208d9e185b912f0e640184d87db03427bfb8694d420d0ded73903b5a",
+                "sha256:fe8575cc809a6703d065e29aebe88b265e4ed435c2fdfd18353f6ab2d08ca650",
+                "sha256:ff53cc75ab9bacb55b8a5e7215f7c073bff7974b3f3c9cd96a9c02ece1e62019"
+            ],
+            "index": "pypi",
+            "version": "==0.2.0"
+        },
+        "idna": {
+            "hashes": [
+                "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6",
+                "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0"
+            ],
+            "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
+            "version": "==2.10"
+        },
+        "numpy": {
+            "hashes": [
+                "sha256:0ee77786eebbfa37f2141fd106b549d37c89207a0d01d8852fde1c82e9bfc0e7",
+                "sha256:199bebc296bd8a5fc31c16f256ac873dd4d5b4928dfd50e6c4995570fc71a8f3",
+                "sha256:1a307bdd3dd444b1d0daa356b5f4c7de2e24d63bdc33ea13ff718b8ec4c6a268",
+                "sha256:1ea7e859f16e72ab81ef20aae69216cfea870676347510da9244805ff9670170",
+                "sha256:271139653e8b7a046d11a78c0d33bafbddd5c443a5b9119618d0652a4eb3a09f",
+                "sha256:35bf5316af8dc7c7db1ad45bec603e5fb28671beb98ebd1d65e8059efcfd3b72",
+                "sha256:463792a249a81b9eb2b63676347f996d3f0082c2666fd0604f4180d2e5445996",
+                "sha256:50d3513469acf5b2c0406e822d3f314d7ac5788c2b438c24e5dd54d5a81ef522",
+                "sha256:50f68ebc439821b826823a8da6caa79cd080dee2a6d5ab9f1163465a060495ed",
+                "sha256:51e8d2ae7c7e985c7bebf218e56f72fa93c900ad0c8a7d9fbbbf362f45710f69",
+                "sha256:522053b731e11329dd52d258ddf7de5288cae7418b55e4b7d32f0b7e31787e9d",
+                "sha256:5ea4401ada0d3988c263df85feb33818dc995abc85b8125f6ccb762009e7bc68",
+                "sha256:604d2e5a31482a3ad2c88206efd43d6fcf666ada1f3188fd779b4917e49b7a98",
+                "sha256:6ff88bcf1872b79002569c63fe26cd2cda614e573c553c4d5b814fb5eb3d2822",
+                "sha256:7197ee0a25629ed782c7bd01871ee40702ffeef35bc48004bc2fdcc71e29ba9d",
+                "sha256:741d95eb2b505bb7a99fbf4be05fa69f466e240c2b4f2d3ddead4f1b5f82a5a5",
+                "sha256:83af653bb92d1e248ccf5fdb05ccc934c14b936bcfe9b917dc180d3f00250ac6",
+                "sha256:8802d23e4895e0c65e418abe67cdf518aa5cbb976d97f42fd591f921d6dffad0",
+                "sha256:8edc4d687a74d0a5f8b9b26532e860f4f85f56c400b3a98899fc44acb5e27add",
+                "sha256:942d2cdcb362739908c26ce8dd88db6e139d3fa829dd7452dd9ff02cba6b58b2",
+                "sha256:9a0669787ba8c9d3bb5de5d9429208882fb47764aa79123af25c5edc4f5966b9",
+                "sha256:9d08d84bb4128abb9fbd9f073e5c69f70e5dab991a9c42e5b4081ea5b01b5db0",
+                "sha256:9f7f56b5e85b08774939622b7d45a5d00ff511466522c44fc0756ac7692c00f2",
+                "sha256:a2daea1cba83210c620e359de2861316f49cc7aea8e9a6979d6cb2ddab6dda8c",
+                "sha256:b9074d062d30c2779d8af587924f178a539edde5285d961d2dfbecbac9c4c931",
+                "sha256:c4aa79993f5d856765819a3651117520e41ac3f89c3fc1cb6dee11aa562df6da",
+                "sha256:d78294f1c20f366cde8a75167f822538a7252b6e8b9d6dbfb3bdab34e7c1929e",
+                "sha256:dfdc8b53aa9838b9d44ed785431ca47aa3efaa51d0d5dd9c412ab5247151a7c4",
+                "sha256:dffed17848e8b968d8d3692604e61881aa6ef1f8074c99e81647ac84f6038535",
+                "sha256:e080087148fd70469aade2abfeadee194357defd759f9b59b349c6192aba994c",
+                "sha256:e983cbabe10a8989333684c98fdc5dd2f28b236216981e0c26ed359aaa676772",
+                "sha256:ea6171d2d8d648dee717457d0f75db49ad8c2f13100680e284d7becf3dc311a6",
+                "sha256:eefc13863bf01583a85e8c1121a901cc7cb8f059b960c4eba30901e2e6aba95f",
+                "sha256:efd656893171bbf1331beca4ec9f2e74358fc732a2084f664fd149cc4b3441d2"
+            ],
+            "index": "pypi",
+            "version": "==1.19.3"
+        },
+        "pandas": {
+            "hashes": [
+                "sha256:0a643bae4283a37732ddfcecab3f62dd082996021b980f580903f4e8e01b3c5b",
+                "sha256:0de3ddb414d30798cbf56e642d82cac30a80223ad6fe484d66c0ce01a84d6f2f",
+                "sha256:19a2148a1d02791352e9fa637899a78e371a3516ac6da5c4edc718f60cbae648",
+                "sha256:21b5a2b033380adbdd36b3116faaf9a4663e375325831dac1b519a44f9e439bb",
+                "sha256:24c7f8d4aee71bfa6401faeba367dd654f696a77151a8a28bc2013f7ced4af98",
+                "sha256:26fa92d3ac743a149a31b21d6f4337b0594b6302ea5575b37af9ca9611e8981a",
+                "sha256:2860a97cbb25444ffc0088b457da0a79dc79f9c601238a3e0644312fcc14bf11",
+                "sha256:2b1c6cd28a0dfda75c7b5957363333f01d370936e4c6276b7b8e696dd500582a",
+                "sha256:2c2f7c670ea4e60318e4b7e474d56447cf0c7d83b3c2a5405a0dbb2600b9c48e",
+                "sha256:3be7a7a0ca71a2640e81d9276f526bca63505850add10206d0da2e8a0a325dae",
+                "sha256:4c62e94d5d49db116bef1bd5c2486723a292d79409fc9abd51adf9e05329101d",
+                "sha256:5008374ebb990dad9ed48b0f5d0038124c73748f5384cc8c46904dace27082d9",
+                "sha256:5447ea7af4005b0daf695a316a423b96374c9c73ffbd4533209c5ddc369e644b",
+                "sha256:573fba5b05bf2c69271a32e52399c8de599e4a15ab7cec47d3b9c904125ab788",
+                "sha256:5a780260afc88268a9d3ac3511d8f494fdcf637eece62fb9eb656a63d53eb7ca",
+                "sha256:70865f96bb38fec46f7ebd66d4b5cfd0aa6b842073f298d621385ae3898d28b5",
+                "sha256:731568be71fba1e13cae212c362f3d2ca8932e83cb1b85e3f1b4dd77d019254a",
+                "sha256:b61080750d19a0122469ab59b087380721d6b72a4e7d962e4d7e63e0c4504814",
+                "sha256:bf23a3b54d128b50f4f9d4675b3c1857a688cc6731a32f931837d72effb2698d",
+                "sha256:c16d59c15d946111d2716856dd5479221c9e4f2f5c7bc2d617f39d870031e086",
+                "sha256:c61c043aafb69329d0f961b19faa30b1dab709dd34c9388143fc55680059e55a",
+                "sha256:c94ff2780a1fd89f190390130d6d36173ca59fcfb3fe0ff596f9a56518191ccb",
+                "sha256:edda9bacc3843dfbeebaf7a701763e68e741b08fccb889c003b0a52f0ee95782",
+                "sha256:f10fc41ee3c75a474d3bdf68d396f10782d013d7f67db99c0efbfd0acb99701b"
+            ],
+            "index": "pypi",
+            "version": "==1.1.5"
+        },
+        "pymysql": {
+            "hashes": [
+                "sha256:263040d2779a3b84930f7ac9da5132be0fefcd6f453a885756656103f8ee1fdd",
+                "sha256:44f47128dda8676e021c8d2dbb49a82be9e4ab158b9f03e897152a3a287c69ea"
+            ],
+            "index": "pypi",
+            "version": "==0.10.1"
+        },
+        "python-dateutil": {
+            "hashes": [
+                "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c",
+                "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"
+            ],
+            "version": "==2.8.1"
+        },
+        "pytz": {
+            "hashes": [
+                "sha256:3e6b7dd2d1e0a59084bcee14a17af60c5c562cdc16d828e8eba2e683d3a7e268",
+                "sha256:5c55e189b682d420be27c6995ba6edce0c0a77dd67bfbe2ae6607134d5851ffd"
+            ],
+            "version": "==2020.4"
+        },
+        "pyyaml": {
+            "hashes": [
+                "sha256:06a0d7ba600ce0b2d2fe2e78453a470b5a6e000a985dd4a4e54e436cc36b0e97",
+                "sha256:240097ff019d7c70a4922b6869d8a86407758333f02203e0fc6ff79c5dcede76",
+                "sha256:4f4b913ca1a7319b33cfb1369e91e50354d6f07a135f3b901aca02aa95940bd2",
+                "sha256:6034f55dab5fea9e53f436aa68fa3ace2634918e8b5994d82f3621c04ff5ed2e",
+                "sha256:69f00dca373f240f842b2931fb2c7e14ddbacd1397d57157a9b005a6a9942648",
+                "sha256:73f099454b799e05e5ab51423c7bcf361c58d3206fa7b0d555426b1f4d9a3eaf",
+                "sha256:74809a57b329d6cc0fdccee6318f44b9b8649961fa73144a98735b0aaf029f1f",
+                "sha256:7739fc0fa8205b3ee8808aea45e968bc90082c10aef6ea95e855e10abf4a37b2",
+                "sha256:95f71d2af0ff4227885f7a6605c37fd53d3a106fcab511b8860ecca9fcf400ee",
+                "sha256:ad9c67312c84def58f3c04504727ca879cb0013b2517c85a9a253f0cb6380c0a",
+                "sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d",
+                "sha256:cc8955cfbfc7a115fa81d85284ee61147059a753344bc51098f3ccd69b0d7e0c",
+                "sha256:d13155f591e6fcc1ec3b30685d50bf0711574e2c0dfffd7644babf8b5102ca1a"
+            ],
+            "index": "pypi",
+            "version": "==5.3.1"
+        },
+        "requests": {
+            "hashes": [
+                "sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804",
+                "sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e"
+            ],
+            "index": "pypi",
+            "version": "==2.25.1"
+        },
+        "simplejson": {
+            "hashes": [
+                "sha256:034550078a11664d77bc1a8364c90bb7eef0e44c2dbb1fd0a4d92e3997088667",
+                "sha256:05b43d568300c1cd43f95ff4bfcff984bc658aa001be91efb3bb21df9d6288d3",
+                "sha256:0dd9d9c738cb008bfc0862c9b8fa6743495c03a0ed543884bf92fb7d30f8d043",
+                "sha256:10fc250c3edea4abc15d930d77274ddb8df4803453dde7ad50c2f5565a18a4bb",
+                "sha256:2862beabfb9097a745a961426fe7daf66e1714151da8bb9a0c430dde3d59c7c0",
+                "sha256:292c2e3f53be314cc59853bd20a35bf1f965f3bc121e007ab6fd526ed412a85d",
+                "sha256:2d3eab2c3fe52007d703a26f71cf649a8c771fcdd949a3ae73041ba6797cfcf8",
+                "sha256:2e7b57c2c146f8e4dadf84977a83f7ee50da17c8861fd7faf694d55e3274784f",
+                "sha256:311f5dc2af07361725033b13cc3d0351de3da8bede3397d45650784c3f21fbcf",
+                "sha256:344e2d920a7f27b4023c087ab539877a1e39ce8e3e90b867e0bfa97829824748",
+                "sha256:3fabde09af43e0cbdee407555383063f8b45bfb52c361bc5da83fcffdb4fd278",
+                "sha256:42b8b8dd0799f78e067e2aaae97e60d58a8f63582939af60abce4c48631a0aa4",
+                "sha256:4b3442249d5e3893b90cb9f72c7d6ce4d2ea144d2c0d9f75b9ae1e5460f3121a",
+                "sha256:55d65f9cc1b733d85ef95ab11f559cce55c7649a2160da2ac7a078534da676c8",
+                "sha256:5c659a0efc80aaaba57fcd878855c8534ecb655a28ac8508885c50648e6e659d",
+                "sha256:72d8a3ffca19a901002d6b068cf746be85747571c6a7ba12cbcf427bfb4ed971",
+                "sha256:75ecc79f26d99222a084fbdd1ce5aad3ac3a8bd535cd9059528452da38b68841",
+                "sha256:76ac9605bf2f6d9b56abf6f9da9047a8782574ad3531c82eae774947ae99cc3f",
+                "sha256:7d276f69bfc8c7ba6c717ba8deaf28f9d3c8450ff0aa8713f5a3280e232be16b",
+                "sha256:7f10f8ba9c1b1430addc7dd385fc322e221559d3ae49b812aebf57470ce8de45",
+                "sha256:8042040af86a494a23c189b5aa0ea9433769cc029707833f261a79c98e3375f9",
+                "sha256:813846738277729d7db71b82176204abc7fdae2f566e2d9fcf874f9b6472e3e6",
+                "sha256:845a14f6deb124a3bcb98a62def067a67462a000e0508f256f9c18eff5847efc",
+                "sha256:869a183c8e44bc03be1b2bbcc9ec4338e37fa8557fc506bf6115887c1d3bb956",
+                "sha256:8acf76443cfb5c949b6e781c154278c059b09ac717d2757a830c869ba000cf8d",
+                "sha256:8f713ea65958ef40049b6c45c40c206ab363db9591ff5a49d89b448933fa5746",
+                "sha256:934115642c8ba9659b402c8bdbdedb48651fb94b576e3b3efd1ccb079609b04a",
+                "sha256:9551f23e09300a9a528f7af20e35c9f79686d46d646152a0c8fc41d2d074d9b0",
+                "sha256:9a2b7543559f8a1c9ed72724b549d8cc3515da7daf3e79813a15bdc4a769de25",
+                "sha256:a55c76254d7cf8d4494bc508e7abb993a82a192d0db4552421e5139235604625",
+                "sha256:ad8f41c2357b73bc9e8606d2fa226233bf4d55d85a8982ecdfd55823a6959995",
+                "sha256:af4868da7dd53296cd7630687161d53a7ebe2e63814234631445697bd7c29f46",
+                "sha256:afebfc3dd3520d37056f641969ce320b071bc7a0800639c71877b90d053e087f",
+                "sha256:b59aa298137ca74a744c1e6e22cfc0bf9dca3a2f41f51bc92eb05695155d905a",
+                "sha256:bc00d1210567a4cdd215ac6e17dc00cb9893ee521cee701adfd0fa43f7c73139",
+                "sha256:c1cb29b1fced01f97e6d5631c3edc2dadb424d1f4421dad079cb13fc97acb42f",
+                "sha256:c94dc64b1a389a416fc4218cd4799aa3756f25940cae33530a4f7f2f54f166da",
+                "sha256:ceaa28a5bce8a46a130cd223e895080e258a88d51bf6e8de2fc54a6ef7e38c34",
+                "sha256:cff6453e25204d3369c47b97dd34783ca820611bd334779d22192da23784194b",
+                "sha256:d0b64409df09edb4c365d95004775c988259efe9be39697d7315c42b7a5e7e94",
+                "sha256:d4813b30cb62d3b63ccc60dd12f2121780c7a3068db692daeb90f989877aaf04",
+                "sha256:da3c55cdc66cfc3fffb607db49a42448785ea2732f055ac1549b69dcb392663b",
+                "sha256:e058c7656c44fb494a11443191e381355388443d543f6fc1a245d5d238544396",
+                "sha256:fed0f22bf1313ff79c7fc318f7199d6c2f96d4de3234b2f12a1eab350e597c06",
+                "sha256:ffd4e4877a78c84d693e491b223385e0271278f5f4e1476a4962dca6824ecfeb"
+            ],
+            "index": "pypi",
+            "version": "==3.17.2"
+        },
+        "six": {
+            "hashes": [
+                "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259",
+                "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"
+            ],
+            "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
+            "version": "==1.15.0"
+        },
+        "tornado": {
+            "hashes": [
+                "sha256:0a00ff4561e2929a2c37ce706cb8233b7907e0cdc22eab98888aca5dd3775feb",
+                "sha256:0d321a39c36e5f2c4ff12b4ed58d41390460f798422c4504e09eb5678e09998c",
+                "sha256:1e8225a1070cd8eec59a996c43229fe8f95689cb16e552d130b9793cb570a288",
+                "sha256:20241b3cb4f425e971cb0a8e4ffc9b0a861530ae3c52f2b0434e6c1b57e9fd95",
+                "sha256:25ad220258349a12ae87ede08a7b04aca51237721f63b1808d39bdb4b2164558",
+                "sha256:33892118b165401f291070100d6d09359ca74addda679b60390b09f8ef325ffe",
+                "sha256:33c6e81d7bd55b468d2e793517c909b139960b6c790a60b7991b9b6b76fb9791",
+                "sha256:3447475585bae2e77ecb832fc0300c3695516a47d46cefa0528181a34c5b9d3d",
+                "sha256:34ca2dac9e4d7afb0bed4677512e36a52f09caa6fded70b4e3e1c89dbd92c326",
+                "sha256:3e63498f680547ed24d2c71e6497f24bca791aca2fe116dbc2bd0ac7f191691b",
+                "sha256:548430be2740e327b3fe0201abe471f314741efcb0067ec4f2d7dcfb4825f3e4",
+                "sha256:6196a5c39286cc37c024cd78834fb9345e464525d8991c21e908cc046d1cc02c",
+                "sha256:61b32d06ae8a036a6607805e6720ef00a3c98207038444ba7fd3d169cd998910",
+                "sha256:6286efab1ed6e74b7028327365cf7346b1d777d63ab30e21a0f4d5b275fc17d5",
+                "sha256:65d98939f1a2e74b58839f8c4dab3b6b3c1ce84972ae712be02845e65391ac7c",
+                "sha256:66324e4e1beede9ac79e60f88de548da58b1f8ab4b2f1354d8375774f997e6c0",
+                "sha256:6c77c9937962577a6a76917845d06af6ab9197702a42e1346d8ae2e76b5e3675",
+                "sha256:70dec29e8ac485dbf57481baee40781c63e381bebea080991893cd297742b8fd",
+                "sha256:7250a3fa399f08ec9cb3f7b1b987955d17e044f1ade821b32e5f435130250d7f",
+                "sha256:748290bf9112b581c525e6e6d3820621ff020ed95af6f17fedef416b27ed564c",
+                "sha256:7da13da6f985aab7f6f28debab00c67ff9cbacd588e8477034c0652ac141feea",
+                "sha256:8f959b26f2634a091bb42241c3ed8d3cedb506e7c27b8dd5c7b9f745318ddbb6",
+                "sha256:9de9e5188a782be6b1ce866e8a51bc76a0fbaa0e16613823fc38e4fc2556ad05",
+                "sha256:a48900ecea1cbb71b8c71c620dee15b62f85f7c14189bdeee54966fbd9a0c5bd",
+                "sha256:b87936fd2c317b6ee08a5741ea06b9d11a6074ef4cc42e031bc6403f82a32575",
+                "sha256:c77da1263aa361938476f04c4b6c8916001b90b2c2fdd92d8d535e1af48fba5a",
+                "sha256:cb5ec8eead331e3bb4ce8066cf06d2dfef1bfb1b2a73082dfe8a161301b76e37",
+                "sha256:cc0ee35043162abbf717b7df924597ade8e5395e7b66d18270116f8745ceb795",
+                "sha256:d14d30e7f46a0476efb0deb5b61343b1526f73ebb5ed84f23dc794bdb88f9d9f",
+                "sha256:d371e811d6b156d82aa5f9a4e08b58debf97c302a35714f6f45e35139c332e32",
+                "sha256:d3d20ea5782ba63ed13bc2b8c291a053c8d807a8fa927d941bd718468f7b950c",
+                "sha256:d3f7594930c423fd9f5d1a76bee85a2c36fd8b4b16921cae7e965f22575e9c01",
+                "sha256:dcef026f608f678c118779cd6591c8af6e9b4155c44e0d1bc0c87c036fb8c8c4",
+                "sha256:e0791ac58d91ac58f694d8d2957884df8e4e2f6687cdf367ef7eb7497f79eaa2",
+                "sha256:e385b637ac3acaae8022e7e47dfa7b83d3620e432e3ecb9a3f7f58f150e50921",
+                "sha256:e519d64089b0876c7b467274468709dadf11e41d65f63bba207e04217f47c085",
+                "sha256:e7229e60ac41a1202444497ddde70a48d33909e484f96eb0da9baf8dc68541df",
+                "sha256:ed3ad863b1b40cd1d4bd21e7498329ccaece75db5a5bf58cd3c9f130843e7102",
+                "sha256:f0ba29bafd8e7e22920567ce0d232c26d4d47c8b5cf4ed7b562b5db39fa199c5",
+                "sha256:fa2ba70284fa42c2a5ecb35e322e68823288a4251f9ba9cc77be04ae15eada68",
+                "sha256:fba85b6cd9c39be262fcd23865652920832b61583de2a2ca907dbd8e8a8c81e5"
+            ],
+            "index": "pypi",
+            "version": "==6.1"
+        },
+        "torndb": {
+            "hashes": [
+                "sha256:0ba8f67058216b89f8ffddaee24a71d525dea61518078bd6f3d7911b3a8883d7"
+            ],
+            "index": "pypi",
+            "version": "==0.3"
+        },
+        "tzlocal": {
+            "hashes": [
+                "sha256:643c97c5294aedc737780a49d9df30889321cbe1204eac2c2ec6134035a92e44",
+                "sha256:e2cb6c6b5b604af38597403e9852872d7f534962ae2954c7f35efcb1ccacf4a4"
+            ],
+            "version": "==2.1"
+        },
+        "urllib3": {
+            "hashes": [
+                "sha256:19188f96923873c92ccb987120ec4acaa12f0461fa9ce5d3d0772bc965a39e08",
+                "sha256:d8ff90d979214d7b4f8ce956e80f4028fc6860e4431f731ea4a8c08f23f99473"
+            ],
+            "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4'",
+            "version": "==1.26.2"
+        }
+    },
+    "develop": {}
+}

+ 2 - 0
README.markdown

@@ -0,0 +1,2 @@
+netstat -ano | findstr 8008
+taskkill -PID {pid} -F

+ 48 - 0
ServerWrapper.py

@@ -0,0 +1,48 @@
+import os
+import tornado.gen
+import tornado.httpclient
+import tornado.httpserver
+import tornado.ioloop
+import tornado.options
+import tornado.web
+from tornado.options import define, options
+from model.common.file_pid import PID
+from urls import urls
+from model.log import logger
+log = logger()
+
+
+iTime = 300
+
+define("port", default=8008, help="run on the given port", type=int)
+
+
+class HttpServerWrapper(tornado.web.Application):
+    def __init__(self, port=80,debug=True):
+        self.port = port
+        handlers = urls
+        settings = {
+            "cookie_secret": "",
+            "login_url": "",
+            "autoreload": True,
+            "debug": False,
+            "allow_remote_access": True,
+            "template_path": os.path.join(os.path.dirname(__file__), "templates"),
+            "static_path": os.path.join(os.path.dirname(__file__), "templates")
+        }
+        super(HttpServerWrapper, self).__init__(handlers, **settings)
+
+
+def main():
+
+    PID.write()
+    tornado.options.parse_command_line()
+    http_server = tornado.httpserver.HTTPServer(HttpServerWrapper())
+    http_server.listen(options.port)
+    log.info("server start, listening on port %s" % options.port)
+    tornado.ioloop.IOLoop.current().start()
+
+
+if __name__ == '__main__':
+    main()
+

BIN
__pycache__/urls.cpython-36.pyc


+ 13 - 0
config/__init__.py

@@ -0,0 +1,13 @@
+"""
+@desc 本地环境用【test】
+      生产环境用【product】
+@auth chenkai
+@date 2019/10/8
+"""
+# import socket
+# from . import product, test
+# ip = socket.gethostbyname(socket.gethostname())
+# if ip.startswith("192"):
+#     product = test
+# else:
+#     product = product

+ 6 - 0
config/db_config.yaml

@@ -0,0 +1,6 @@
+quchen_text:
+  host: rm-bp1c9cj79872tx3aaro.mysql.rds.aliyuncs.com
+  user: superc
+  passwd: Cc719199895
+  db: quchen_text
+

+ 0 - 0
config/global_config.yaml


+ 0 - 0
data_manage/__init__.py


BIN
data_manage/__pycache__/__init__.cpython-36.pyc


BIN
data_manage/__pycache__/pitcher_panel.cpython-36.pyc


+ 90 - 0
data_manage/pitcher_panel.py

@@ -0,0 +1,90 @@
+from model.DateUtils import DateUtils
+from model.DataBaseUtils import *
+from model.log import logger
+from model.CommonUtils import *
+du = DateUtils()
+ck = CkUtils()
+db = MysqlUtils()
+log = logger()
+
+
+def get_pitcher_panel_channel(pitcher,channel,start,end,page,page_size,order_by,order):
+    sql=f"""select channel,stage,platform,book,formatDateTime(dt,'%Y-%m-%d') as date,cost,first_order_amount,
+           if(cost=0,0,round(first_order_amount/cost,4)) first_roi,
+           first_order_user,first_order_count,
+           if(first_order_user=0,0,round(cost/first_order_user,2)) first_per_cost,
+           view_count,click_count,follow_user,
+           if(click_count=0,0,round(follow_user/click_count,4)) follow_rate,
+           if(follow_user=0,0,round(cost/follow_user,2)) follow_per_cost,
+            total_cost,
+           if(total_cost=0,0,round(total_amount/total_cost,4)) back_rate
+    
+           from dw_daily_channel where dt>='{start}' and dt<='{end}'  """
+    if pitcher!='all':
+        sql += f" and pitcher='{pitcher}' "
+
+    if channel!='':
+        sql += f" and channel='{channel}' "
+
+    sql += f" order by {order_by} {order} limit {page},{page_size} "
+
+    print(sql)
+    data=ck.execute(sql)
+    key=['channel','stage','platform','book','date','cost','first_order_amount','first_roi','first_order_user',
+         'first_order_count','first_per_cost','view_count','click_count','follow_user','follow_rate','follow_per_cost',
+         'total_cost','back_rate']
+
+    return get_dict_list(key, data)
+
+
+
+
+
+def get_pitcher_panel_daily(pitcher, start, end, page, page_size, order_by, order):
+    sql=f"""
+        select formatDateTime(dt,'%Y-%m-%d') date ,pitcher,
+               round(sum(cost),2) cost,
+                round(sum(first_order_amount),2) first_order_amount,
+               if(cost=0,0,round(first_order_amount/cost,4)) first_roi ,
+               round(sum(order_amount),2) order_amount,
+               if(cost=0,0,round(sum(reg_order_amount)/cost,4))  today_roi,
+               round(sum(total_cost),2) total_cost,
+               round(sum(total_amount),2) total_amount,
+               total_amount-total_cost total_profit,
+               if(total_cost=0,0,round(total_amount/total_cost,4)) total_roi
+               from dw_daily_channel  where dt>='{start}' and dt<='{end}' """
+
+    if pitcher != 'all':
+        sql += f" and pitcher='{pitcher}' "
+
+    sql += f" group by date,pitcher order by {order_by} {order} limit {page},{page_size} "
+    print(sql)
+    data = ck.execute(sql)
+    key=['date','pitcher','cost','first_order_amount','first_roi','order_amount','today_roi','total_cost','total_amount','total_profit','total_roi']
+    return get_dict_list(key,data)
+
+def get_pitcher_panel_overview(pitcher):
+
+    sql=f"""select  pitcher,cost,amount,roi, 
+       channel_count,on_channel_count,
+       off_channel_count,
+       this_month_cost,
+       this_month_amount,
+   this_month_roi,
+    last_month_cost,
+    last_month_amount,
+     last_month_roi,
+    last_month_far_amount,
+       follow_user
+       from  dm_pitcher_daily_page_total where  dt='{du.get_n_days(-1)}'"""
+
+    if pitcher != 'all':
+        sql += f" and pitcher='{pitcher}' "
+
+    print(sql)
+    data=ck.execute(sql)
+    print(data)
+
+    key=['pitcher','cost','amount','roi','channel_count','on_channel_count','off_channel_count','this_month_cost','this_month_amount','this_month_roi',
+         'last_month_cost','last_month_amount','last_month_roi','last_month_far_amount','follow_user']
+    return get_dict_list(key,data)

+ 65 - 0
handlers/HandlerBase.py

@@ -0,0 +1,65 @@
+import simplejson as json
+import traceback
+from datetime import date
+from concurrent.futures import ThreadPoolExecutor
+from tornado.web import RequestHandler
+from model.log import logger
+from model.common import errors
+log = logger()
+
+
+class BaseHandler(RequestHandler):
+    def __init__(self, application, request, **kwargs):
+        RequestHandler.__init__(self, application, request, **kwargs)
+        self._status_code = 200
+        self.executor = ThreadPoolExecutor(200)
+        if self.settings['allow_remote_access']:
+            self.access_control_allow()
+
+
+    def access_control_allow(self):
+        self.set_header('Content-Type','application/json')
+        self.set_header("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE,OPTIONS")
+        self.set_header("Access-Control-Allow-Headers", "Content-Type, Depth, User-Agent, Token, Origin, X-Requested-With, Accept, Authorization, admin_id")
+        self.set_header('Access-Control-Allow-Origin', "*")
+
+    def write_json(self, data, status_code=200, msg='success'):
+        self.write(json.dumps({'status': {'msg': msg, "RetCode": status_code}, 'data': data}))
+
+
+    def write_error(self, status_code, msg=None, **kwargs):
+
+        if self.settings.get("serve_traceback") and "exc_info" in kwargs:
+            # in debug mode, try to send a traceback
+            lines = []
+            for line in traceback.format_exception(*kwargs["exc_info"]):
+                lines.append(line)
+
+            self.write_json(dict(traceback=''.join(lines)), status_code, self._reason)
+
+        elif msg:
+            self.write_json(None, status_code, msg)
+        else:
+            self.write_json(None, status_code, self._reason)
+
+    def _authentication(self):
+        """
+        :return: True, 认证通过, False 认证不通过
+        """
+        return True
+        log.info("author %s" % self.request.headers)
+        # log.info(self.request.remote_ip)
+        if self.request.headers.get("Gip_real") == '183.129.168.74':
+            return True
+
+        if not self.request.headers.get("Authorization"):
+
+            return False
+        else:
+            # redis 中判断值是否存在
+            # ur = UserRedisComm()
+            # key = "admin_account_check%s" % (self.request.headers.get("Authorization"))
+            # return True if ur.r.get(key) else False
+            return True
+
+

+ 49 - 0
handlers/PitcherPanel.py

@@ -0,0 +1,49 @@
+from handlers.HandlerBase import BaseHandler
+from model.log import logger
+from data_manage.pitcher_panel import *
+log = logger()
+
+
+class PitcherPanelChannel(BaseHandler):
+
+    def post(self):
+        pitcher = self.get_argument("pitcher", '')
+        channel = self.get_argument("channel", '')
+        start = self.get_argument("start", du.get_n_days(-1))
+        end = self.get_argument("end", du.get_n_days(-1))
+        date_range = self.get_argument("date_range", '')
+        page = self.get_argument("page",'1')
+        page_size = self.get_argument("page_size",'10')
+        order_by=self.get_argument("order_by",'date')
+        order=self.get_argument("order", 'desc')
+        if date_range!='':
+            end=du.get_n_days(-1)
+            start=du.get_n_days(-int(date_range))
+
+        data=get_pitcher_panel_channel(pitcher, channel, start, end, page, page_size, order_by, order)
+        self.write_json(data)
+
+
+class PitcherPanelDaily(BaseHandler):
+    def post(self):
+        pitcher = self.get_argument("pitcher", '')
+        start = self.get_argument("start", du.get_n_days(-1))
+        end = self.get_argument("end", du.get_n_days(-1))
+        date_range = self.get_argument("date_range", '')
+        page = self.get_argument("page", '1')
+        page_size = self.get_argument("page_size", '10')
+        order_by = self.get_argument("order_by", 'date')
+        order = self.get_argument("order", 'desc')
+        if date_range != '':
+            end = du.get_n_days(-1)
+            start = du.get_n_days(-int(date_range))
+
+        data = get_pitcher_panel_daily(pitcher, start, end, page, page_size, order_by, order)
+        self.write_json(data)
+
+
+class PitcherPanelOverview(BaseHandler):
+    def post(self):
+        pitcher = self.get_argument("pitcher", '')
+        data = get_pitcher_panel_overview(pitcher)
+        self.write_json(data)

+ 0 - 0
handlers/__init__.py


BIN
handlers/__pycache__/HandlerBase.cpython-36.pyc


BIN
handlers/__pycache__/PitcherPanel.cpython-36.pyc


BIN
handlers/__pycache__/__init__.cpython-36.pyc


+ 485 - 0
logs/runlog20201223.log

@@ -0,0 +1,485 @@
+[2020-12-23 19:17:32,948] - [INFO] - write pid 5464 ...
+[2020-12-23 19:17:32,954] - [INFO] - server start, listening on port 8008
+[2020-12-23 19:17:37,549] - [ERROR] - Uncaught exception POST /data/pitcher_panel/channel (::1)
+HTTPServerRequest(protocol='http', host='localhost:8008', method='POST', uri='/data/pitcher_panel/channel', version='HTTP/1.1', remote_ip='::1')
+Traceback (most recent call last):
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\tornado\web.py", line 1702, in _execute
+    result = method(*self.path_args, **self.path_kwargs)
+  File "D:\code\QcWebServer\handlers\PitcherPanel.py", line 24, in post
+    data=get_pitcher_panel_channel(pitcher, channel, start, end, page, page_size, order_by, order)
+  File "D:\code\QcWebServer\data_manage\pitcher_panel.py", line 31, in get_pitcher_panel_channel
+    data=ck.execute(sql)
+  File "D:\code\QcWebServer\model\DataBaseUtils.py", line 61, in execute
+    return self.client.execute(sql)
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\clickhouse_driver\client.py", line 252, in execute
+    columnar=columnar
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\clickhouse_driver\client.py", line 447, in process_ordinary_query
+    columnar=columnar)
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\clickhouse_driver\client.py", line 113, in receive_result
+    return result.get_result()
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\clickhouse_driver\result.py", line 50, in get_result
+    for packet in self.packet_generator:
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\clickhouse_driver\client.py", line 129, in packet_generator
+    packet = self.receive_packet()
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\clickhouse_driver\client.py", line 146, in receive_packet
+    raise packet.exception
+clickhouse_driver.errors.ServerException: Code: 62.
+DB::Exception: Syntax error: failed at position 605 (line 11, col 44): dt>='2020-12-22' and dt<='2020-12-22'   and pitcher="陈冲"  order by desc dt limit 1,10 . Expected one of: AND, OR, alias, UNION ALL, token, AS, WITH, HAVING, LIMIT, SETTINGS, FORMAT, NOT, BETWEEN, LIKE, IS, NOT LIKE, IN, NOT IN, GLOBAL IN, GLOBAL NOT IN, Comma, Dot, Arrow, QuestionMark, ORDER BY, INTO OUTFILE, GROUP BY. Stack trace:
+
+0. /server/clickhouse_build/../contrib/poco/Foundation/src/Exception.cpp:27: Poco::Exception::Exception(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int) @ 0xc0390cc in /clickhouse/bin/clickhouse
+1. /server/clickhouse_build/../src/Common/Exception.cpp:29: DB::Exception::Exception(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int) @ 0x5066519 in /clickhouse/bin/clickhouse
+2. /server/clickhouse_build/../src/Parsers/parseQuery.cpp:310: DB::parseQuery(DB::IParser&, char const*, char const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned long, unsigned long) (.cold) @ 0x4db0714 in /clickhouse/bin/clickhouse
+3. /server/clickhouse_build/../src/Interpreters/executeQuery.cpp:287: DB::executeQueryImpl(char const*, char const*, DB::Context&, bool, DB::QueryProcessingStage::Enum, bool, DB::ReadBuffer*, bool) @ 0x8f06380 in /clickhouse/bin/clickhouse
+4. /server/clickhouse_build/../src/Interpreters/executeQuery.cpp:718: DB::executeQuery(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, DB::Context&, bool, DB::QueryProcessingStage::Enum, bool, bool) @ 0x8f0a0dd in /clickhouse/bin/clickhouse
+5. /server/clickhouse_build/../programs/server/TCPHandler.cpp:257: DB::TCPHandler::runImpl() @ 0x50c1029 in /clickhouse/bin/clickhouse
+6. /server/clickhouse_build/../programs/server/TCPHandler.cpp:1252: DB::TCPHandler::run() @ 0x50c1f2c in /clickhouse/bin/clickhouse
+7. /server/clickhouse_build/../contrib/poco/Net/src/TCPServerConnection.cpp:57: Poco::Net::TCPServerConnection::start() @ 0x9e54827 in /clickhouse/bin/clickhouse
+8. /server/clickhouse_build/../contrib/libcxx/include/atomic:856: Poco::Net::TCPServerDispatcher::run() @ 0x9e54c1d in /clickhouse/bin/clickhouse
+9. /server/clickhouse_build/../contrib/poco/Foundation/include/Poco/Mutex_STD.h:132: Poco::PooledThread::run() @ 0xc0ab67f in /clickhouse/bin/clickhouse
+10. /server/clickhouse_build/../contrib/poco/Foundation/include/Poco/AutoPtr.h:205: Poco::ThreadImpl::runnableEntry(void*) @ 0xc0a8748 in /clickhouse/bin/clickhouse
+11. /server/clickhouse_build/../contrib/libcxx/include/memory:2615: void* std::__1::__thread_proxy<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void* (*)(void*), Poco::ThreadImpl*> >(void*) @ 0xc0a9fe9 in /clickhouse/bin/clickhouse
+12. start_thread @ 0x76db in /lib/x86_64-linux-gnu/libpthread-2.27.so
+13. clone @ 0x121a3f in /lib/x86_64-linux-gnu/libc-2.27.so
+
+[2020-12-23 19:17:37,573] - [ERROR] - 500 POST /data/pitcher_panel/channel (::1) 275.75ms
+[2020-12-23 19:18:12,975] - [INFO] - D:\code\QcWebServer\data_manage\pitcher_panel.py modified; restarting server
+[2020-12-23 19:18:13,939] - [INFO] - write pid 1536 ...
+[2020-12-23 19:18:13,947] - [INFO] - server start, listening on port 8008
+[2020-12-23 19:18:14,008] - [ERROR] - Uncaught exception POST /data/pitcher_panel/channel (127.0.0.1)
+HTTPServerRequest(protocol='http', host='localhost:8008', method='POST', uri='/data/pitcher_panel/channel', version='HTTP/1.1', remote_ip='127.0.0.1')
+Traceback (most recent call last):
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\tornado\web.py", line 1702, in _execute
+    result = method(*self.path_args, **self.path_kwargs)
+  File "D:\code\QcWebServer\handlers\PitcherPanel.py", line 24, in post
+    data=get_pitcher_panel_channel(pitcher, channel, start, end, page, page_size, order_by, order)
+  File "D:\code\QcWebServer\data_manage\pitcher_panel.py", line 30, in get_pitcher_panel_channel
+    print(sql)
+OSError: [Errno 22] Invalid argument
+[2020-12-23 19:18:14,010] - [ERROR] - 500 POST /data/pitcher_panel/channel (127.0.0.1) 2.03ms
+[2020-12-23 19:18:23,514] - [ERROR] - Uncaught exception POST /data/pitcher_panel/channel (127.0.0.1)
+HTTPServerRequest(protocol='http', host='localhost:8008', method='POST', uri='/data/pitcher_panel/channel', version='HTTP/1.1', remote_ip='127.0.0.1')
+Traceback (most recent call last):
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\tornado\web.py", line 1702, in _execute
+    result = method(*self.path_args, **self.path_kwargs)
+  File "D:\code\QcWebServer\handlers\PitcherPanel.py", line 24, in post
+    data=get_pitcher_panel_channel(pitcher, channel, start, end, page, page_size, order_by, order)
+  File "D:\code\QcWebServer\data_manage\pitcher_panel.py", line 30, in get_pitcher_panel_channel
+    print(sql)
+OSError: [Errno 22] Invalid argument
+[2020-12-23 19:18:23,515] - [ERROR] - 500 POST /data/pitcher_panel/channel (127.0.0.1) 1.00ms
+[2020-12-23 19:18:29,172] - [INFO] - write pid 4820 ...
+[2020-12-23 19:18:33,210] - [INFO] - write pid 4548 ...
+[2020-12-23 19:24:03,509] - [INFO] - write pid 20328 ...
+[2020-12-23 19:24:03,516] - [INFO] - server start, listening on port 8008
+[2020-12-23 19:24:08,478] - [ERROR] - Uncaught exception POST /data/pitcher_panel/channel (::1)
+HTTPServerRequest(protocol='http', host='localhost:8008', method='POST', uri='/data/pitcher_panel/channel', version='HTTP/1.1', remote_ip='::1')
+Traceback (most recent call last):
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\tornado\web.py", line 1702, in _execute
+    result = method(*self.path_args, **self.path_kwargs)
+  File "D:\code\QcWebServer\handlers\PitcherPanel.py", line 24, in post
+    data=get_pitcher_panel_channel(pitcher, channel, start, end, page, page_size, order_by, order)
+  File "D:\code\QcWebServer\data_manage\pitcher_panel.py", line 31, in get_pitcher_panel_channel
+    data=ck.execute(sql)
+  File "D:\code\QcWebServer\model\DataBaseUtils.py", line 61, in execute
+    return self.client.execute(sql)
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\clickhouse_driver\client.py", line 252, in execute
+    columnar=columnar
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\clickhouse_driver\client.py", line 447, in process_ordinary_query
+    columnar=columnar)
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\clickhouse_driver\client.py", line 113, in receive_result
+    return result.get_result()
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\clickhouse_driver\result.py", line 50, in get_result
+    for packet in self.packet_generator:
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\clickhouse_driver\client.py", line 129, in packet_generator
+    packet = self.receive_packet()
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\clickhouse_driver\client.py", line 146, in receive_packet
+    raise packet.exception
+clickhouse_driver.errors.ServerException: Code: 62.
+DB::Exception: Syntax error: failed at position 677 (line 11, col 116): dt limit 1,10 . Expected one of: AND, OR, alias, UNION ALL, token, AS, LIMIT, SETTINGS, FORMAT, NOT, BETWEEN, LIKE, IS, NOT LIKE, IN, NOT IN, GLOBAL IN, GLOBAL NOT IN, Comma, Dot, Arrow, QuestionMark, INTO OUTFILE. Stack trace:
+
+0. /server/clickhouse_build/../contrib/poco/Foundation/src/Exception.cpp:27: Poco::Exception::Exception(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int) @ 0xc0390cc in /clickhouse/bin/clickhouse
+1. /server/clickhouse_build/../src/Common/Exception.cpp:29: DB::Exception::Exception(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int) @ 0x5066519 in /clickhouse/bin/clickhouse
+2. /server/clickhouse_build/../src/Parsers/parseQuery.cpp:310: DB::parseQuery(DB::IParser&, char const*, char const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned long, unsigned long) (.cold) @ 0x4db0714 in /clickhouse/bin/clickhouse
+3. /server/clickhouse_build/../src/Interpreters/executeQuery.cpp:287: DB::executeQueryImpl(char const*, char const*, DB::Context&, bool, DB::QueryProcessingStage::Enum, bool, DB::ReadBuffer*, bool) @ 0x8f06380 in /clickhouse/bin/clickhouse
+4. /server/clickhouse_build/../src/Interpreters/executeQuery.cpp:718: DB::executeQuery(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, DB::Context&, bool, DB::QueryProcessingStage::Enum, bool, bool) @ 0x8f0a0dd in /clickhouse/bin/clickhouse
+5. /server/clickhouse_build/../programs/server/TCPHandler.cpp:257: DB::TCPHandler::runImpl() @ 0x50c1029 in /clickhouse/bin/clickhouse
+6. /server/clickhouse_build/../programs/server/TCPHandler.cpp:1252: DB::TCPHandler::run() @ 0x50c1f2c in /clickhouse/bin/clickhouse
+7. /server/clickhouse_build/../contrib/poco/Net/src/TCPServerConnection.cpp:57: Poco::Net::TCPServerConnection::start() @ 0x9e54827 in /clickhouse/bin/clickhouse
+8. /server/clickhouse_build/../contrib/libcxx/include/atomic:856: Poco::Net::TCPServerDispatcher::run() @ 0x9e54c1d in /clickhouse/bin/clickhouse
+9. /server/clickhouse_build/../contrib/poco/Foundation/include/Poco/Mutex_STD.h:132: Poco::PooledThread::run() @ 0xc0ab67f in /clickhouse/bin/clickhouse
+10. /server/clickhouse_build/../contrib/poco/Foundation/include/Poco/AutoPtr.h:205: Poco::ThreadImpl::runnableEntry(void*) @ 0xc0a8748 in /clickhouse/bin/clickhouse
+11. /server/clickhouse_build/../contrib/libcxx/include/memory:2615: void* std::__1::__thread_proxy<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void* (*)(void*), Poco::ThreadImpl*> >(void*) @ 0xc0a9fe9 in /clickhouse/bin/clickhouse
+12. start_thread @ 0x76db in /lib/x86_64-linux-gnu/libpthread-2.27.so
+13. clone @ 0x121a3f in /lib/x86_64-linux-gnu/libc-2.27.so
+
+[2020-12-23 19:24:08,495] - [ERROR] - 500 POST /data/pitcher_panel/channel (::1) 404.54ms
+[2020-12-23 19:25:27,019] - [INFO] - D:\code\QcWebServer\handlers\PitcherPanel.py modified; restarting server
+[2020-12-23 19:25:27,980] - [INFO] - write pid 2636 ...
+[2020-12-23 19:25:27,986] - [INFO] - server start, listening on port 8008
+[2020-12-23 19:25:28,542] - [ERROR] - Uncaught exception POST /data/pitcher_panel/channel (::1)
+HTTPServerRequest(protocol='http', host='localhost:8008', method='POST', uri='/data/pitcher_panel/channel', version='HTTP/1.1', remote_ip='::1')
+Traceback (most recent call last):
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\tornado\web.py", line 1702, in _execute
+    result = method(*self.path_args, **self.path_kwargs)
+  File "D:\code\QcWebServer\handlers\PitcherPanel.py", line 24, in post
+    data=get_pitcher_panel_channel(pitcher, channel, start, end, page, page_size, order_by, order)
+  File "D:\code\QcWebServer\data_manage\pitcher_panel.py", line 30, in get_pitcher_panel_channel
+    print(sql)
+OSError: [Errno 22] Invalid argument
+[2020-12-23 19:25:28,544] - [ERROR] - 500 POST /data/pitcher_panel/channel (::1) 2.99ms
+[2020-12-23 19:25:33,457] - [INFO] - write pid 10868 ...
+[2020-12-23 19:26:00,647] - [INFO] - write pid 7276 ...
+[2020-12-23 19:26:00,653] - [INFO] - server start, listening on port 8008
+[2020-12-23 19:26:03,805] - [ERROR] - Uncaught exception POST /data/pitcher_panel/channel (::1)
+HTTPServerRequest(protocol='http', host='localhost:8008', method='POST', uri='/data/pitcher_panel/channel', version='HTTP/1.1', remote_ip='::1')
+Traceback (most recent call last):
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\tornado\web.py", line 1702, in _execute
+    result = method(*self.path_args, **self.path_kwargs)
+  File "D:\code\QcWebServer\handlers\PitcherPanel.py", line 24, in post
+    data=get_pitcher_panel_channel(pitcher, channel, start, end, page, page_size, order_by, order)
+  File "D:\code\QcWebServer\data_manage\pitcher_panel.py", line 31, in get_pitcher_panel_channel
+    data=ck.execute(sql)
+  File "D:\code\QcWebServer\model\DataBaseUtils.py", line 61, in execute
+    return self.client.execute(sql)
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\clickhouse_driver\client.py", line 252, in execute
+    columnar=columnar
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\clickhouse_driver\client.py", line 447, in process_ordinary_query
+    columnar=columnar)
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\clickhouse_driver\client.py", line 113, in receive_result
+    return result.get_result()
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\clickhouse_driver\result.py", line 50, in get_result
+    for packet in self.packet_generator:
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\clickhouse_driver\client.py", line 129, in packet_generator
+    packet = self.receive_packet()
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\clickhouse_driver\client.py", line 146, in receive_packet
+    raise packet.exception
+clickhouse_driver.errors.ServerException: Code: 47.
+DB::Exception: Missing columns: '陈冲' while processing query: 'SELECT channel, stage, platform, book, dt, cost, first_order_amount, if(cost = 0, 0, round(first_order_amount / cost, 4)) AS first_roi, first_order_user, first_order_count, if(first_order_user = 0, 0, round(cost / first_order_user, 2)) AS first_per_cost, view_count, click_count, follow_user, if(click_count = 0, 0, round(follow_user / click_count, 4)) AS follow_rate, if(follow_user = 0, 0, round(cost / follow_user, 2)) AS follow_per_cost, total_cost, if(total_cost = 0, 0, round(total_amount / total_cost, 4)) AS back_rate FROM dw_daily_channel WHERE (dt >= '2020-12-22') AND (dt <= '2020-12-22') AND (pitcher = `陈冲`) ORDER BY dt DESC LIMIT 1, 10', required columns: 'first_order_amount' 'dt' 'platform' 'stage' 'pitcher' 'cost' 'channel' 'follow_user' 'first_order_user' 'first_order_count' 'book' 'click_count' 'view_count' 'total_amount' 'total_cost' '陈冲', source columns: 'total_amount' 'web_view_count' 'dt' 'reg_order_user' 'total_cost' 'click_count' 'view_count' 'reg_order_count' 'first_order_amount' 'reg_order_amount' 'stage' 'order_amount' 'order_user' 'order_count' 'book' 'web_order_count' 'follow_user' 'channel' 'platform' 'first_order_count' 'first_order_user' 'cost' 'pitcher' 'platform_view_count' 'reg_order_amount30'. Stack trace:
+
+0. /server/clickhouse_build/../contrib/poco/Foundation/src/Exception.cpp:27: Poco::Exception::Exception(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int) @ 0xc0390cc in /clickhouse/bin/clickhouse
+1. /server/clickhouse_build/../src/Common/Exception.cpp:29: DB::Exception::Exception(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int) @ 0x5066519 in /clickhouse/bin/clickhouse
+2. /server/clickhouse_build/../contrib/libcxx/include/string:2134: DB::SyntaxAnalyzerResult::collectUsedColumns(std::__1::shared_ptr<DB::IAST> const&) (.cold) @ 0x4c72e66 in /clickhouse/bin/clickhouse
+3. /server/clickhouse_build/../contrib/libcxx/include/new:251: DB::SyntaxAnalyzer::analyzeSelect(std::__1::shared_ptr<DB::IAST>&, DB::SyntaxAnalyzerResult&&, DB::SelectQueryOptions const&, std::__1::vector<DB::TableWithColumnNamesAndTypes, std::__1::allocator<DB::TableWithColumnNamesAndTypes> > const&, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&) const @ 0x8ecb84f in /clickhouse/bin/clickhouse
+4. /server/clickhouse_build/../src/Interpreters/InterpreterSelectQuery.cpp:300: DB::InterpreterSelectQuery::InterpreterSelectQuery(std::__1::shared_ptr<DB::IAST> const&, DB::Context const&, std::__1::shared_ptr<DB::IBlockInputStream> const&, std::__1::optional<DB::Pipe>, std::__1::shared_ptr<DB::IStorage> const&, DB::SelectQueryOptions const&, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&)::'lambda'(bool)::operator()(bool) const @ 0x8d3bf75 in /clickhouse/bin/clickhouse
+5. /server/clickhouse_build/../src/Interpreters/InterpreterSelectQuery.cpp:374: DB::InterpreterSelectQuery::InterpreterSelectQuery(std::__1::shared_ptr<DB::IAST> const&, DB::Context const&, std::__1::shared_ptr<DB::IBlockInputStream> const&, std::__1::optional<DB::Pipe>, std::__1::shared_ptr<DB::IStorage> const&, DB::SelectQueryOptions const&, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&) @ 0x8d3d282 in /clickhouse/bin/clickhouse
+6. /server/clickhouse_build/../src/Interpreters/InterpreterSelectQuery.cpp:167: DB::InterpreterSelectQuery::InterpreterSelectQuery(std::__1::shared_ptr<DB::IAST> const&, DB::Context const&, DB::SelectQueryOptions const&, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&) @ 0x8d3e7e5 in /clickhouse/bin/clickhouse
+7. /server/clickhouse_build/../contrib/libcxx/include/vector:1681: DB::InterpreterSelectWithUnionQuery::InterpreterSelectWithUnionQuery(std::__1::shared_ptr<DB::IAST> const&, DB::Context const&, DB::SelectQueryOptions const&, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&) @ 0x8d78c96 in /clickhouse/bin/clickhouse
+8. /server/clickhouse_build/../contrib/libcxx/include/vector:461: DB::InterpreterFactory::get(std::__1::shared_ptr<DB::IAST>&, DB::Context&, DB::QueryProcessingStage::Enum) @ 0x8d1b7f4 in /clickhouse/bin/clickhouse
+9. /server/clickhouse_build/../src/Interpreters/executeQuery.cpp:406: DB::executeQueryImpl(char const*, char const*, DB::Context&, bool, DB::QueryProcessingStage::Enum, bool, DB::ReadBuffer*, bool) @ 0x8f06b06 in /clickhouse/bin/clickhouse
+10. /server/clickhouse_build/../src/Interpreters/executeQuery.cpp:718: DB::executeQuery(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, DB::Context&, bool, DB::QueryProcessingStage::Enum, bool, bool) @ 0x8f0a0dd in /clickhouse/bin/clickhouse
+11. /server/clickhouse_build/../programs/server/TCPHandler.cpp:257: DB::TCPHandler::runImpl() @ 0x50c1029 in /clickhouse/bin/clickhouse
+12. /server/clickhouse_build/../programs/server/TCPHandler.cpp:1252: DB::TCPHandler::run() @ 0x50c1f2c in /clickhouse/bin/clickhouse
+13. /server/clickhouse_build/../contrib/poco/Net/src/TCPServerConnection.cpp:57: Poco::Net::TCPServerConnection::start() @ 0x9e54827 in /clickhouse/bin/clickhouse
+14. /server/clickhouse_build/../contrib/libcxx/include/atomic:856: Poco::Net::TCPServerDispatcher::run() @ 0x9e54c1d in /clickhouse/bin/clickhouse
+15. /server/clickhouse_build/../contrib/poco/Foundation/include/Poco/Mutex_STD.h:132: Poco::PooledThread::run() @ 0xc0ab67f in /clickhouse/bin/clickhouse
+16. /server/clickhouse_build/../contrib/poco/Foundation/include/Poco/AutoPtr.h:205: Poco::ThreadImpl::runnableEntry(void*) @ 0xc0a8748 in /clickhouse/bin/clickhouse
+17. /server/clickhouse_build/../contrib/libcxx/include/memory:2615: void* std::__1::__thread_proxy<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void* (*)(void*), Poco::ThreadImpl*> >(void*) @ 0xc0a9fe9 in /clickhouse/bin/clickhouse
+18. start_thread @ 0x76db in /lib/x86_64-linux-gnu/libpthread-2.27.so
+19. clone @ 0x121a3f in /lib/x86_64-linux-gnu/libc-2.27.so
+
+[2020-12-23 19:26:03,811] - [ERROR] - 500 POST /data/pitcher_panel/channel (::1) 263.66ms
+[2020-12-23 19:26:42,204] - [INFO] - write pid 16860 ...
+[2020-12-23 19:26:42,210] - [INFO] - server start, listening on port 8008
+[2020-12-23 19:26:44,621] - [ERROR] - Uncaught exception POST /data/pitcher_panel/channel (::1)
+HTTPServerRequest(protocol='http', host='localhost:8008', method='POST', uri='/data/pitcher_panel/channel', version='HTTP/1.1', remote_ip='::1')
+Traceback (most recent call last):
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\tornado\web.py", line 1702, in _execute
+    result = method(*self.path_args, **self.path_kwargs)
+  File "D:\code\QcWebServer\handlers\PitcherPanel.py", line 24, in post
+    data=get_pitcher_panel_channel(pitcher, channel, start, end, page, page_size, order_by, order)
+  File "D:\code\QcWebServer\data_manage\pitcher_panel.py", line 31, in get_pitcher_panel_channel
+    data=ck.execute(sql)
+  File "D:\code\QcWebServer\model\DataBaseUtils.py", line 61, in execute
+    return self.client.execute(sql)
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\clickhouse_driver\client.py", line 252, in execute
+    columnar=columnar
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\clickhouse_driver\client.py", line 447, in process_ordinary_query
+    columnar=columnar)
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\clickhouse_driver\client.py", line 113, in receive_result
+    return result.get_result()
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\clickhouse_driver\result.py", line 50, in get_result
+    for packet in self.packet_generator:
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\clickhouse_driver\client.py", line 129, in packet_generator
+    packet = self.receive_packet()
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\clickhouse_driver\client.py", line 146, in receive_packet
+    raise packet.exception
+clickhouse_driver.errors.ServerException: Code: 47.
+DB::Exception: Missing columns: '2020-12-22' '陈冲' while processing query: 'SELECT channel, stage, platform, book, dt, cost, first_order_amount, if(cost = 0, 0, round(first_order_amount / cost, 4)) AS first_roi, first_order_user, first_order_count, if(first_order_user = 0, 0, round(cost / first_order_user, 2)) AS first_per_cost, view_count, click_count, follow_user, if(click_count = 0, 0, round(follow_user / click_count, 4)) AS follow_rate, if(follow_user = 0, 0, round(cost / follow_user, 2)) AS follow_per_cost, total_cost, if(total_cost = 0, 0, round(total_amount / total_cost, 4)) AS back_rate FROM dw_daily_channel WHERE (dt >= `2020-12-22`) AND (dt <= `2020-12-22`) AND (pitcher = `陈冲`) ORDER BY dt DESC LIMIT 1, 10', required columns: 'first_order_amount' 'dt' 'platform' 'stage' 'channel' 'follow_user' 'cost' 'pitcher' 'first_order_user' 'first_order_count' 'book' 'click_count' 'view_count' 'total_cost' '陈冲' '2020-12-22' 'total_amount', source columns: 'total_amount' 'web_view_count' 'dt' 'reg_order_user' 'total_cost' 'click_count' 'view_count' 'reg_order_count' 'first_order_amount' 'reg_order_amount' 'stage' 'order_amount' 'order_user' 'order_count' 'book' 'web_order_count' 'follow_user' 'channel' 'platform' 'first_order_count' 'first_order_user' 'cost' 'pitcher' 'platform_view_count' 'reg_order_amount30'. Stack trace:
+
+0. /server/clickhouse_build/../contrib/poco/Foundation/src/Exception.cpp:27: Poco::Exception::Exception(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int) @ 0xc0390cc in /clickhouse/bin/clickhouse
+1. /server/clickhouse_build/../src/Common/Exception.cpp:29: DB::Exception::Exception(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int) @ 0x5066519 in /clickhouse/bin/clickhouse
+2. /server/clickhouse_build/../contrib/libcxx/include/string:2134: DB::SyntaxAnalyzerResult::collectUsedColumns(std::__1::shared_ptr<DB::IAST> const&) (.cold) @ 0x4c72e66 in /clickhouse/bin/clickhouse
+3. /server/clickhouse_build/../contrib/libcxx/include/new:251: DB::SyntaxAnalyzer::analyzeSelect(std::__1::shared_ptr<DB::IAST>&, DB::SyntaxAnalyzerResult&&, DB::SelectQueryOptions const&, std::__1::vector<DB::TableWithColumnNamesAndTypes, std::__1::allocator<DB::TableWithColumnNamesAndTypes> > const&, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&) const @ 0x8ecb84f in /clickhouse/bin/clickhouse
+4. /server/clickhouse_build/../src/Interpreters/InterpreterSelectQuery.cpp:300: DB::InterpreterSelectQuery::InterpreterSelectQuery(std::__1::shared_ptr<DB::IAST> const&, DB::Context const&, std::__1::shared_ptr<DB::IBlockInputStream> const&, std::__1::optional<DB::Pipe>, std::__1::shared_ptr<DB::IStorage> const&, DB::SelectQueryOptions const&, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&)::'lambda'(bool)::operator()(bool) const @ 0x8d3bf75 in /clickhouse/bin/clickhouse
+5. /server/clickhouse_build/../src/Interpreters/InterpreterSelectQuery.cpp:374: DB::InterpreterSelectQuery::InterpreterSelectQuery(std::__1::shared_ptr<DB::IAST> const&, DB::Context const&, std::__1::shared_ptr<DB::IBlockInputStream> const&, std::__1::optional<DB::Pipe>, std::__1::shared_ptr<DB::IStorage> const&, DB::SelectQueryOptions const&, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&) @ 0x8d3d282 in /clickhouse/bin/clickhouse
+6. /server/clickhouse_build/../src/Interpreters/InterpreterSelectQuery.cpp:167: DB::InterpreterSelectQuery::InterpreterSelectQuery(std::__1::shared_ptr<DB::IAST> const&, DB::Context const&, DB::SelectQueryOptions const&, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&) @ 0x8d3e7e5 in /clickhouse/bin/clickhouse
+7. /server/clickhouse_build/../contrib/libcxx/include/vector:1681: DB::InterpreterSelectWithUnionQuery::InterpreterSelectWithUnionQuery(std::__1::shared_ptr<DB::IAST> const&, DB::Context const&, DB::SelectQueryOptions const&, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&) @ 0x8d78c96 in /clickhouse/bin/clickhouse
+8. /server/clickhouse_build/../contrib/libcxx/include/vector:461: DB::InterpreterFactory::get(std::__1::shared_ptr<DB::IAST>&, DB::Context&, DB::QueryProcessingStage::Enum) @ 0x8d1b7f4 in /clickhouse/bin/clickhouse
+9. /server/clickhouse_build/../src/Interpreters/executeQuery.cpp:406: DB::executeQueryImpl(char const*, char const*, DB::Context&, bool, DB::QueryProcessingStage::Enum, bool, DB::ReadBuffer*, bool) @ 0x8f06b06 in /clickhouse/bin/clickhouse
+10. /server/clickhouse_build/../src/Interpreters/executeQuery.cpp:718: DB::executeQuery(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, DB::Context&, bool, DB::QueryProcessingStage::Enum, bool, bool) @ 0x8f0a0dd in /clickhouse/bin/clickhouse
+11. /server/clickhouse_build/../programs/server/TCPHandler.cpp:257: DB::TCPHandler::runImpl() @ 0x50c1029 in /clickhouse/bin/clickhouse
+12. /server/clickhouse_build/../programs/server/TCPHandler.cpp:1252: DB::TCPHandler::run() @ 0x50c1f2c in /clickhouse/bin/clickhouse
+13. /server/clickhouse_build/../contrib/poco/Net/src/TCPServerConnection.cpp:57: Poco::Net::TCPServerConnection::start() @ 0x9e54827 in /clickhouse/bin/clickhouse
+14. /server/clickhouse_build/../contrib/libcxx/include/atomic:856: Poco::Net::TCPServerDispatcher::run() @ 0x9e54c1d in /clickhouse/bin/clickhouse
+15. /server/clickhouse_build/../contrib/poco/Foundation/include/Poco/Mutex_STD.h:132: Poco::PooledThread::run() @ 0xc0ab67f in /clickhouse/bin/clickhouse
+16. /server/clickhouse_build/../contrib/poco/Foundation/include/Poco/AutoPtr.h:205: Poco::ThreadImpl::runnableEntry(void*) @ 0xc0a8748 in /clickhouse/bin/clickhouse
+17. /server/clickhouse_build/../contrib/libcxx/include/memory:2615: void* std::__1::__thread_proxy<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void* (*)(void*), Poco::ThreadImpl*> >(void*) @ 0xc0a9fe9 in /clickhouse/bin/clickhouse
+18. start_thread @ 0x76db in /lib/x86_64-linux-gnu/libpthread-2.27.so
+19. clone @ 0x121a3f in /lib/x86_64-linux-gnu/libc-2.27.so
+
+[2020-12-23 19:26:44,636] - [ERROR] - 500 POST /data/pitcher_panel/channel (::1) 136.14ms
+[2020-12-23 19:30:40,582] - [INFO] - write pid 6184 ...
+[2020-12-23 19:30:40,588] - [INFO] - server start, listening on port 8008
+[2020-12-23 19:30:42,487] - [INFO] - 200 POST /data/pitcher_panel/channel (::1) 145.34ms
+[2020-12-23 19:35:07,606] - [INFO] - D:\code\QcWebServer\data_manage\pitcher_panel.py modified; restarting server
+[2020-12-23 19:35:08,564] - [INFO] - write pid 6424 ...
+[2020-12-23 19:35:08,570] - [INFO] - server start, listening on port 8008
+[2020-12-23 19:36:11,083] - [INFO] - D:\code\QcWebServer\model\DataBaseUtils.py modified; restarting server
+[2020-12-23 19:36:11,937] - [INFO] - write pid 8032 ...
+[2020-12-23 19:36:11,943] - [INFO] - server start, listening on port 8008
+[2020-12-23 19:39:23,455] - [INFO] - D:\code\QcWebServer\data_manage\pitcher_panel.py modified; restarting server
+[2020-12-23 19:39:23,963] - [INFO] - write pid 6332 ...
+[2020-12-23 19:39:23,971] - [INFO] - server start, listening on port 8008
+[2020-12-23 19:39:24,312] - [INFO] - write pid 5112 ...
+[2020-12-23 19:39:27,145] - [INFO] - 200 POST /data/pitcher_panel/channel (::1) 215.21ms
+[2020-12-23 19:39:55,231] - [INFO] - write pid 12364 ...
+[2020-12-23 19:39:55,237] - [INFO] - server start, listening on port 8008
+[2020-12-23 19:40:00,990] - [INFO] - 200 POST /data/pitcher_panel/channel (::1) 285.77ms
+[2020-12-23 19:40:21,783] - [INFO] - write pid 7944 ...
+[2020-12-23 19:40:21,788] - [INFO] - server start, listening on port 8008
+[2020-12-23 19:40:23,448] - [INFO] - 200 POST /data/pitcher_panel/channel (::1) 202.31ms
+[2020-12-23 19:42:46,796] - [INFO] - D:\code\QcWebServer\model\DataBaseUtils.py modified; restarting server
+[2020-12-23 19:42:47,791] - [INFO] - write pid 18920 ...
+[2020-12-23 19:42:47,797] - [INFO] - server start, listening on port 8008
+[2020-12-23 19:43:21,803] - [INFO] - D:\code\QcWebServer\data_manage\pitcher_panel.py modified; restarting server
+[2020-12-23 19:43:22,352] - [INFO] - write pid 6632 ...
+[2020-12-23 19:43:22,359] - [INFO] - server start, listening on port 8008
+[2020-12-23 19:43:22,689] - [INFO] - write pid 4480 ...
+[2020-12-23 19:43:25,966] - [INFO] - 200 POST /data/pitcher_panel/channel (::1) 268.89ms
+[2020-12-23 19:44:24,872] - [INFO] - D:\code\QcWebServer\data_manage\pitcher_panel.py modified; restarting server
+[2020-12-23 19:44:26,021] - [INFO] - write pid 16204 ...
+[2020-12-23 19:44:26,027] - [INFO] - server start, listening on port 8008
+[2020-12-23 19:45:54,545] - [INFO] - D:\code\QcWebServer\data_manage\pitcher_panel.py modified; restarting server
+[2020-12-23 19:45:55,338] - [INFO] - write pid 12688 ...
+[2020-12-23 19:45:55,345] - [INFO] - server start, listening on port 8008
+[2020-12-23 19:45:55,558] - [INFO] - write pid 16708 ...
+[2020-12-23 19:45:58,489] - [INFO] - 200 POST /data/pitcher_panel/channel (::1) 346.39ms
+[2020-12-23 19:49:37,259] - [INFO] - write pid 6328 ...
+[2020-12-23 19:49:37,266] - [INFO] - server start, listening on port 8008
+[2020-12-23 19:49:42,886] - [ERROR] - Uncaught exception POST /data/pitcher_panel/channel (::1)
+HTTPServerRequest(protocol='http', host='localhost:8008', method='POST', uri='/data/pitcher_panel/channel', version='HTTP/1.1', remote_ip='::1')
+Traceback (most recent call last):
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\tornado\web.py", line 1702, in _execute
+    result = method(*self.path_args, **self.path_kwargs)
+  File "D:\code\QcWebServer\handlers\PitcherPanel.py", line 25, in post
+    self.write_json(data)
+  File "D:\code\QcWebServer\handlers\HandlerBase.py", line 27, in write_json
+    self.write(json.dumps({'status': {'msg': msg, "RetCode": status_code}, 'data': data}))
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\simplejson\__init__.py", line 395, in dumps
+    return _default_encoder.encode(obj)
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\simplejson\encoder.py", line 296, in encode
+    chunks = self.iterencode(o, _one_shot=True)
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\simplejson\encoder.py", line 378, in iterencode
+    return _iterencode(o, 0)
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\simplejson\encoder.py", line 273, in default
+    o.__class__.__name__)
+TypeError: Object of type date is not JSON serializable
+[2020-12-23 19:49:42,916] - [ERROR] - 500 POST /data/pitcher_panel/channel (::1) 183.47ms
+[2020-12-23 19:49:57,133] - [INFO] - write pid 15184 ...
+[2020-12-23 19:49:57,140] - [INFO] - server start, listening on port 8008
+[2020-12-23 19:49:58,286] - [ERROR] - Uncaught exception POST /data/pitcher_panel/channel (::1)
+HTTPServerRequest(protocol='http', host='localhost:8008', method='POST', uri='/data/pitcher_panel/channel', version='HTTP/1.1', remote_ip='::1')
+Traceback (most recent call last):
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\tornado\web.py", line 1702, in _execute
+    result = method(*self.path_args, **self.path_kwargs)
+  File "D:\code\QcWebServer\handlers\PitcherPanel.py", line 26, in post
+    self.write_json(data)
+  File "D:\code\QcWebServer\handlers\HandlerBase.py", line 27, in write_json
+    self.write(json.dumps({'status': {'msg': msg, "RetCode": status_code}, 'data': data}))
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\simplejson\__init__.py", line 395, in dumps
+    return _default_encoder.encode(obj)
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\simplejson\encoder.py", line 296, in encode
+    chunks = self.iterencode(o, _one_shot=True)
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\simplejson\encoder.py", line 378, in iterencode
+    return _iterencode(o, 0)
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\simplejson\encoder.py", line 273, in default
+    o.__class__.__name__)
+TypeError: Object of type date is not JSON serializable
+[2020-12-23 19:49:58,297] - [ERROR] - 500 POST /data/pitcher_panel/channel (::1) 126.21ms
+[2020-12-23 19:51:29,672] - [INFO] - D:\code\QcWebServer\data_manage\pitcher_panel.py modified; restarting server
+[2020-12-23 19:51:30,644] - [INFO] - write pid 12132 ...
+[2020-12-23 19:51:30,650] - [INFO] - server start, listening on port 8008
+[2020-12-23 19:52:23,664] - [INFO] - D:\code\QcWebServer\data_manage\pitcher_panel.py modified; restarting server
+[2020-12-23 19:52:24,620] - [INFO] - write pid 19096 ...
+[2020-12-23 19:52:24,621] - [INFO] - write pid 12080 ...
+[2020-12-23 19:52:24,625] - [INFO] - server start, listening on port 8008
+[2020-12-23 19:52:51,508] - [INFO] - write pid 13880 ...
+[2020-12-23 19:52:51,514] - [INFO] - server start, listening on port 8008
+[2020-12-23 19:52:54,781] - [INFO] - 200 POST /data/pitcher_panel/channel (::1) 508.10ms
+[2020-12-23 19:55:43,528] - [INFO] - D:\code\QcWebServer\data_manage\pitcher_panel.py modified; restarting server
+[2020-12-23 19:55:44,492] - [INFO] - write pid 12320 ...
+[2020-12-23 19:55:44,499] - [INFO] - server start, listening on port 8008
+[2020-12-23 19:58:17,520] - [INFO] - D:\code\QcWebServer\data_manage\pitcher_panel.py modified; restarting server
+[2020-12-23 19:58:18,487] - [INFO] - write pid 4128 ...
+[2020-12-23 19:58:18,495] - [INFO] - server start, listening on port 8008
+[2020-12-23 20:02:35,001] - [INFO] - D:\code\QcWebServer\data_manage\pitcher_panel.py modified; restarting server
+[2020-12-23 20:02:35,878] - [INFO] - write pid 18664 ...
+[2020-12-23 20:02:35,883] - [INFO] - server start, listening on port 8008
+[2020-12-23 20:02:35,959] - [INFO] - write pid 10916 ...
+[2020-12-23 20:02:39,826] - [INFO] - 200 POST /data/pitcher_panel/channel (::1) 585.77ms
+[2020-12-23 20:03:14,904] - [INFO] - D:\code\QcWebServer\handlers\PitcherPanel.py modified; restarting server
+[2020-12-23 20:03:15,819] - [INFO] - write pid 704 ...
+[2020-12-23 20:03:15,825] - [INFO] - server start, listening on port 8008
+[2020-12-23 20:05:45,846] - [INFO] - D:\code\QcWebServer\handlers\PitcherPanel.py modified; restarting server
+[2020-12-23 20:37:34,098] - [INFO] - write pid 3468 ...
+[2020-12-23 20:37:34,104] - [INFO] - server start, listening on port 8008
+[2020-12-23 20:38:32,270] - [ERROR] - Uncaught exception POST /data/pitcher_panel/daily (::1)
+HTTPServerRequest(protocol='http', host='localhost:8008', method='POST', uri='/data/pitcher_panel/daily', version='HTTP/1.1', remote_ip='::1')
+Traceback (most recent call last):
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\tornado\web.py", line 1702, in _execute
+    result = method(*self.path_args, **self.path_kwargs)
+  File "D:\code\QcWebServer\handlers\PitcherPanel.py", line 41, in post
+    data = get_pitcher_panel_daily(pitcher, start, end, page, page_size, order_by, order)
+  File "D:\code\QcWebServer\data_manage\pitcher_panel.py", line 62, in get_pitcher_panel_daily
+    data = ck.execute(sql)
+  File "D:\code\QcWebServer\model\DataBaseUtils.py", line 62, in execute
+    return self.client.execute(sql)
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\clickhouse_driver\client.py", line 252, in execute
+    columnar=columnar
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\clickhouse_driver\client.py", line 447, in process_ordinary_query
+    columnar=columnar)
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\clickhouse_driver\client.py", line 113, in receive_result
+    return result.get_result()
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\clickhouse_driver\result.py", line 50, in get_result
+    for packet in self.packet_generator:
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\clickhouse_driver\client.py", line 129, in packet_generator
+    packet = self.receive_packet()
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\clickhouse_driver\client.py", line 146, in receive_packet
+    raise packet.exception
+clickhouse_driver.errors.ServerException: Code: 215.
+DB::Exception: Column `dt` is not under aggregate function and not in GROUP BY. Stack trace:
+
+0. /server/clickhouse_build/../contrib/poco/Foundation/src/Exception.cpp:27: Poco::Exception::Exception(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int) @ 0xc0390cc in /clickhouse/bin/clickhouse
+1. /server/clickhouse_build/../src/Common/Exception.cpp:29: DB::Exception::Exception(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int) @ 0x5066519 in /clickhouse/bin/clickhouse
+2. /server/clickhouse_build/../contrib/libcxx/include/string:2134: DB::ActionsMatcher::visit(DB::ASTIdentifier const&, std::__1::shared_ptr<DB::IAST> const&, DB::ActionsMatcher::Data&) (.cold) @ 0x4d9416e in /clickhouse/bin/clickhouse
+3. /server/clickhouse_build/../contrib/libcxx/include/memory:3826: DB::InDepthNodeVisitor<DB::ActionsMatcher, true, std::__1::shared_ptr<DB::IAST> const>::visit(std::__1::shared_ptr<DB::IAST> const&) @ 0x98c4bb5 in /clickhouse/bin/clickhouse
+4. /server/clickhouse_build/../src/Interpreters/InDepthNodeVisitor.h:45: DB::InDepthNodeVisitor<DB::ActionsMatcher, true, std::__1::shared_ptr<DB::IAST> const>::visit(std::__1::shared_ptr<DB::IAST> const&) @ 0x98c4bf3 in /clickhouse/bin/clickhouse
+5. /server/clickhouse_build/../src/Interpreters/InDepthNodeVisitor.h:45: DB::ExpressionAnalyzer::getRootActions(std::__1::shared_ptr<DB::IAST> const&, bool, std::__1::shared_ptr<DB::ExpressionActions>&, bool) (.constprop.0) @ 0x98b9c3b in /clickhouse/bin/clickhouse
+6. /server/clickhouse_build/../src/Interpreters/ExpressionAnalyzer.cpp:798: DB::SelectQueryExpressionAnalyzer::appendOrderBy(DB::ExpressionActionsChain&, bool, bool, std::__1::vector<std::__1::shared_ptr<DB::ExpressionActions>, std::__1::allocator<std::__1::shared_ptr<DB::ExpressionActions> > >&) @ 0x98bb8bb in /clickhouse/bin/clickhouse
+7. /server/clickhouse_build/../src/Interpreters/ExpressionAnalyzer.cpp:1089: DB::ExpressionAnalysisResult::ExpressionAnalysisResult(DB::SelectQueryExpressionAnalyzer&, bool, bool, bool, std::__1::shared_ptr<DB::FilterInfo> const&, DB::Block const&) @ 0x98c38ea in /clickhouse/bin/clickhouse
+8. /server/clickhouse_build/../src/Interpreters/ExpressionAnalyzer.h:164: DB::InterpreterSelectQuery::getSampleBlockImpl(bool) @ 0x8d3af27 in /clickhouse/bin/clickhouse
+9. /server/clickhouse_build/../src/Interpreters/InterpreterSelectQuery.cpp:300: DB::InterpreterSelectQuery::InterpreterSelectQuery(std::__1::shared_ptr<DB::IAST> const&, DB::Context const&, std::__1::shared_ptr<DB::IBlockInputStream> const&, std::__1::optional<DB::Pipe>, std::__1::shared_ptr<DB::IStorage> const&, DB::SelectQueryOptions const&, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&)::'lambda'(bool)::operator()(bool) const @ 0x8d3c66b in /clickhouse/bin/clickhouse
+10. /server/clickhouse_build/../src/Interpreters/InterpreterSelectQuery.cpp:374: DB::InterpreterSelectQuery::InterpreterSelectQuery(std::__1::shared_ptr<DB::IAST> const&, DB::Context const&, std::__1::shared_ptr<DB::IBlockInputStream> const&, std::__1::optional<DB::Pipe>, std::__1::shared_ptr<DB::IStorage> const&, DB::SelectQueryOptions const&, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&) @ 0x8d3d282 in /clickhouse/bin/clickhouse
+11. /server/clickhouse_build/../src/Interpreters/InterpreterSelectQuery.cpp:167: DB::InterpreterSelectQuery::InterpreterSelectQuery(std::__1::shared_ptr<DB::IAST> const&, DB::Context const&, DB::SelectQueryOptions const&, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&) @ 0x8d3e7e5 in /clickhouse/bin/clickhouse
+12. /server/clickhouse_build/../contrib/libcxx/include/vector:1681: DB::InterpreterSelectWithUnionQuery::InterpreterSelectWithUnionQuery(std::__1::shared_ptr<DB::IAST> const&, DB::Context const&, DB::SelectQueryOptions const&, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&) @ 0x8d78c96 in /clickhouse/bin/clickhouse
+13. /server/clickhouse_build/../contrib/libcxx/include/vector:461: DB::InterpreterFactory::get(std::__1::shared_ptr<DB::IAST>&, DB::Context&, DB::QueryProcessingStage::Enum) @ 0x8d1b7f4 in /clickhouse/bin/clickhouse
+14. /server/clickhouse_build/../src/Interpreters/executeQuery.cpp:406: DB::executeQueryImpl(char const*, char const*, DB::Context&, bool, DB::QueryProcessingStage::Enum, bool, DB::ReadBuffer*, bool) @ 0x8f06b06 in /clickhouse/bin/clickhouse
+15. /server/clickhouse_build/../src/Interpreters/executeQuery.cpp:718: DB::executeQuery(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, DB::Context&, bool, DB::QueryProcessingStage::Enum, bool, bool) @ 0x8f0a0dd in /clickhouse/bin/clickhouse
+16. /server/clickhouse_build/../programs/server/TCPHandler.cpp:257: DB::TCPHandler::runImpl() @ 0x50c1029 in /clickhouse/bin/clickhouse
+17. /server/clickhouse_build/../programs/server/TCPHandler.cpp:1252: DB::TCPHandler::run() @ 0x50c1f2c in /clickhouse/bin/clickhouse
+18. /server/clickhouse_build/../contrib/poco/Net/src/TCPServerConnection.cpp:57: Poco::Net::TCPServerConnection::start() @ 0x9e54827 in /clickhouse/bin/clickhouse
+19. /server/clickhouse_build/../contrib/libcxx/include/atomic:856: Poco::Net::TCPServerDispatcher::run() @ 0x9e54c1d in /clickhouse/bin/clickhouse
+20. /server/clickhouse_build/../contrib/poco/Foundation/include/Poco/Mutex_STD.h:132: Poco::PooledThread::run() @ 0xc0ab67f in /clickhouse/bin/clickhouse
+21. /server/clickhouse_build/../contrib/poco/Foundation/include/Poco/AutoPtr.h:205: Poco::ThreadImpl::runnableEntry(void*) @ 0xc0a8748 in /clickhouse/bin/clickhouse
+22. /server/clickhouse_build/../contrib/libcxx/include/memory:2615: void* std::__1::__thread_proxy<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void* (*)(void*), Poco::ThreadImpl*> >(void*) @ 0xc0a9fe9 in /clickhouse/bin/clickhouse
+23. start_thread @ 0x76db in /lib/x86_64-linux-gnu/libpthread-2.27.so
+24. clone @ 0x121a3f in /lib/x86_64-linux-gnu/libc-2.27.so
+
+[2020-12-23 20:38:32,286] - [ERROR] - 500 POST /data/pitcher_panel/daily (::1) 322.47ms
+[2020-12-23 20:39:42,605] - [INFO] - write pid 17236 ...
+[2020-12-23 20:39:42,610] - [INFO] - server start, listening on port 8008
+[2020-12-23 20:39:44,100] - [ERROR] - Uncaught exception POST /data/pitcher_panel/daily (::1)
+HTTPServerRequest(protocol='http', host='localhost:8008', method='POST', uri='/data/pitcher_panel/daily', version='HTTP/1.1', remote_ip='::1')
+Traceback (most recent call last):
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\tornado\web.py", line 1702, in _execute
+    result = method(*self.path_args, **self.path_kwargs)
+  File "D:\code\QcWebServer\handlers\PitcherPanel.py", line 41, in post
+    data = get_pitcher_panel_daily(pitcher, start, end, page, page_size, order_by, order)
+  File "D:\code\QcWebServer\data_manage\pitcher_panel.py", line 62, in get_pitcher_panel_daily
+    data = ck.execute(sql)
+  File "D:\code\QcWebServer\model\DataBaseUtils.py", line 62, in execute
+    return self.client.execute(sql)
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\clickhouse_driver\client.py", line 252, in execute
+    columnar=columnar
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\clickhouse_driver\client.py", line 447, in process_ordinary_query
+    columnar=columnar)
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\clickhouse_driver\client.py", line 113, in receive_result
+    return result.get_result()
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\clickhouse_driver\result.py", line 50, in get_result
+    for packet in self.packet_generator:
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\clickhouse_driver\client.py", line 129, in packet_generator
+    packet = self.receive_packet()
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\clickhouse_driver\client.py", line 146, in receive_packet
+    raise packet.exception
+clickhouse_driver.errors.ServerException: Code: 62.
+DB::Exception: Syntax error: failed at position 81 (line 3, col 21): (sum(cost),2) cost,
+                round(sum(first_order_amount),2) first_order_amount,
+               if(cost=0,0,round(first_order_amount/cost,4)) first_roi . Expected one of: UNION ALL, token, FROM, PREWHERE, WHERE, WITH, HAVING, LIMIT, SETTINGS, FORMAT, Comma, ORDER BY, INTO OUTFILE, GROUP BY. Stack trace:
+
+0. /server/clickhouse_build/../contrib/poco/Foundation/src/Exception.cpp:27: Poco::Exception::Exception(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int) @ 0xc0390cc in /clickhouse/bin/clickhouse
+1. /server/clickhouse_build/../src/Common/Exception.cpp:29: DB::Exception::Exception(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int) @ 0x5066519 in /clickhouse/bin/clickhouse
+2. /server/clickhouse_build/../src/Parsers/parseQuery.cpp:310: DB::parseQuery(DB::IParser&, char const*, char const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned long, unsigned long) (.cold) @ 0x4db0714 in /clickhouse/bin/clickhouse
+3. /server/clickhouse_build/../src/Interpreters/executeQuery.cpp:287: DB::executeQueryImpl(char const*, char const*, DB::Context&, bool, DB::QueryProcessingStage::Enum, bool, DB::ReadBuffer*, bool) @ 0x8f06380 in /clickhouse/bin/clickhouse
+4. /server/clickhouse_build/../src/Interpreters/executeQuery.cpp:718: DB::executeQuery(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, DB::Context&, bool, DB::QueryProcessingStage::Enum, bool, bool) @ 0x8f0a0dd in /clickhouse/bin/clickhouse
+5. /server/clickhouse_build/../programs/server/TCPHandler.cpp:257: DB::TCPHandler::runImpl() @ 0x50c1029 in /clickhouse/bin/clickhouse
+6. /server/clickhouse_build/../programs/server/TCPHandler.cpp:1252: DB::TCPHandler::run() @ 0x50c1f2c in /clickhouse/bin/clickhouse
+7. /server/clickhouse_build/../contrib/poco/Net/src/TCPServerConnection.cpp:57: Poco::Net::TCPServerConnection::start() @ 0x9e54827 in /clickhouse/bin/clickhouse
+8. /server/clickhouse_build/../contrib/libcxx/include/atomic:856: Poco::Net::TCPServerDispatcher::run() @ 0x9e54c1d in /clickhouse/bin/clickhouse
+9. /server/clickhouse_build/../contrib/poco/Foundation/include/Poco/Mutex_STD.h:132: Poco::PooledThread::run() @ 0xc0ab67f in /clickhouse/bin/clickhouse
+10. /server/clickhouse_build/../contrib/poco/Foundation/include/Poco/AutoPtr.h:205: Poco::ThreadImpl::runnableEntry(void*) @ 0xc0a8748 in /clickhouse/bin/clickhouse
+11. /server/clickhouse_build/../contrib/libcxx/include/memory:2615: void* std::__1::__thread_proxy<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void* (*)(void*), Poco::ThreadImpl*> >(void*) @ 0xc0a9fe9 in /clickhouse/bin/clickhouse
+12. start_thread @ 0x76db in /lib/x86_64-linux-gnu/libpthread-2.27.so
+13. clone @ 0x121a3f in /lib/x86_64-linux-gnu/libc-2.27.so
+
+[2020-12-23 20:39:44,120] - [ERROR] - 500 POST /data/pitcher_panel/daily (::1) 136.05ms
+[2020-12-23 20:40:50,058] - [INFO] - write pid 16120 ...
+[2020-12-23 20:40:50,065] - [INFO] - server start, listening on port 8008
+[2020-12-23 20:40:51,767] - [ERROR] - Uncaught exception POST /data/pitcher_panel/daily (::1)
+HTTPServerRequest(protocol='http', host='localhost:8008', method='POST', uri='/data/pitcher_panel/daily', version='HTTP/1.1', remote_ip='::1')
+Traceback (most recent call last):
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\tornado\web.py", line 1702, in _execute
+    result = method(*self.path_args, **self.path_kwargs)
+  File "D:\code\QcWebServer\handlers\PitcherPanel.py", line 41, in post
+    data = get_pitcher_panel_daily(pitcher, start, end, page, page_size, order_by, order)
+  File "D:\code\QcWebServer\data_manage\pitcher_panel.py", line 62, in get_pitcher_panel_daily
+    data = ck.execute(sql)
+  File "D:\code\QcWebServer\model\DataBaseUtils.py", line 62, in execute
+    return self.client.execute(sql)
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\clickhouse_driver\client.py", line 252, in execute
+    columnar=columnar
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\clickhouse_driver\client.py", line 447, in process_ordinary_query
+    columnar=columnar)
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\clickhouse_driver\client.py", line 113, in receive_result
+    return result.get_result()
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\clickhouse_driver\result.py", line 50, in get_result
+    for packet in self.packet_generator:
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\clickhouse_driver\client.py", line 129, in packet_generator
+    packet = self.receive_packet()
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\clickhouse_driver\client.py", line 146, in receive_packet
+    raise packet.exception
+clickhouse_driver.errors.ServerException: Code: 62.
+DB::Exception: Syntax error: failed at position 81 (line 3, col 21): (sum(cost),2) cost,
+                round(sum(first_order_amount),2) first_order_amount,
+               if(cost=0,0,round(first_order_amount/cost,4)) first_roi . Expected one of: UNION ALL, token, FROM, PREWHERE, WHERE, WITH, HAVING, LIMIT, SETTINGS, FORMAT, Comma, ORDER BY, INTO OUTFILE, GROUP BY. Stack trace:
+
+0. /server/clickhouse_build/../contrib/poco/Foundation/src/Exception.cpp:27: Poco::Exception::Exception(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int) @ 0xc0390cc in /clickhouse/bin/clickhouse
+1. /server/clickhouse_build/../src/Common/Exception.cpp:29: DB::Exception::Exception(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int) @ 0x5066519 in /clickhouse/bin/clickhouse
+2. /server/clickhouse_build/../src/Parsers/parseQuery.cpp:310: DB::parseQuery(DB::IParser&, char const*, char const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned long, unsigned long) (.cold) @ 0x4db0714 in /clickhouse/bin/clickhouse
+3. /server/clickhouse_build/../src/Interpreters/executeQuery.cpp:287: DB::executeQueryImpl(char const*, char const*, DB::Context&, bool, DB::QueryProcessingStage::Enum, bool, DB::ReadBuffer*, bool) @ 0x8f06380 in /clickhouse/bin/clickhouse
+4. /server/clickhouse_build/../src/Interpreters/executeQuery.cpp:718: DB::executeQuery(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, DB::Context&, bool, DB::QueryProcessingStage::Enum, bool, bool) @ 0x8f0a0dd in /clickhouse/bin/clickhouse
+5. /server/clickhouse_build/../programs/server/TCPHandler.cpp:257: DB::TCPHandler::runImpl() @ 0x50c1029 in /clickhouse/bin/clickhouse
+6. /server/clickhouse_build/../programs/server/TCPHandler.cpp:1252: DB::TCPHandler::run() @ 0x50c1f2c in /clickhouse/bin/clickhouse
+7. /server/clickhouse_build/../contrib/poco/Net/src/TCPServerConnection.cpp:57: Poco::Net::TCPServerConnection::start() @ 0x9e54827 in /clickhouse/bin/clickhouse
+8. /server/clickhouse_build/../contrib/libcxx/include/atomic:856: Poco::Net::TCPServerDispatcher::run() @ 0x9e54c1d in /clickhouse/bin/clickhouse
+9. /server/clickhouse_build/../contrib/poco/Foundation/include/Poco/Mutex_STD.h:132: Poco::PooledThread::run() @ 0xc0ab67f in /clickhouse/bin/clickhouse
+10. /server/clickhouse_build/../contrib/poco/Foundation/include/Poco/AutoPtr.h:205: Poco::ThreadImpl::runnableEntry(void*) @ 0xc0a8748 in /clickhouse/bin/clickhouse
+11. /server/clickhouse_build/../contrib/libcxx/include/memory:2615: void* std::__1::__thread_proxy<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void* (*)(void*), Poco::ThreadImpl*> >(void*) @ 0xc0a9fe9 in /clickhouse/bin/clickhouse
+12. start_thread @ 0x76db in /lib/x86_64-linux-gnu/libpthread-2.27.so
+13. clone @ 0x121a3f in /lib/x86_64-linux-gnu/libc-2.27.so
+
+[2020-12-23 20:40:51,786] - [ERROR] - 500 POST /data/pitcher_panel/daily (::1) 133.47ms
+[2020-12-23 20:42:16,015] - [INFO] - write pid 19792 ...
+[2020-12-23 20:42:16,021] - [INFO] - server start, listening on port 8008
+[2020-12-23 20:42:17,936] - [INFO] - 200 POST /data/pitcher_panel/daily (::1) 129.64ms
+[2020-12-23 20:42:41,242] - [INFO] - 200 POST /data/pitcher_panel/daily (::1) 38.12ms
+[2020-12-23 20:45:48,037] - [INFO] - D:\code\QcWebServer\handlers\PitcherPanel.py modified; restarting server

+ 89 - 0
logs/runlog20201224.log

@@ -0,0 +1,89 @@
+[2020-12-24 15:10:26,716] - [INFO] - write pid 20636 ...
+[2020-12-24 15:10:26,723] - [INFO] - server start, listening on port 8008
+[2020-12-24 15:10:54,735] - [INFO] - 200 POST /data/pitcher_panel/overview (::1) 237.05ms
+[2020-12-24 15:12:11,149] - [INFO] - write pid 8168 ...
+[2020-12-24 15:12:11,155] - [INFO] - server start, listening on port 8008
+[2020-12-24 15:12:13,547] - [INFO] - 200 POST /data/pitcher_panel/overview (::1) 1096.71ms
+[2020-12-24 15:13:20,357] - [INFO] - write pid 3512 ...
+[2020-12-24 15:13:20,362] - [INFO] - server start, listening on port 8008
+[2020-12-24 15:13:22,028] - [INFO] - 200 POST /data/pitcher_panel/overview (::1) 201.21ms
+[2020-12-24 15:13:59,393] - [INFO] - D:\code\QcWebServer\data_manage\pitcher_panel.py modified; restarting server
+[2020-12-24 15:14:00,415] - [INFO] - write pid 18456 ...
+[2020-12-24 15:14:00,421] - [INFO] - server start, listening on port 8008
+[2020-12-24 15:19:42,934] - [INFO] - D:\code\QcWebServer\data_manage\pitcher_panel.py modified; restarting server
+[2020-12-24 15:19:43,730] - [INFO] - write pid 996 ...
+[2020-12-24 15:19:43,736] - [INFO] - server start, listening on port 8008
+[2020-12-24 15:19:43,851] - [INFO] - write pid 4160 ...
+[2020-12-24 15:19:46,257] - [INFO] - 200 POST /data/pitcher_panel/overview (::1) 289.99ms
+[2020-12-24 15:20:41,249] - [INFO] - D:\code\QcWebServer\data_manage\pitcher_panel.py modified; restarting server
+[2020-12-24 15:20:42,288] - [INFO] - write pid 20948 ...
+[2020-12-24 15:20:42,295] - [INFO] - server start, listening on port 8008
+[2020-12-24 15:28:05,310] - [INFO] - D:\code\QcWebServer\data_manage\pitcher_panel.py modified; restarting server
+[2020-12-24 15:37:47,271] - [INFO] - write pid 13612 ...
+[2020-12-24 15:37:47,276] - [INFO] - server start, listening on port 8008
+[2020-12-24 15:37:53,210] - [INFO] - 200 POST /data/pitcher_panel/overview (::1) 1978.11ms
+[2020-12-24 15:38:16,526] - [INFO] - 200 POST /data/pitcher_panel/overview (::1) 331.67ms
+[2020-12-24 15:38:16,535] - [INFO] - D:\code\QcWebServer\data_manage\pitcher_panel.py modified; restarting server
+[2020-12-24 15:38:17,465] - [INFO] - write pid 20300 ...
+[2020-12-24 15:38:17,470] - [INFO] - server start, listening on port 8008
+[2020-12-24 15:38:23,252] - [ERROR] - Uncaught exception POST /data/pitcher_panel/overview (::1)
+HTTPServerRequest(protocol='http', host='localhost:8008', method='POST', uri='/data/pitcher_panel/overview', version='HTTP/1.1', remote_ip='::1')
+Traceback (most recent call last):
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\tornado\web.py", line 1702, in _execute
+    result = method(*self.path_args, **self.path_kwargs)
+  File "D:\code\QcWebServer\handlers\PitcherPanel.py", line 48, in post
+    data = get_pitcher_panel_overview(pitcher)
+  File "D:\code\QcWebServer\data_manage\pitcher_panel.py", line 88, in get_pitcher_panel_overview
+    print(sql)
+OSError: [Errno 22] Invalid argument
+[2020-12-24 15:38:23,271] - [ERROR] - 500 POST /data/pitcher_panel/overview (::1) 19.95ms
+[2020-12-24 15:38:26,154] - [ERROR] - Uncaught exception POST /data/pitcher_panel/overview (::1)
+HTTPServerRequest(protocol='http', host='localhost:8008', method='POST', uri='/data/pitcher_panel/overview', version='HTTP/1.1', remote_ip='::1')
+Traceback (most recent call last):
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\tornado\web.py", line 1702, in _execute
+    result = method(*self.path_args, **self.path_kwargs)
+  File "D:\code\QcWebServer\handlers\PitcherPanel.py", line 48, in post
+    data = get_pitcher_panel_overview(pitcher)
+  File "D:\code\QcWebServer\data_manage\pitcher_panel.py", line 88, in get_pitcher_panel_overview
+    print(sql)
+OSError: [Errno 22] Invalid argument
+[2020-12-24 15:38:26,154] - [ERROR] - 500 POST /data/pitcher_panel/overview (::1) 1.00ms
+[2020-12-24 15:38:33,820] - [INFO] - write pid 11808 ...
+[2020-12-24 15:38:54,182] - [INFO] - write pid 11116 ...
+[2020-12-24 15:38:54,187] - [INFO] - server start, listening on port 8008
+[2020-12-24 15:38:57,710] - [INFO] - 200 POST /data/pitcher_panel/overview (::1) 217.90ms
+[2020-12-24 15:41:04,303] - [INFO] - write pid 18900 ...
+[2020-12-24 15:41:04,309] - [INFO] - server start, listening on port 8008
+[2020-12-24 15:41:06,037] - [INFO] - 200 POST /data/pitcher_panel/overview (::1) 169.17ms
+[2020-12-24 15:41:14,089] - [INFO] - write pid 21308 ...
+[2020-12-24 15:41:14,097] - [INFO] - server start, listening on port 8008
+[2020-12-24 15:41:15,805] - [INFO] - 200 POST /data/pitcher_panel/overview (::1) 286.31ms
+[2020-12-24 15:47:33,602] - [INFO] - D:\code\QcWebServer\data_manage\pitcher_panel.py modified; restarting server
+[2020-12-24 15:47:34,571] - [INFO] - write pid 19644 ...
+[2020-12-24 15:47:34,577] - [INFO] - server start, listening on port 8008
+[2020-12-24 15:55:08,545] - [INFO] - write pid 20716 ...
+[2020-12-24 15:55:30,424] - [INFO] - write pid 20940 ...
+[2020-12-24 15:55:30,429] - [INFO] - server start, listening on port 8008
+[2020-12-24 15:55:32,672] - [ERROR] - Uncaught exception POST /data/pitcher_panel/overview (::1)
+HTTPServerRequest(protocol='http', host='localhost:8008', method='POST', uri='/data/pitcher_panel/overview', version='HTTP/1.1', remote_ip='::1')
+Traceback (most recent call last):
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\tornado\web.py", line 1702, in _execute
+    result = method(*self.path_args, **self.path_kwargs)
+  File "D:\code\QcWebServer\handlers\PitcherPanel.py", line 49, in post
+    self.write_json(data)
+  File "D:\code\QcWebServer\handlers\HandlerBase.py", line 27, in write_json
+    self.write(json.dumps({'status': {'msg': msg, "RetCode": status_code}, 'data': data}))
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\simplejson\__init__.py", line 395, in dumps
+    return _default_encoder.encode(obj)
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\simplejson\encoder.py", line 296, in encode
+    chunks = self.iterencode(o, _one_shot=True)
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\simplejson\encoder.py", line 378, in iterencode
+    return _iterencode(o, 0)
+  File "D:\workspace\py_env\QcWebServer-LLP_2JqD\lib\site-packages\simplejson\encoder.py", line 273, in default
+    o.__class__.__name__)
+TypeError: Object of type date is not JSON serializable
+[2020-12-24 15:55:32,722] - [ERROR] - 500 POST /data/pitcher_panel/overview (::1) 436.42ms
+[2020-12-24 15:57:01,913] - [INFO] - write pid 15612 ...
+[2020-12-24 15:57:01,920] - [INFO] - server start, listening on port 8008
+[2020-12-24 15:57:06,227] - [INFO] - 200 POST /data/pitcher_panel/overview (::1) 215.64ms
+[2020-12-24 15:58:40,133] - [INFO] - 200 POST /data/pitcher_panel/channel (::1) 49.54ms

+ 12 - 0
model/CommonUtils.py

@@ -0,0 +1,12 @@
+
+
+def get_dict_list(key,value_list):
+    """把一个列表的数据变成字典
+    :param key []
+    :param value_list [[]]
+    :return [{},{}]
+    """
+    data_list=[]
+    for i in value_list:
+        data_list.append(dict(zip(key, i)))
+    return data_list

+ 621 - 0
model/DataBaseOperation.py

@@ -0,0 +1,621 @@
+"""
+@desc 数据库操作方法封装
+@auth  chenkai
+@date 2020/11/19
+@py_version py3.6
+"""
+import pymysql
+import logging as log
+import pandas as pd
+import time
+from model.log import logger
+log = logger()
+pd.set_option('display.max_columns', None)
+pd.set_option('display.width', 1000)
+MYSQL_DEBUG = 1
+
+
+class MysqlOperation:
+
+    def __init__(self, host, user, passwd, db, port=3306):
+        try:
+            self.conn = pymysql.connect(host=host,
+                                        user=user,
+                                        passwd=passwd,
+                                        db=db,
+                                        charset='utf8mb4',
+                                        port=port)
+            self.cursor = self.conn.cursor()
+        except Exception as e:
+            log.info(e)
+
+
+    def set_dict_cursor(self):
+        """
+        设置字典形式取数据
+        """
+        self.cursor = self.conn.cursor(pymysql.cursors.DictCursor)
+    
+    def getData(self, sql, args=None):
+        """
+
+        :param sql:
+        :param args:
+        :return: tuple(tuple)
+        """
+
+        start = time.time()
+        self.cursor.execute(sql, args=args)
+        result = self.cursor.fetchall()
+        if MYSQL_DEBUG:
+            sql_str = sql % tuple(args) if args else sql
+            log.info('sql: \n' + sql_str)
+            log.info('sql cost: %s' % (time.time() - start))
+        return result
+
+    def get_data_list(self,sql,arg=None):
+        """
+        :param sql:
+        :param arg:
+        :return: list[list]
+        """
+        data=self.getData(sql,arg)
+        li=[]
+        for i in data:
+            li.append(list(i))
+        return li
+
+
+
+    def execute(self, sql):
+        start = time.time()
+        self.cursor.execute(sql)
+        self.conn.commit()
+        if MYSQL_DEBUG:
+
+            log.info('sql: \n' + sql)
+            log.info('sql cost: %s' % (time.time() - start))
+
+
+    def getOne(self,sql, args=None):
+        result = self.getData(sql, args)
+
+        return result[0][0]
+
+    def getData_pd(self, sql, args=None):
+        start = time.time()
+        # if args:
+        #     log.debug(sql % tuple(args))
+        # else:
+        #     log.debug(sql)
+        self.cursor.execute(sql, args=args)
+        num_fields = len(self.cursor.description)
+        field_names = [i[0] for i in self.cursor.description]
+        df = self.cursor.fetchall()
+
+        df = pd.DataFrame(data=list(df), columns=field_names)
+
+        if MYSQL_DEBUG:
+            sql_str = sql % tuple(args) if args else sql
+            log.info('sql: \n' + sql_str)
+            log.info('sql cost: %s' % (time.time() - start))
+        return df
+
+    def insertData(self, sql, args=None):
+        # if args:
+        #     log.debug(sql % tuple(args))
+        # else:
+        #     log.debug(sql)
+        start = time.time()
+        self.cursor.execute(sql, args=args)
+
+        if MYSQL_DEBUG:
+            sql_str = sql % tuple(args) if args else sql
+            log.info('sql: \n' + sql_str)
+            log.info('sql cost: %s' % (time.time() - start))
+        self.conn.commit()
+
+    def executeWithoutCommit(self, sql, args=None):
+        return self.cursor.execute(sql, args=args)
+
+    def commit(self):
+        self.conn.commit()
+
+    def insertorupdate(self, table, keys, tags, tagvalue, flag, *args):
+        """
+        :param table: 表名
+        :param keys: 联合主键名元组
+        :param tags: 字段名元组
+        :param tagvalue: 字段值
+        :param args: 主键值
+        :param flag: 控制是否打印日志
+        :return:
+
+        """
+
+        # log.info(tags)
+        sql = "INSERT INTO " + table + " ("
+        sql += ",".join(keys) + ","
+        sql += ",".join(tags)
+        sql += ") SELECT "
+        sql += "%s," * len(keys)
+        sql += ("%s," * len(tags))[:-1]
+        sql += " FROM DUAL WHERE NOT EXISTS (SELECT id FROM " + table
+        sql += " WHERE "
+        for _ in keys:
+            sql += _ + "=%s AND "
+
+        sql = sql[:-4]
+        sql += "LIMIT 1)"
+        arg = list(args)
+        arg.extend(tagvalue)
+        arg.extend(list(args))
+
+        rows = self.cursor.execute(sql, args=arg)
+        if rows == 0:
+            sql = "UPDATE " + table + " SET "
+            for _ in tags:
+                sql += _ + "=%s,"
+            sql = sql[:-1]
+            sql += " WHERE "
+            for _ in keys:
+                sql += _ + "=%s AND "
+            sql = sql[:-4]
+            arg = []
+            arg.extend(tagvalue)
+            arg.extend(list(args))
+            self.cursor.execute(sql, args=arg)
+        if flag:
+            log.info(sql % tuple(arg))
+        self.conn.commit()
+
+    def _insertorupdate(self, table, keys, tags, tag_value, flag, key_value, update=False):
+
+        if not update:
+            sql = "INSERT INTO " + table + " ("
+            sql += ",".join(keys) + ","
+            sql += ",".join(tags)
+            sql += ") SELECT "
+            sql += "%s," * len(keys)
+            sql += ("%s," * len(tags))[:-1]
+            sql += " FROM DUAL WHERE NOT EXISTS (SELECT id FROM " + table
+            sql += " WHERE "
+            for _ in keys:
+                sql += _ + "=%s AND "
+
+            sql = sql[:-4]
+            sql += "LIMIT 1)"
+            arg = list(key_value)
+            arg.extend(tag_value)
+            arg.extend(list(key_value))
+
+            rows = self.cursor.execute(sql, args=arg)
+            if rows == 0:
+                sql = "UPDATE " + table + " SET "
+                for _ in tags:
+                    sql += _ + "=%s,"
+                sql = sql[:-1]
+                sql += " WHERE "
+                for _ in keys:
+                    sql += _ + "=%s AND "
+                sql = sql[:-4]
+                arg = []
+                arg.extend(tag_value)
+                arg.extend(list(key_value))
+                self.cursor.execute(sql, args=arg)
+            if flag:
+                log.info(sql % tuple(arg))
+        else:
+
+            sql = "UPDATE " + table + " SET "
+            for _ in tags:
+                sql += _ + "=%s,"
+            sql = sql[:-1]
+            sql += " WHERE "
+            for _ in keys:
+                sql += _ + "=%s AND "
+            sql = sql[:-4]
+            arg = []
+            arg.extend(tag_value)
+            arg.extend(list(key_value))
+            self.cursor.execute(sql, args=arg)
+
+            if flag:
+                log.info(sql % tuple(arg))
+
+    def _insert_on_duplicate(self, table, keys, tags, tag_value, flag, key_value):
+        name_all = list(keys)
+        name_all.extend(tags)
+        arg = list(key_value)
+        arg.extend(tag_value)
+        arg.extend(tag_value)
+        sql_name = '(' + ','.join(name_all) + ')'
+        sql_value = '(' + ','.join(['%s'] * len(name_all)) + ')'
+        sql_update = ','.join([_ + '=%s' for _ in tags])
+        sql = """
+            insert into %s
+            %s
+            VALUES %s
+            ON duplicate key UPDATE %s
+        """ % (table, sql_name, sql_value, sql_update)
+        self.cursor.execute(sql, args=arg)
+        if flag:
+            log.debug(sql % tuple(arg))
+
+    def insertorupdatemany(self, table, keys, tags, tag_values, key_values, flag=False, unique_key=False, update=False):
+        """
+        :param table: 表名
+        :param keys: 联合主键名元组
+        :param tags: 字段名元组
+        :param tag_values: 字段值组(list or pd.DataFrame)
+        :param key_values: 主键值组(list or pd.DataFrame)
+        :param flag: 控制是否打印日志
+        :param unique_key: keys 是否为table的 unique_key
+        :return:
+        ps: 效率(外网): rows / 50;  1000以上更新使用
+        """
+        if isinstance(tag_values, pd.DataFrame):
+            list_tag_value = [list(tag_values.iloc[_, :]) for _ in range(len(tag_values))]
+        else:
+            list_tag_value = list(tag_values)
+        if isinstance(key_values, pd.DataFrame):
+            list_key_value = [list(key_values.iloc[_, :]) for _ in range(len(key_values))]
+        else:
+            list_key_value = list(key_values)
+        for _ in range(len(list_tag_value)):
+            tag_value = list_tag_value[_]
+            key_value = list_key_value[_]
+            if unique_key:
+                self._insert_on_duplicate(table, keys, tags, tag_value, flag, key_value)
+            else:
+                self._insertorupdate(table, keys, tags, tag_value, flag, key_value, update)
+        self.conn.commit()
+
+    def _check_repeat_key(self, key_list):
+        tmp = list(map(lambda x: tuple(x), key_list))
+        if len(tmp) == len(set(tmp)):
+            return False
+        else:
+            last_data = -1
+            repeat_key = set()
+            for i in sorted(tmp):
+                if last_data == i:
+                    repeat_key.add(i)
+                if len(repeat_key) >= 10:
+                    break
+                last_data = i
+            log.error('Reject repeated keys')
+            log.error('repeat_key: %s' % repeat_key)
+            return True
+
+    def _convert_to_list(self, data):
+        if isinstance(data, pd.DataFrame):
+            # np.nan != np.nan 从而判断值为np.nan
+            list_data = [map(lambda x: None if x != x else x, list(data.iloc[_, :])) for _ in range(len(data))]
+            li =[]
+            for  i in list_data:
+                li.append(list(i))
+            list_data = li
+
+        else:
+            list_data = list(data)
+
+        return list_data
+
+    def _get_exist_keys_index(self, table, keys, key_values, flag=False):
+        list_sql_when = []
+        list_tmp = []
+
+        for i in range(len(key_values)):
+            sql_when = """when (%s)=(%s) then %s""" % (','.join(keys), ','.join(['%s'] * len(key_values[i])), i)
+            list_sql_when.append(sql_when)
+            list_tmp.extend(key_values[i])
+        list_sql_condition = []
+        for i in range(len(key_values)):
+            # sql_condition_old = """(%s)=(%s)""" % (','.join(keys), ','.join(['%s'] * len(key_values[i])))
+            row_condition_list = map(lambda x: '%s = %%s' % x, keys)
+            sql_condition = """(%s)""" % ' and '.join(row_condition_list)
+            # print sql_condition_old, sql_condition
+            list_sql_condition.append(sql_condition)
+            list_tmp.extend(key_values[i])
+        sql_where = ' or '.join(list_sql_condition)
+
+        sql_case = '\n'.join(list_sql_when)
+        sql = """
+            select
+            case
+                %s
+            end
+            from %s
+            where %s
+        """ % (sql_case, table, sql_where)
+        if flag:
+            log.info(sql % tuple(list_tmp))
+
+        self.cursor.execute(sql, tuple(list_tmp))
+        print()
+        result = self.cursor.fetchall()
+        return map(lambda x: x[0], result)
+
+    def insertorupdatemany_v2(self, table, keys, tags, tag_values, key_values, flag=False, split=80):
+        """
+        更新插入多条数据(无key时自动插入, 有keys时更新)
+        :param table: 表名
+        :param keys: 联合主键名元组
+        :param tags: 字段名元组
+        :param tag_values: 字段值组(list or pd.DataFrame)
+        :param key_values: 主键值组(list or pd.DataFrame)
+        :param flag: 控制是否打印日志
+        :param split: 切割阈值
+        :return:
+
+        ps: 效率(外网): rows^2 / 50000;  rows以split为单位分批更新
+        """
+        if not isinstance(tag_values, (tuple, list, pd.DataFrame)):
+            log.error('Type Error')
+            exit(-1)
+            return
+        if len(tag_values) > split:
+            length = len(tag_values)
+            for i in range(0, length, split):
+                start, finish = i, i + split
+                self.insertorupdatemany_v2(table, keys, tags, tag_values[start:finish], key_values[start:finish], flag, split=split)
+            return
+        if len(key_values) == 0 or len(tag_values) == 0:
+            log.debug('insert or update 0 rows')
+            return
+        tag_values = self._convert_to_list(tag_values)
+        key_values = self._convert_to_list(key_values)
+        assert self._check_repeat_key(key_values) == False
+
+        exist_key_index = list(self._get_exist_keys_index(table, keys, key_values, flag))
+
+        new_key_index = list(set(range(len(key_values))) - set(exist_key_index))
+        update_keys = list(map(lambda x: key_values[x], exist_key_index))
+        update_tags = list(map(lambda x: tag_values[x], exist_key_index))
+        insert_keys = list(map(lambda x: key_values[x], new_key_index))
+        insert_tags = list(map(lambda x: tag_values[x], new_key_index))
+
+        self.insert_many(table=table,
+                         keys=keys,
+                         tags=tags,
+                         tag_values=insert_tags,
+                         key_values=insert_keys,
+                         flag=flag)
+
+        self.update_many(table=table,
+                         keys=keys,
+                         tags=tags,
+                         tag_values=update_tags,
+                         key_values=update_keys,
+                         flag=flag,
+                         split=split)
+
+    def insertorupdatemany_v3(self, df, table, keys, tags, flag=False, split=80):
+        self.insertorupdatemany_v2(
+            table=table,
+            keys=keys,
+            tags=tags,
+            tag_values=df[tags],
+            key_values=df[keys],
+            flag=flag,
+            split=split
+        )
+
+    def _get_s_format(self, data):
+        """
+        Args:
+            data: [[featureA1, featureB1, ...], [featureA2, featureB2, ...], ...]
+
+        Returns:
+            format of %s and real value
+
+        Example:
+            [['2017-07-01', 78], ['2017-07-01', 1]] ->
+                     ('((%s, %s), (%s, %s))', ['2017-07-01', 78, '2017-07-01', 1])
+        """
+        list_tmp_s = []
+        values = []
+        for _ in data:
+            tmp_s = ','.join(len(_) * ['%s'])
+            values.extend(_)
+            if len(_) > 1:
+                tmp_s = '(' + tmp_s + ')'
+            list_tmp_s.append(tmp_s)
+        format_s = '(' + ','.join(list_tmp_s) + ')'
+        return format_s, values
+
+    def delete_by_key(self, table, keys, key_values, flag=False):
+        """
+
+        Args:
+            table: 表名
+            keys: 联合主键名元组
+            key_values: 主键值组(list or pd.DataFrame)
+            flag: 控制是否打印日志
+
+        Examples:
+            delete_by_key('table_test', keys=['date'], key_values=[['2017-07-01'], ['2017-07-02']], flag=False)
+            delete_by_key('table_test', keys=['date'], key_values=['2017-07-01'], flag=False)
+        """
+        if len(key_values) == 0:
+            return
+        if not (isinstance(key_values[0], (list, tuple)) or isinstance(key_values, pd.DataFrame)):
+            key_values_list = [key_values]
+        else:
+            key_values_list = self._convert_to_list(key_values)
+        sql_keys = '(' + ','.join(keys) + ')'
+
+        contact_s, values_s = self._get_s_format(key_values_list)
+        sql_del = """
+            delete from %s
+            where %s in %s
+        """ % (table, sql_keys, contact_s)
+        if flag:
+            log.debug(sql_del % tuple(values_s))
+        self.cursor.execute(sql_del, tuple(values_s))
+        self.conn.commit()
+
+    def insert_many(self, table, keys, tags, tag_values, key_values, flag=False, split=80):
+        """
+        直接插入多条数据
+        :param table: 表名
+        :param keys: 联合主键名元组
+        :param tags: 字段名元组
+        :param tag_values: 字段值组(list or pd.DataFrame)
+        :param key_values: 主键值组(list or pd.DataFrame)
+        :param flag: 控制是否打印日志
+        :return:
+
+        Examples: 参照 insertorupdatemany_v2
+        insert into table
+        (count_date, cid, tag1, tag2)
+        values ('2017-01-01', 10, 1, 'a'), ('2017-01-02', 20, 2, 'b'), ...
+        """
+        if len(key_values) == 0 or len(tag_values) == 0:
+            log.debug('insert 0 rows')
+            return
+        if len(tag_values) > split:
+            length = len(tag_values)
+            for i in range(0, length, split):
+                start, finish = i, i + split
+                self.insert_many(table, keys, tags, tag_values[start:finish], key_values[start:finish], flag, split=split)
+            return
+        tag_values = self._convert_to_list(tag_values)
+        key_values = self._convert_to_list(key_values)
+
+        feature_total = "(" + ",".join(keys + tags) + ")"
+        tmp_s = "(" + ",".join(["%s"] * len(keys + tags)) + ")"
+        tmp_s_concat = ",\n".join([tmp_s] * len(key_values))
+        sql_insert = """
+                Insert into %s
+                %s
+                values %s""" % (table, feature_total, tmp_s_concat)
+        value_insert = []
+        for _ in zip(key_values, tag_values):
+            value_insert.extend(_[0] + _[1])
+        if flag:
+            log.debug(sql_insert % tuple(value_insert))
+        t0 = time.time()
+
+        self.cursor.execute(sql_insert,tuple(value_insert))
+        log.debug('insert %s rows, cost: %s' % (len(key_values), time.time() - t0))
+        self.conn.commit()
+
+    def update_many(self, table, keys, tags, tag_values, key_values, flag=False, split=80):
+        """
+        更新多条数据(无key时不会自动插入)
+        :param table: 表名
+        :param keys: 联合主键名元组
+        :param tags: 字段名元组
+        :param tag_values: 字段值组(list or pd.DataFrame)
+        :param key_values: 主键值组(list or pd.DataFrame)
+        :param flag: 控制是否打印日志
+        :param split: 分批更新量
+        :return:
+
+        Examples: 参照 insertorupdatemany_v2
+        # 单条 update sql tag1=1, tag2='a' 插入到 (count_date, cid) =('2017-01-01', 10)
+        update table
+        set tag1=1, tag2='a'
+        where (count_date, cid) =('2017-01-01', 10)
+
+        # 多条组合 update sql
+        # tag1=1, tag2='a' 插入到 (count_date, cid) =('2017-01-01', 10);
+        # tag1=1, tag2='a' 插入到 (count_date, cid) =('2017-01-01', 10);
+        update table
+        set tag1 = case 
+            when (count_date, cid)=('2017-01-01', 10) then 1
+            when (count_date, cid)=('2017-01-02', 20) then 2
+            ...
+            ,
+            tag_2 = case
+            when (count_date, cid)=('2017-01-01', 10) then 'a'
+            when (count_date, cid)=('2017-01-02', 20) then 'b'
+            ...
+        where (count_date, cid)=('2017-01-01', 10) or (count_date, cid)=('2017-01-02', 20) or ...
+
+        """
+        if len(tag_values) > split:
+            length = len(tag_values)
+            for i in range(0, length, split):
+                start, finish = i, i + split
+                self.update_many(table, keys, tags, tag_values[start:finish], key_values[start:finish], flag, split=split)
+            return
+        if len(key_values) == 0 or len(tag_values) == 0:
+            log.debug('update 0 rows')
+            return
+
+        tag_values = self._convert_to_list(tag_values)
+        key_values = self._convert_to_list(key_values)
+
+        if self._check_repeat_key(key_values):
+            return
+
+        update_value = []
+        sql_keys = ','.join(keys)
+        if len(keys) > 1:
+            sql_keys = '(' + sql_keys + ')'
+
+        sql_key_values = ','.join(['%s'] * len(keys))
+        if len(keys) > 1:
+            sql_key_values = '(' + sql_key_values + ')'
+
+        sql_set_list = []
+        for i in range(len(tags)):
+            sql_when_list = []
+            for j in range(len(tag_values)):
+                sql_when = """when %s=%s then %s """ % (sql_keys, sql_key_values, '%s')
+                update_value.extend(key_values[j])
+                update_value.append(tag_values[j][i])
+                sql_when_list.append(sql_when)
+            sql_when_concat = '\n\t'.join(sql_when_list)
+            sql_set = """%s = case \n\t %s\n end""" % (tags[i], sql_when_concat)
+            sql_set_list.append(sql_set)
+        for _ in key_values:
+            update_value.extend(_)
+        sql_set_concat = ',\n'.join(sql_set_list)
+
+        list_sql_condition = []
+        for i in range(len(key_values)):
+            row_condition_list = map(lambda x: '%s = %%s' % x, keys)
+            sql_condition = """(%s)""" % ' and '.join(row_condition_list)
+            list_sql_condition.append(sql_condition)
+        sql_where = ' or '.join(list_sql_condition)
+
+        # condition = ' or\n\t'.join([sql_keys + '=' + sql_key_values] * len(tag_values))
+        # print condition
+        sql = """update %s\n set %s\n where %s""" % (table, sql_set_concat, sql_where)
+        if flag:
+            log.info(sql % tuple(update_value))
+        t0 = time.time()
+        self.cursor.execute(sql, tuple(update_value))
+        self.conn.commit()
+        log.debug('update %s rows, cost: %s' % (len(key_values), time.time() - t0))
+
+
+    def getColumn(self,table,flag=0):
+        "获取表的所有列"
+        sql="SELECT `COLUMN_NAME` FROM `INFORMATION_SCHEMA`.`COLUMNS` " \
+            "WHERE `TABLE_NAME`='{}' ORDER BY ordinal_position".format(table)
+        self.cursor.execute(sql)
+        a= self.cursor.fetchall()
+        str=''
+        li=[]
+        for i in a:
+            str+=i[0]+','
+            li.append(i[0])
+
+        if flag:
+            return li
+        else:
+            return str[:-1]
+
+
+
+
+
+
+
+
+

+ 114 - 0
model/DataBaseUtils.py

@@ -0,0 +1,114 @@
+"""
+@desc 数据库连接
+@auth chenkai
+@date 2020/11/19
+"""
+from model.DataBaseOperation import MysqlOperation
+from model.log import logger
+import yaml
+import os
+from clickhouse_driver.client import Client
+import pandas as pd
+log = logger()
+
+
+class MysqlUtils:
+    _quchen_text = None
+
+    def __init__(self):
+        p_path =os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir))
+        path = os.path.join(p_path,"config", "db_config.yaml")
+        f = open(path, encoding="utf-8")
+        self.config = yaml.load(f.read(), Loader=yaml.FullLoader)
+
+    @property
+    def quchen_text(self):
+
+        conf = self.config['quchen_text']
+        self._quchen_text = MysqlOperation(host=conf['host'],
+                                      user=conf['user'],
+                                      passwd=conf['passwd'],
+                                      db=conf['db'])
+        return self._quchen_text
+
+
+
+    def find_db(self, db):
+
+        if db == "quchen_text":
+            self._quchen_text = self._quchen_text
+            return self._quchen_text
+
+        else:
+            log.debug("输入数据库有误")
+
+    def close(self):
+        if self._quchen_text:
+            self._quchen_text.cursor.close()
+            self._quchen_text.conn.close()
+
+
+class CkUtils:
+
+    def __init__(self):
+        self.client = Client(host='cc-bp1h3yc7o3g3o7k64o.ads.aliyuncs.com',
+                           user='qucheng_ck',
+                           password='Qc123456',
+                           port='3306',
+                           send_receive_timeout=5)
+
+    def execute(self, sql):
+
+        return self.client.execute(sql)
+
+    def getData_pd(self, sql, col):
+        data = self.execute(sql)
+        df = pd.DataFrame(data, columns=col)
+        return df
+
+    def getColumns(self, table, is_list=False):
+        """默认返回列表"""
+        data = self.execute("desc " + table)
+        li = []
+        str = ''
+        for i in data:
+            li.append(i[0])
+            str += i[0] + ','
+        if is_list:
+            return li
+        else:
+            return str[:-1]
+
+
+
+    def insertMany(self,table,col,data):
+        """
+        :param table: 表名 srt
+        :param col:   字段名 srt   eg: ”a,b,c“
+        :param data:  tuple/list
+        :return:
+        """
+        max=200
+        sql="insert into {} ({}) values ".format(table,col)
+
+        if len(data) == 0:
+            log.debug("data.len==0")
+            return
+        if len(data) <= max:
+            sql = sql+str(data)[1:-1]
+            # log.info(sql)
+            # log.info("insert {} rows".format(len(data)))
+            self.execute(sql)
+            return
+        else:
+
+            sql2=sql+str(data[:max])[1:-1]
+            # log.info(sql2)
+            self.execute(sql2)
+            # log.info("insert {} rows".format(max))
+            self.insertMany(table,col,data[max:])
+
+
+if __name__ == '__main__':
+    p_path = os.path.dirname(os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir)))
+    print(os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir)))

+ 273 - 0
model/DateUtils.py

@@ -0,0 +1,273 @@
+import time
+from datetime import date, datetime, timedelta
+import calendar
+from dateutil.relativedelta import relativedelta
+
+
+class DateUtils:
+    """
+    时间相关函数封装
+    """
+
+    def __init__(self):
+        self.today = datetime.strptime(datetime.today().strftime("%Y-%m-%d"), "%Y-%m-%d")
+        self.daydelta = timedelta(days=1)
+        self.now = datetime.now()
+
+    def getDateLists(self, begin, end):
+        """
+        返回一个时间列表
+        """
+        interval = self.getInterval(begin, end)
+        return [self.getLastDays(begin, -x) for x in range(interval + 1)]
+
+    def getMonthLists(self, begin, end):
+        begin_date = datetime.strptime(begin, "%Y-%m").date()
+        end_date = datetime.strptime(end, '%Y-%m').date()
+        temp = end_date
+        month_list = []
+        while temp >= begin_date:
+            month_list.append(temp.strftime('%Y-%m'))
+            temp = self.get_before_month(temp.year, temp.month, 1, 1)
+        month_list.reverse()
+        return month_list
+
+    def getLastDays(self, begin, interval):
+        """
+        :param begin:
+        :param interval: 正数是之前几天, 负数是之后几天
+        :return:
+        """
+        start = datetime(int(begin[0:4]), int(begin[5:7]), int(begin[8:10]))
+        delta = timedelta(days=1)
+        if interval < 0:
+            for _ in range(0, -interval):
+                start = start + delta
+        else:
+            for _ in range(0, interval):
+                start = start - delta
+        return start.strftime("%Y-%m-%d")
+
+    def get_n_month_ago_begin(self, begin, n):
+        year = int(begin[:4])
+        month = int(begin[5:7])
+        if n > 0:
+            for i in range(0, n):
+                month -= 1
+                if month == 0:
+                    month = 12
+                    year -= 1
+        else:
+            for i in range(0, -n):
+                if month == 12:
+                    month = 0
+                    year += 1
+                month += 1
+        return date(year, month, 1).strftime('%Y-%m')
+
+
+
+    def get_n_days(self, interval=0, flag=0):
+        """
+        负数,过去的几天
+        正数,未来的几天
+        :param interval:
+        :param flag: 1 返回 timedelta
+        :return:
+        """
+        start = self.today
+        if interval < 0:
+            for _ in range(0, -interval):
+                start = start - self.daydelta
+        else:
+            for _ in range(0, interval):
+                start = start + self.daydelta
+        if flag == 1:
+            return start
+        else:
+            return start.strftime("%Y-%m-%d")
+
+    def getNow(self):
+        """
+        获取当天时间
+        :return: 当天时间的字符串
+        """
+        now = datetime.now()
+        return now.strftime("%Y-%m-%d")
+
+    def getWeek(self, begin):
+        return datetime(int(begin[0:4]), int(begin[5:7]), int(begin[8:10])).strftime("%w")
+
+    def get_today_before_month(self, n):
+        """
+        获取之前n个月
+        :param n:
+        :return:
+        """
+        year = time.localtime()[0]
+        month = time.localtime()[1]
+        for i in range(0, n):
+            month -= 1
+            if month == 0:
+                month = 12
+                year -= 1
+        return year, month
+
+    def get_one_month_ago(self, flag=0):
+        """
+        返回一个月前的时间, 默认返回格式化时间字符串
+        flag 1 返回 datetime
+        :param flag:
+        :return:
+        """
+        x = self.today-relativedelta(months=1)
+        if flag == 1:
+            return x
+        else:
+            return x.strftime("%Y-%m-%d")
+
+    def get_today_before_month_list(self, n=0):
+        year = time.localtime()[0]
+        month = time.localtime()[1]
+        ret = []
+        for i in range(0, n):
+            month -= 1
+            if month == 0:
+                month = 12
+                year -= 1
+            if month >= 10:
+                ret.append(str(year) + "-" + str(month) + "-" + "01")
+            else:
+                ret.append(str(year) + "-0" + str(month) + "-" + "01")
+        return ret
+
+    def get_before_month(self, year, month, day, n):
+        for i in range(0, n):
+            month -= 1
+            if month == 0:
+                month = 12
+                year -= 1
+        day = min(day, calendar.monthrange(year, month)[1])
+        return date(year, month, day)
+
+    def getInterval(self, begin, end):
+        t1 = datetime(int(begin[0:4]), int(begin[5:7]), int(begin[8:10]))
+        t2 = datetime(int(end[0:4]), int(end[5:7]), int(end[8:10]))
+        return (t2 - t1).days
+
+    def month_first_day(self, flag=False):
+        """
+        返回当月第一天
+        若为1号,则返回上个月1
+        :param flag:
+        :return:
+        """
+        if self.today.day == 1:
+            # 如果当日是月初1号,则返回上月1号
+            if self.today.month == 1:
+                tmp = date(self.today.year - 1, 12, 1)
+            else:
+                tmp = date(self.today.year, self.today.month - 1, 1)
+        else:
+            tmp = date(self.today.year, self.today.month, 1)
+        return tmp if flag else tmp.strftime("%Y-%m-%d")
+
+    def get_today(self, flag=False):
+        return self.today if flag else self.today.strftime("%Y-%m-%d")
+
+    def get_n_pre_month_first_day(self, n, flag=False):
+        """
+        获取 n 个月前第一天
+        """
+        r = self.get_before_month(self.today.year, self.today.month, 1, n)
+        return r if flag else r.strftime("%Y-%m-%d")
+
+    def get_n_month_ago(self, n, flag=0):
+        d = self.get_before_month(self.today.year, self.today.month, self.today.day, n)
+        return d.strftime("%Y-%m-%d") if flag == 0 else d
+
+    def get_week_ago(self, flag=False):
+        """
+        :param: None
+        :return: 7 days ago
+        """
+        tmp = (self.today - timedelta(days=7))
+        return tmp if flag else tmp.strftime("%Y-%m-%d")
+
+    def get_week_first_day(self, flag=False):
+
+        """
+        返回当前天的一周开始
+        :param flag:
+        :return:
+        """
+        # print self.today.day
+        if self.today.weekday() == 0:
+            # 如果当天是周一,则返回上周一日期
+            tmp = self.today - timedelta(days=7)
+        else:
+            tmp = self.today - timedelta(days=self.today.weekday())
+
+        return tmp if flag else tmp.strftime("%Y-%m-%d")
+
+    def get_one_day_ago(self, flag=False):
+        """
+        :param: None
+        :return: 1 day ago
+        """
+        tmp = (self.today - timedelta(days=1))
+        return tmp if flag else tmp.strftime("%Y-%m-%d")
+
+    def get_start(self, s_start=date.today().strftime("%Y-%m-%d")):
+        return datetime(int(s_start[0:4]), int(s_start[5:7]), int(s_start[8:10]))
+
+    def get_n_hours_ago(self, n=1, flag = 0):
+        """
+        get n hous ago
+        flag is True return datetime format
+        default 1 hours ago
+        if n > 0 :
+            过去时间
+        else:
+            未来时间
+        :param n:
+        :return:
+        """
+        r = self.now - timedelta(hours=n)
+        return r if flag else r.strftime("%Y-%m-%d %H:00:00")
+
+    def get_n_minutes_ago(self, n=1, string=True):
+        """
+        get n minutes ago
+        default 1 minutes ago
+        if n > 0 :
+            过去时间
+        else:
+            未来时间
+        :param n:
+        :return:
+        """
+        if string:
+            return (self.now - timedelta(minutes=n)).strftime("%Y-%m-%d %H:%M")
+        else:
+            return self.now - timedelta(minutes=n)
+
+    def get_n_pre_month_last_day(self, n=0, flag=False):
+        """
+        获取 n 个月前的最后一天
+        :param n:
+        :param flag:
+        :return:
+        """
+        r = self.get_before_month(self.today.year, self.today.month, 1, n)
+        num = calendar.monthrange(r.year, r.month)[1]
+        x = r.replace(day=num)
+        return x if flag else x.strftime("%Y-%m-%d")
+
+if __name__ == "__main__":
+    ut = DateUtils()
+    end = ut.now.strftime('%Y-%m') + '-01 00:00:00'
+    # begin = ut.get_n_month_ago_begin(ut.now.strftime('%Y-%m'), 1) + '-01 00:00:00'
+    # print(ut.get_n_pre_month_first_day(0))
+    ut.today = date(2018, 1, 1)
+    print(ut.month_first_day())

+ 48 - 0
model/DingTalkUtils.py

@@ -0,0 +1,48 @@
+"""
+@desc 钉钉报警
+@auth ck
+手机号是str,用","分隔,如果不填,默认@所有人
+"""
+import requests
+import random
+
+url = "https://oapi.dingtalk.com/robot/send?access_token=ba21cd5591c44593ca7cac05902835e33298c7bf566a5381dc3f01e41c8d5c30"
+headers = {'Content-Type': 'application/json;charset=utf-8'}
+members = ["13726204048", "18860455786"]
+
+class DingTalkUtils:
+    """
+    @phone Str
+
+            不填:默认@所有人
+            可多个,按英文逗号隔开
+            可填 【ramdom】 随机发送
+    """
+    def send(msg, phone=""):
+        if phone == "":
+            isAtall = True
+            atMobiles = []
+
+        elif phone == "random":
+            isAtall = False
+            atMobiles = []
+            atMobiles.append(random.choice(members))
+
+        else:
+            isAtall = False
+            atMobiles =phone.split(",")
+
+        data = {'msgtype': 'text',
+                    "at": {"isAtAll": isAtall,
+                           "atMobiles": atMobiles},
+                    "text": {"content": msg+"\n[趣程]"}}
+
+        requests.post(url=url, headers=headers, json=data)
+
+
+
+if __name__ == '__main__':
+    DingTalkUtils.send("该下班了","13726204048,11")
+    # 发送的内容得加上趣程
+
+

+ 0 - 0
model/__init__.py


BIN
model/__pycache__/CommonUtils.cpython-36.pyc


BIN
model/__pycache__/DataBaseOperation.cpython-36.pyc


BIN
model/__pycache__/DataBaseUtils.cpython-36.pyc


BIN
model/__pycache__/DateUtils.cpython-36.pyc


BIN
model/__pycache__/__init__.cpython-36.pyc


BIN
model/__pycache__/log.cpython-36.pyc


+ 0 - 0
model/common/__init__.py


BIN
model/common/__pycache__/__init__.cpython-36.pyc


BIN
model/common/__pycache__/errors.cpython-36.pyc


BIN
model/common/__pycache__/file_pid.cpython-36.pyc


+ 12 - 0
model/common/errors.py

@@ -0,0 +1,12 @@
+
+status_0 = dict(status_code=405, reason='Method not allowed.')
+status_1 = dict(status_code=404, reason='API not found.')
+status_2 = dict(status_code=510, reason='Account is not logined.')
+status_3 = dict(status_code=511, reason='Invalid ID.')
+status_00 = dict(status_code=200, reason='ok')
+
+status_22 = dict(status_code=404, reason='Resource not found.')
+status_23 = dict(status_code=523, reason='Wrong password.')
+status_24 = dict(status_code=524, reason='Upload file failed.')
+status_25 = dict(status_code=404, reason='Post params not found.')
+

+ 22 - 0
model/common/file_pid.py

@@ -0,0 +1,22 @@
+
+
+import os
+from model.log import logger
+log=logger()
+
+
+class PID(object):
+    @staticmethod
+    def write():
+        pid = os.getpid()
+        f = open("pid", "w")
+        f.write(str(pid))
+        f.close()
+        log.info("write pid %s ..." % pid)
+
+    @staticmethod
+    def remove():
+        try:
+            os.remove("pid")
+        except Exception as e:
+            log.critical(e.message)

+ 67 - 0
model/log.py

@@ -0,0 +1,67 @@
+
+import logging
+import os
+import time
+
+
+class logger(object):
+    """
+    终端打印不同颜色的日志,在pycharm中如果强行规定了日志的颜色, 这个方法不会起作用, 但是
+    对于终端,这个方法是可以打印不同颜色的日志的。
+    """
+
+    # 在这里定义StreamHandler,可以实现单例, 所有的logger()共用一个StreamHandler
+    ch = logging.StreamHandler()
+
+    def __init__(self):
+        self.logger = logging.getLogger()
+        if not self.logger.handlers:
+            # 如果self.logger没有handler, 就执行以下代码添加handler
+            self.logger.setLevel(logging.DEBUG)
+            rootpath =os.path.dirname(os.path.dirname(__file__))
+            self.log_path = rootpath + '/logs'
+            if not os.path.exists(self.log_path):
+                os.makedirs(self.log_path)
+
+            # 创建一个handler,用于写入日志文件
+            fh = logging.FileHandler(self.log_path + '/runlog' + time.strftime("%Y%m%d", time.localtime()) + '.log',
+                                     encoding='utf-8')
+            fh.setLevel(logging.INFO)
+
+            # 定义handler的输出格式
+            formatter = logging.Formatter('[%(asctime)s] - [%(levelname)s] - %(message)s')
+            fh.setFormatter(formatter)
+
+            # 给logger添加handler
+            self.logger.addHandler(fh)
+
+    def debug(self, message):
+        self.fontColor('\033[0;32m%s\033[0m')
+        self.logger.debug(message)
+
+    def info(self, message):
+        self.fontColor('\033[0;34m%s\033[0m')
+        self.logger.info(message)
+
+    def warning(self, message):
+        self.fontColor('\033[0;37m%s\033[0m')
+        self.logger.warning(message)
+
+    def error(self, message):
+        self.fontColor('\033[0;31m%s\033[0m')
+        self.logger.error(message)
+
+    def critical(self, message):
+        self.fontColor('\033[0;35m%s\033[0m')
+        self.logger.critical(message)
+
+    def fontColor(self, color):
+        # 不同的日志输出不同的颜色
+        formatter = logging.Formatter(color % '[%(asctime)s] - [%(levelname)s] - %(message)s')
+        self.ch.setFormatter(formatter)
+        self.logger.addHandler(self.ch)
+
+
+if __name__ == "__main__":
+    rootpath = os.path.dirname(os.path.dirname(__file__))
+    print(rootpath)

+ 1 - 0
pid

@@ -0,0 +1 @@
+15612

+ 10 - 0
urls.py

@@ -0,0 +1,10 @@
+from handlers.PitcherPanel import*
+
+
+
+urls = [
+    (r'/data/pitcher_panel/channel', PitcherPanelChannel),
+    (r'/data/pitcher_panel/daily', PitcherPanelDaily),
+    (r'/data/pitcher_panel/overview', PitcherPanelOverview),
+
+]