2022-12-06T01:12:18,573 Created temporary directory: /tmp/pip-ephem-wheel-cache-ob71gktv 2022-12-06T01:12:18,577 Created temporary directory: /tmp/pip-build-tracker-epsjtati 2022-12-06T01:12:18,578 Initialized build tracking at /tmp/pip-build-tracker-epsjtati 2022-12-06T01:12:18,578 Created build tracker: /tmp/pip-build-tracker-epsjtati 2022-12-06T01:12:18,579 Entered build tracker: /tmp/pip-build-tracker-epsjtati 2022-12-06T01:12:18,580 Created temporary directory: /tmp/pip-wheel-u9q8tpfy 2022-12-06T01:12:18,588 DEPRECATION: --no-binary currently disables reading from the cache of locally built wheels. In the future --no-binary will not influence the wheel cache. pip 23.1 will enforce this behaviour change. A possible replacement is to use the --no-cache-dir option. You can use the flag --use-feature=no-binary-enable-wheel-cache to test the upcoming behaviour. Discussion can be found at https://github.com/pypa/pip/issues/11453 2022-12-06T01:12:18,593 Created temporary directory: /tmp/pip-ephem-wheel-cache-k2cko101 2022-12-06T01:12:18,651 Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple 2022-12-06T01:12:18,658 2 location(s) to search for versions of apache-iotdb: 2022-12-06T01:12:18,658 * https://pypi.org/simple/apache-iotdb/ 2022-12-06T01:12:18,658 * https://www.piwheels.org/simple/apache-iotdb/ 2022-12-06T01:12:18,659 Fetching project page and analyzing links: https://pypi.org/simple/apache-iotdb/ 2022-12-06T01:12:18,660 Getting page https://pypi.org/simple/apache-iotdb/ 2022-12-06T01:12:18,663 Found index url https://pypi.org/simple 2022-12-06T01:12:18,898 Fetched page https://pypi.org/simple/apache-iotdb/ as application/vnd.pypi.simple.v1+json 2022-12-06T01:12:18,922 Found link https://files.pythonhosted.org/packages/76/14/d01b6281df00530c69bc8eae2074b9970bbe865a5e971b5cd2019e8b8250/apache-iotdb-0.9.0.tar.gz (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7), version: 0.9.0 2022-12-06T01:12:18,923 Skipping link: No binaries permitted for apache-iotdb: https://files.pythonhosted.org/packages/84/aa/fa9401ccadb89ddce7c2b8a03baee9dbb9913c52b5936d0ec7968cabf056/apache_iotdb-0.9.0-py3-none-any.whl (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7) 2022-12-06T01:12:18,924 Found link https://files.pythonhosted.org/packages/01/fa/e65db378e4d8e07322ec175f37568bceb55ebb3c8397fa7b48e9f087c451/apache-iotdb-0.9.2.tar.gz (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7), version: 0.9.2 2022-12-06T01:12:18,925 Skipping link: No binaries permitted for apache-iotdb: https://files.pythonhosted.org/packages/43/8d/72fa03325e9281b613a0eabae9cc7c606ce0e8952bee0c3ca855e4579a1d/apache_iotdb-0.9.2-py3-none-any.whl (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7) 2022-12-06T01:12:18,926 Found link https://files.pythonhosted.org/packages/34/95/030c2da665358de8ba950099b3b0397dca437fcde60d5d1730d0c451d5e3/apache-iotdb-0.9.3.tar.gz (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7), version: 0.9.3 2022-12-06T01:12:18,927 Skipping link: No binaries permitted for apache-iotdb: https://files.pythonhosted.org/packages/5c/d4/2e329baab32ad93730ba4b79df9b91f1d55d0d37428a5dbbe2dd4c9f3a9d/apache_iotdb-0.9.3-py3-none-any.whl (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7) 2022-12-06T01:12:18,928 Found link https://files.pythonhosted.org/packages/1d/dc/138e08717f8c2e0e238f35d39b34af6cfc1c7a1332b6aa4689750f4fda26/apache-iotdb-0.10.0.tar.gz (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7), version: 0.10.0 2022-12-06T01:12:18,929 Skipping link: No binaries permitted for apache-iotdb: https://files.pythonhosted.org/packages/c3/76/46884f04945b6f02bbec4e06d83fafc16f326ca0f9b35b8c0141018990c0/apache_iotdb-0.10.0-py3-none-any.whl (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7) 2022-12-06T01:12:18,930 Found link https://files.pythonhosted.org/packages/f6/4d/b229b9f309431e8164c9cd893431009a57efcaa059f58c1091d222601da3/apache-iotdb-0.10.1.tar.gz (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7), version: 0.10.1 2022-12-06T01:12:18,931 Skipping link: No binaries permitted for apache-iotdb: https://files.pythonhosted.org/packages/d6/87/2e003dcf87ffa8e73f48a62a107b989967e906670d905a05ae1c1349f396/apache_iotdb-0.10.1-py3-none-any.whl (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7) 2022-12-06T01:12:18,932 Found link https://files.pythonhosted.org/packages/16/8b/2ec65fa81d5961bd927c02d6a209490bf325b2a164506cd3b12e846d7061/apache-iotdb-0.11.0.tar.gz (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7), version: 0.11.0 2022-12-06T01:12:18,933 Skipping link: No binaries permitted for apache-iotdb: https://files.pythonhosted.org/packages/47/c8/047703f7e8125b15361c766b90c6f1cbdbf797f84803f38b1732c1a386cb/apache_iotdb-0.11.0-py3-none-any.whl (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7) 2022-12-06T01:12:18,934 Found link https://files.pythonhosted.org/packages/55/a1/ef100f67e0f26fbc1d19b84115b21de942e7b7e01803706d19f841ac06c1/apache-iotdb-0.11.1.tar.gz (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7), version: 0.11.1 2022-12-06T01:12:18,934 Skipping link: No binaries permitted for apache-iotdb: https://files.pythonhosted.org/packages/9f/9f/dce2d782c8b64700539039ef5d66f5f7a781689538c0a176cf56099ec9d1/apache_iotdb-0.11.1-py3-none-any.whl (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7) 2022-12-06T01:12:18,936 Found link https://files.pythonhosted.org/packages/69/d5/f1b9ff293fe02eb1f1cb3cba13b5d9a4b547415ab0045b2a8a3612249e12/apache-iotdb-0.11.2.tar.gz (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7), version: 0.11.2 2022-12-06T01:12:18,937 Skipping link: No binaries permitted for apache-iotdb: https://files.pythonhosted.org/packages/2b/96/a5f0c63659cc8477c53d8a8321c07ea5a0bb2430abaaab477a6185bb43a1/apache_iotdb-0.11.2-py3-none-any.whl (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7) 2022-12-06T01:12:18,938 Found link https://files.pythonhosted.org/packages/7d/cf/0d672a828527f59cdc66c078b0b8e356ca0a3191224a4363ce2256337d1c/apache-iotdb-0.11.3.tar.gz (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7), version: 0.11.3 2022-12-06T01:12:18,939 Skipping link: No binaries permitted for apache-iotdb: https://files.pythonhosted.org/packages/d2/c7/6709b26341e59788d05a297182aa3f96c692e85421c169f657e92c3b4765/apache_iotdb-0.11.3-py3-none-any.whl (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7) 2022-12-06T01:12:18,940 Found link https://files.pythonhosted.org/packages/00/a1/5b1b8a2754f4b25420d9a4461b5e2b8573bb89b43054f9303ea0558df0de/apache-iotdb-0.11.4.tar.gz (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7), version: 0.11.4 2022-12-06T01:12:18,940 Skipping link: No binaries permitted for apache-iotdb: https://files.pythonhosted.org/packages/48/f4/a21fd4495f93c428de788a477665f1815b257568469c38108666125fff4b/apache_iotdb-0.11.4-py3-none-any.whl (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7) 2022-12-06T01:12:18,942 Found link https://files.pythonhosted.org/packages/9e/16/bb2ef45f62e9866f1be97f04e2c581247d3b145e5d8a01b7c143023c6c45/apache-iotdb-0.12.0.tar.gz (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7), version: 0.12.0 2022-12-06T01:12:18,942 Skipping link: No binaries permitted for apache-iotdb: https://files.pythonhosted.org/packages/93/32/e051c3ce387e54b1f036995e92ff352895cf01a51b170752e906a7d42364/apache_iotdb-0.12.0-py3-none-any.whl (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7) 2022-12-06T01:12:18,944 Found link https://files.pythonhosted.org/packages/20/0c/b39e9f362fb0a1a43cb0a05a5b2d9163815f0048575e0c071bbaa50070b8/apache-iotdb-0.12.1.tar.gz (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7), version: 0.12.1 2022-12-06T01:12:18,944 Skipping link: No binaries permitted for apache-iotdb: https://files.pythonhosted.org/packages/55/cf/219a0c3cd17537cebf6e67deeaa77b57741c9b40bcddbb7f59ac9b828401/apache_iotdb-0.12.1-py3-none-any.whl (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7) 2022-12-06T01:12:18,946 Found link https://files.pythonhosted.org/packages/fd/64/d83ceaaab941dd78df38cd8c35d27028a27724c2535f0e6f01a48472aa28/apache-iotdb-0.12.2.tar.gz (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7), version: 0.12.2 2022-12-06T01:12:18,946 Skipping link: No binaries permitted for apache-iotdb: https://files.pythonhosted.org/packages/0b/33/60af46cbc25d7ecf9722bf311295cb0acbf2841f6eb3e3af7433ac3e199d/apache_iotdb-0.12.2-py3-none-any.whl (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7) 2022-12-06T01:12:18,948 Found link https://files.pythonhosted.org/packages/24/7c/81a9dcfd218d4654b03d9079578659d6201aa4f9e9ccba328c0742e8e9c1/apache-iotdb-0.12.3.tar.gz (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7), version: 0.12.3 2022-12-06T01:12:18,948 Skipping link: No binaries permitted for apache-iotdb: https://files.pythonhosted.org/packages/9f/ae/e79cef98fa20cf977ea22b065fcff8d7b976922dd281f4a74a02b1a72b41/apache_iotdb-0.12.3-py3-none-any.whl (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7) 2022-12-06T01:12:18,950 Found link https://files.pythonhosted.org/packages/9e/11/0d12f9b906b3aac1446c09e297bcdf3a0cdfb016aae1ec77effa214999de/apache-iotdb-0.12.4.tar.gz (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7), version: 0.12.4 2022-12-06T01:12:18,950 Skipping link: No binaries permitted for apache-iotdb: https://files.pythonhosted.org/packages/2b/cb/34f5d9137086d912e4518d751eca1ac9a8b908706c4b3176ca32911fabd2/apache_iotdb-0.12.4-py3-none-any.whl (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7) 2022-12-06T01:12:18,951 Found link https://files.pythonhosted.org/packages/8a/52/93503eac47c1561edc21431f7154b694afad9d461e2af0fea36966953c24/apache-iotdb-0.12.5.tar.gz (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7), version: 0.12.5 2022-12-06T01:12:18,952 Skipping link: No binaries permitted for apache-iotdb: https://files.pythonhosted.org/packages/7a/30/1cd9bca76c1f4f9b4cd48d11f23103ade9c5a35410bbf0a8f5997bab51b0/apache_iotdb-0.12.5-py3-none-any.whl (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7) 2022-12-06T01:12:18,953 Found link https://files.pythonhosted.org/packages/00/d9/19746ff8906cc2ac3c9326fbcbd244d2424f4aad5d7201843956d27dcb0b/apache-iotdb-0.12.6.tar.gz (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7), version: 0.12.6 2022-12-06T01:12:18,954 Skipping link: No binaries permitted for apache-iotdb: https://files.pythonhosted.org/packages/cf/7b/ab3acb96fd057e900f9aca1b030f4fb42caf4104000ab742ce19a1029b6f/apache_iotdb-0.12.6-py3-none-any.whl (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7) 2022-12-06T01:12:18,955 Found link https://files.pythonhosted.org/packages/a6/cd/33de301e51132f8d0d79adc346d38685a6b871251846bad95b35ebf74ac9/apache-iotdb-0.13.0.tar.gz (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7), version: 0.13.0 2022-12-06T01:12:18,956 Skipping link: No binaries permitted for apache-iotdb: https://files.pythonhosted.org/packages/71/c1/3684d3b6e6eddda5fbe994e123c6bc6569409994a44b5d3e4b130554802a/apache_iotdb-0.13.0-py3-none-any.whl (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7) 2022-12-06T01:12:18,957 Found link https://files.pythonhosted.org/packages/7e/3e/40f0d900e04598036cc65ae437a2ee9f4aa149860d434a6f4b291460582c/apache-iotdb-0.13.0.post1.tar.gz (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7), version: 0.13.0.post1 2022-12-06T01:12:18,958 Skipping link: No binaries permitted for apache-iotdb: https://files.pythonhosted.org/packages/7c/f2/ef6f589910f1b850ad665d4958e2a26b5249bddc81d5f29a711e21a79dc1/apache_iotdb-0.13.0.post1-py3-none-any.whl (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7) 2022-12-06T01:12:18,959 Found link https://files.pythonhosted.org/packages/e5/47/3efce218f936953f6ee5e338748981137a5d30579578038a67063b1c10d8/apache-iotdb-0.13.1.tar.gz (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7), version: 0.13.1 2022-12-06T01:12:18,960 Skipping link: No binaries permitted for apache-iotdb: https://files.pythonhosted.org/packages/b7/1d/3074d8ab58366c99783fe0ed853472a21d69dfd2b80ca001281d170833e2/apache_iotdb-0.13.1-py3-none-any.whl (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7) 2022-12-06T01:12:18,961 Found link https://files.pythonhosted.org/packages/6f/55/1bcfde81cb204d77387e7cadbf8c3510ec04a2b02fa8b26d04b8f5037bca/apache-iotdb-0.13.2.tar.gz (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7), version: 0.13.2 2022-12-06T01:12:18,962 Skipping link: No binaries permitted for apache-iotdb: https://files.pythonhosted.org/packages/94/0c/3a7d8a238d7c8771453889f8f03f9ebcd418839306e64f4ddea8c0baee81/apache_iotdb-0.13.2-py3-none-any.whl (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7) 2022-12-06T01:12:18,964 Found link https://files.pythonhosted.org/packages/bb/7d/24cefdcd57e96d496fd3492fc28b3d53da6ba0fc6ee69f99dddec1cf500c/apache-iotdb-0.14.0rc1.tar.gz (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7), version: 0.14.0rc1 2022-12-06T01:12:18,964 Skipping link: No binaries permitted for apache-iotdb: https://files.pythonhosted.org/packages/6d/37/0e5a292ed1a695927cefec20d4ad01d3c7af78e691d5250f1646f318d4ef/apache_iotdb-0.14.0rc1-py3-none-any.whl (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7) 2022-12-06T01:12:18,966 Found link https://files.pythonhosted.org/packages/49/91/11702001bdc0af0266d5f4dd222b5f937684e8c08e5044735ade6748cd58/apache-iotdb-1.0.0.tar.gz (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7), version: 1.0.0 2022-12-06T01:12:18,966 Skipping link: No binaries permitted for apache-iotdb: https://files.pythonhosted.org/packages/3d/57/3019d5cf51e6198d5b7ee9e3c07a15efa7487e8b280b4b71cc521a6651e3/apache_iotdb-1.0.0-py3-none-any.whl (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7) 2022-12-06T01:12:18,967 Fetching project page and analyzing links: https://www.piwheels.org/simple/apache-iotdb/ 2022-12-06T01:12:18,968 Getting page https://www.piwheels.org/simple/apache-iotdb/ 2022-12-06T01:12:18,970 Found index url https://www.piwheels.org/simple 2022-12-06T01:12:19,215 Fetched page https://www.piwheels.org/simple/apache-iotdb/ as text/html 2022-12-06T01:12:19,233 Skipping link: No binaries permitted for apache-iotdb: https://www.piwheels.org/simple/apache-iotdb/apache_iotdb-0.14.0rc1-py3-none-any.whl#sha256=2f71e6b3443c4748717889729380082daa7bd8f9950d4c17909134372367bccc (from https://www.piwheels.org/simple/apache-iotdb/) (requires-python:>=3.7) 2022-12-06T01:12:19,233 Skipping link: No binaries permitted for apache-iotdb: https://www.piwheels.org/simple/apache-iotdb/apache_iotdb-0.13.2-py3-none-any.whl#sha256=136811be5cdfe045bc349a8f6c0b07117600185c0c7ada8353610179adde27ae (from https://www.piwheels.org/simple/apache-iotdb/) (requires-python:>=3.7) 2022-12-06T01:12:19,234 Skipping link: No binaries permitted for apache-iotdb: https://www.piwheels.org/simple/apache-iotdb/apache_iotdb-0.13.1-py3-none-any.whl#sha256=22668867268f1ea89b8205cbda30d0578aaa5ccfff0b552396e7059a95d3781a (from https://www.piwheels.org/simple/apache-iotdb/) (requires-python:>=3.7) 2022-12-06T01:12:19,234 Skipping link: No binaries permitted for apache-iotdb: https://www.piwheels.org/simple/apache-iotdb/apache_iotdb-0.13.0.post1-py3-none-any.whl#sha256=d53cf02df2cc507d9caf48167c52d69e24abab9800430de3ff8abf8159bff63b (from https://www.piwheels.org/simple/apache-iotdb/) (requires-python:>=3.7) 2022-12-06T01:12:19,235 Skipping link: No binaries permitted for apache-iotdb: https://www.piwheels.org/simple/apache-iotdb/apache_iotdb-0.13.0-py3-none-any.whl#sha256=67b7429e60cdd5e1e3a808592a87a591c028af62de8e2fec2535b4a3105f21b7 (from https://www.piwheels.org/simple/apache-iotdb/) (requires-python:>=3.7) 2022-12-06T01:12:19,236 Skipping link: No binaries permitted for apache-iotdb: https://www.piwheels.org/simple/apache-iotdb/apache_iotdb-0.12.6-py3-none-any.whl#sha256=a4f679df0053b74f83de861277de12e030eb8601063b172ec44789118ba11400 (from https://www.piwheels.org/simple/apache-iotdb/) (requires-python:>=3.7) 2022-12-06T01:12:19,236 Skipping link: No binaries permitted for apache-iotdb: https://www.piwheels.org/simple/apache-iotdb/apache_iotdb-0.12.5-py3-none-any.whl#sha256=06bb080be5b0469037e68db56a7feb10da911a396a47d598598d8d8c50d07419 (from https://www.piwheels.org/simple/apache-iotdb/) (requires-python:>=3.7) 2022-12-06T01:12:19,237 Skipping link: No binaries permitted for apache-iotdb: https://www.piwheels.org/simple/apache-iotdb/apache_iotdb-0.12.4-py3-none-any.whl#sha256=af5fa8000dd449fb6d98420287b2049b5e68d268fa1529fa96955b5fe7637c13 (from https://www.piwheels.org/simple/apache-iotdb/) (requires-python:>=3.7) 2022-12-06T01:12:19,237 Skipping link: No binaries permitted for apache-iotdb: https://www.piwheels.org/simple/apache-iotdb/apache_iotdb-0.12.3-py3-none-any.whl#sha256=eb77b047b61a087b286e01afea6ee9761c9e687479a4e551be085d82612ed220 (from https://www.piwheels.org/simple/apache-iotdb/) (requires-python:>=3.7) 2022-12-06T01:12:19,238 Skipping link: No binaries permitted for apache-iotdb: https://www.piwheels.org/simple/apache-iotdb/apache_iotdb-0.12.2-py3-none-any.whl#sha256=bb7605db211272947ba451cdad35a2b4f554167361f0c08acedbfb0723ac7ab8 (from https://www.piwheels.org/simple/apache-iotdb/) (requires-python:>=3.7) 2022-12-06T01:12:19,238 Skipping link: No binaries permitted for apache-iotdb: https://www.piwheels.org/simple/apache-iotdb/apache_iotdb-0.12.1-py3-none-any.whl#sha256=bc5ddc6b683bf26a0b9a8c47ada13d29918503664e9e1c3fdefae73121f3a327 (from https://www.piwheels.org/simple/apache-iotdb/) (requires-python:>=3.7) 2022-12-06T01:12:19,239 Skipping link: No binaries permitted for apache-iotdb: https://www.piwheels.org/simple/apache-iotdb/apache_iotdb-0.12.0-py3-none-any.whl#sha256=061d9407266b9d100113fa2d11890a8d5d56f8b496305c5864f08a9af35fcc12 (from https://www.piwheels.org/simple/apache-iotdb/) (requires-python:>=3.7) 2022-12-06T01:12:19,239 Skipping link: No binaries permitted for apache-iotdb: https://www.piwheels.org/simple/apache-iotdb/apache_iotdb-0.11.4-py3-none-any.whl#sha256=cf1ee85db62d31642b32742aba0a026a941b85cf4bb49ec48ef09b9e241f3bf5 (from https://www.piwheels.org/simple/apache-iotdb/) (requires-python:>=3.7) 2022-12-06T01:12:19,240 Skipping link: No binaries permitted for apache-iotdb: https://www.piwheels.org/simple/apache-iotdb/apache_iotdb-0.11.3-py3-none-any.whl#sha256=55e9a0042694ba7fa482f733a1d548c0180bccf0e35e090b85d7b9050c95162b (from https://www.piwheels.org/simple/apache-iotdb/) (requires-python:>=3.7) 2022-12-06T01:12:19,240 Skipping link: No binaries permitted for apache-iotdb: https://www.piwheels.org/simple/apache-iotdb/apache_iotdb-0.11.2-py3-none-any.whl#sha256=762d5b0c5f82869237d5375d2a8774f99654c3b693d6f77bf6e9decc78b7fd5d (from https://www.piwheels.org/simple/apache-iotdb/) (requires-python:>=3.7) 2022-12-06T01:12:19,241 Skipping link: No binaries permitted for apache-iotdb: https://www.piwheels.org/simple/apache-iotdb/apache_iotdb-0.11.1-py3-none-any.whl#sha256=317a24e4870d587820f8d5be294e2e9a6ad09f70566ce4380506085c47b2fc0a (from https://www.piwheels.org/simple/apache-iotdb/) (requires-python:>=3.7) 2022-12-06T01:12:19,241 Skipping link: No binaries permitted for apache-iotdb: https://www.piwheels.org/simple/apache-iotdb/apache_iotdb-0.11.0-py3-none-any.whl#sha256=4771e87dd8d933815206c063014beff8eff4c8025353723ac67603f49a119224 (from https://www.piwheels.org/simple/apache-iotdb/) (requires-python:>=3.7) 2022-12-06T01:12:19,242 Skipping link: No binaries permitted for apache-iotdb: https://www.piwheels.org/simple/apache-iotdb/apache_iotdb-0.10.1-py3-none-any.whl#sha256=b4b13fa0d6ed86fbcc1231cad3d220ee81b38452e87fea655641720f803d4c1d (from https://www.piwheels.org/simple/apache-iotdb/) (requires-python:>=3.7) 2022-12-06T01:12:19,242 Skipping link: No binaries permitted for apache-iotdb: https://www.piwheels.org/simple/apache-iotdb/apache_iotdb-0.10.0-py3-none-any.whl#sha256=388ade65f63cb37eef343e4f294cf3488b79894ff8061a7d9b2bf42277ded9de (from https://www.piwheels.org/simple/apache-iotdb/) (requires-python:>=3.7) 2022-12-06T01:12:19,243 Skipping link: No binaries permitted for apache-iotdb: https://www.piwheels.org/simple/apache-iotdb/apache_iotdb-0.9.3-py3-none-any.whl#sha256=b535b53a5182dc94116e67edb4a34c1efb007574273e2ff4ad72ebc3b4634326 (from https://www.piwheels.org/simple/apache-iotdb/) (requires-python:>=3.7) 2022-12-06T01:12:19,244 Skipping link: No binaries permitted for apache-iotdb: https://www.piwheels.org/simple/apache-iotdb/apache_iotdb-0.9.2-py3-none-any.whl#sha256=b7fad95c7f041f18a621439aa3cd19fc79d76caa85a93967163566c10b7c6348 (from https://www.piwheels.org/simple/apache-iotdb/) (requires-python:>=3.7) 2022-12-06T01:12:19,244 Skipping link: No binaries permitted for apache-iotdb: https://www.piwheels.org/simple/apache-iotdb/apache_iotdb-0.9.0-py3-none-any.whl#sha256=1feb6b731a9af26aac7a1e6fab74e85dd960562a1dca6e4c5c9d10234a570e82 (from https://www.piwheels.org/simple/apache-iotdb/) (requires-python:>=3.7) 2022-12-06T01:12:19,245 Skipping link: not a file: https://www.piwheels.org/simple/apache-iotdb/ 2022-12-06T01:12:19,245 Skipping link: not a file: https://pypi.org/simple/apache-iotdb/ 2022-12-06T01:12:19,294 Given no hashes to check 1 links for project 'apache-iotdb': discarding no candidates 2022-12-06T01:12:19,337 Collecting apache-iotdb==1.0.0 2022-12-06T01:12:19,342 Created temporary directory: /tmp/pip-unpack-n8dk861s 2022-12-06T01:12:19,607 Downloading apache-iotdb-1.0.0.tar.gz (81 kB) 2022-12-06T01:12:20,081 Added apache-iotdb==1.0.0 from https://files.pythonhosted.org/packages/49/91/11702001bdc0af0266d5f4dd222b5f937684e8c08e5044735ade6748cd58/apache-iotdb-1.0.0.tar.gz to build tracker '/tmp/pip-build-tracker-epsjtati' 2022-12-06T01:12:20,091 Created temporary directory: /tmp/pip-build-env-8invdbgq 2022-12-06T01:12:20,104 Installing build dependencies: started 2022-12-06T01:12:20,106 Running command pip subprocess to install build dependencies 2022-12-06T01:12:22,941 Using pip 22.3 from /home/piwheels/.local/lib/python3.7/site-packages/pip (python 3.7) 2022-12-06T01:12:23,946 DEPRECATION: --no-binary currently disables reading from the cache of locally built wheels. In the future --no-binary will not influence the wheel cache. pip 23.1 will enforce this behaviour change. A possible replacement is to use the --no-cache-dir option. You can use the flag --use-feature=no-binary-enable-wheel-cache to test the upcoming behaviour. Discussion can be found at https://github.com/pypa/pip/issues/11453 2022-12-06T01:12:23,999 Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple 2022-12-06T01:12:27,999 Collecting setuptools>=40.8.0 2022-12-06T01:12:28,268 Using cached https://www.piwheels.org/simple/setuptools/setuptools-65.6.3-py3-none-any.whl (1.2 MB) 2022-12-06T01:12:28,909 Collecting wheel 2022-12-06T01:12:28,944 Using cached https://www.piwheels.org/simple/wheel/wheel-0.38.4-py3-none-any.whl (36 kB) 2022-12-06T01:12:35,097 Installing collected packages: wheel, setuptools 2022-12-06T01:12:35,378 Creating /tmp/pip-build-env-8invdbgq/overlay/bin 2022-12-06T01:12:35,383 changing mode of /tmp/pip-build-env-8invdbgq/overlay/bin/wheel to 755 2022-12-06T01:12:40,185 Successfully installed setuptools-65.6.3 wheel-0.38.4 2022-12-06T01:12:40,218 [notice] A new release of pip available: 22.3 -> 22.3.1 2022-12-06T01:12:40,219 [notice] To update, run: python3 -m pip install --upgrade pip 2022-12-06T01:12:40,664 Installing build dependencies: finished with status 'done' 2022-12-06T01:12:40,675 Getting requirements to build wheel: started 2022-12-06T01:12:40,678 Running command Getting requirements to build wheel 2022-12-06T01:12:42,397 2022-12-06T01:12:42,405 # Apache IoTDB 2022-12-06T01:12:42,405 [![Python Client](https://github.com/apache/iotdb/actions/workflows/client-python.yml/badge.svg?branch=rel%2F1.0)](https://github.com/apache/iotdb/actions/workflows/client-python.yml) 2022-12-06T01:12:42,406 [![GitHub release](https://img.shields.io/github/release/apache/iotdb.svg)](https://github.com/apache/iotdb/releases) 2022-12-06T01:12:42,406 [![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html) 2022-12-06T01:12:42,406 ![](https://github-size-badge.herokuapp.com/apache/iotdb.svg) 2022-12-06T01:12:42,407 ![](https://img.shields.io/github/downloads/apache/iotdb/total.svg) 2022-12-06T01:12:42,407 ![](https://img.shields.io/badge/platform-win%20%7C%20macos%20%7C%20linux-yellow.svg) 2022-12-06T01:12:42,407 [![IoTDB Website](https://img.shields.io/website-up-down-green-red/https/shields.io.svg?label=iotdb-website)](https://iotdb.apache.org/) 2022-12-06T01:12:42,408 Apache IoTDB (Database for Internet of Things) is an IoT native database with high performance for 2022-12-06T01:12:42,409 data management and analysis, deployable on the edge and the cloud. Due to its light-weight 2022-12-06T01:12:42,409 architecture, high performance and rich feature set together with its deep integration with 2022-12-06T01:12:42,409 Apache Hadoop, Spark and Flink, Apache IoTDB can meet the requirements of massive data storage, 2022-12-06T01:12:42,409 high-speed data ingestion and complex data analysis in the IoT industrial fields. 2022-12-06T01:12:42,410 ## Python Native API 2022-12-06T01:12:42,411 ### Requirements 2022-12-06T01:12:42,411 You have to install thrift (>=0.13) before using the package. 2022-12-06T01:12:42,412 ### How to use (Example) 2022-12-06T01:12:42,413 First, download the latest package: `pip3 install apache-iotdb` 2022-12-06T01:12:42,414 *Notice: If you are installing Python API v0.13.0, DO NOT install by `pip install apache-iotdb==0.13.0`, use `pip install apache-iotdb==0.13.0.post1` instead!* 2022-12-06T01:12:42,414 You can get an example of using the package to read and write data at here: [Example](https://github.com/apache/iotdb/blob/master/client-py/SessionExample.py) 2022-12-06T01:12:42,415 An example of aligned timeseries: [Aligned Timeseries Session Example](https://github.com/apache/iotdb/blob/master/client-py/SessionAlignedTimeseriesExample.py) 2022-12-06T01:12:42,416 (you need to add `import iotdb` in the head of the file) 2022-12-06T01:12:42,417 Or: 2022-12-06T01:12:42,417 ```python 2022-12-06T01:12:42,418 from iotdb.Session import Session 2022-12-06T01:12:42,418 ip = "127.0.0.1" 2022-12-06T01:12:42,419 port_ = "6667" 2022-12-06T01:12:42,419 username_ = "root" 2022-12-06T01:12:42,419 password_ = "root" 2022-12-06T01:12:42,419 session = Session(ip, port_, username_, password_) 2022-12-06T01:12:42,420 session.open(False) 2022-12-06T01:12:42,420 zone = session.get_time_zone() 2022-12-06T01:12:42,420 session.close() 2022-12-06T01:12:42,421 ``` 2022-12-06T01:12:42,421 ### Initialization 2022-12-06T01:12:42,422 * Initialize a Session 2022-12-06T01:12:42,423 ```python 2022-12-06T01:12:42,423 session = Session(ip, port_, username_, password_, fetch_size=1024, zone_id="UTC+8") 2022-12-06T01:12:42,423 ``` 2022-12-06T01:12:42,424 * Open a session, with a parameter to specify whether to enable RPC compression 2022-12-06T01:12:42,424 ```python 2022-12-06T01:12:42,425 session.open(enable_rpc_compression=False) 2022-12-06T01:12:42,425 ``` 2022-12-06T01:12:42,426 Notice: this RPC compression status of client must comply with that of IoTDB server 2022-12-06T01:12:42,426 * Close a Session 2022-12-06T01:12:42,427 ```python 2022-12-06T01:12:42,427 session.close() 2022-12-06T01:12:42,428 ``` 2022-12-06T01:12:42,428 ### Data Definition Interface (DDL Interface) 2022-12-06T01:12:42,429 #### DATABASE Management 2022-12-06T01:12:42,430 * CREATE DATABASE 2022-12-06T01:12:42,430 ```python 2022-12-06T01:12:42,431 session.set_storage_group(group_name) 2022-12-06T01:12:42,431 ``` 2022-12-06T01:12:42,432 * Delete one or several databases 2022-12-06T01:12:42,432 ```python 2022-12-06T01:12:42,432 session.delete_storage_group(group_name) 2022-12-06T01:12:42,433 session.delete_storage_groups(group_name_lst) 2022-12-06T01:12:42,433 ``` 2022-12-06T01:12:42,433 #### Timeseries Management 2022-12-06T01:12:42,434 * Create one or multiple timeseries 2022-12-06T01:12:42,434 ```python 2022-12-06T01:12:42,435 session.create_time_series(ts_path, data_type, encoding, compressor, 2022-12-06T01:12:42,435 props=None, tags=None, attributes=None, alias=None) 2022-12-06T01:12:42,436 session.create_multi_time_series( 2022-12-06T01:12:42,436 ts_path_lst, data_type_lst, encoding_lst, compressor_lst, 2022-12-06T01:12:42,436 props_lst=None, tags_lst=None, attributes_lst=None, alias_lst=None 2022-12-06T01:12:42,437 ) 2022-12-06T01:12:42,437 ``` 2022-12-06T01:12:42,438 * Create aligned timeseries 2022-12-06T01:12:42,438 ```python 2022-12-06T01:12:42,439 session.create_aligned_time_series( 2022-12-06T01:12:42,439 device_id, measurements_lst, data_type_lst, encoding_lst, compressor_lst 2022-12-06T01:12:42,439 ) 2022-12-06T01:12:42,440 ``` 2022-12-06T01:12:42,440 Attention: Alias of measurements are **not supported** currently. 2022-12-06T01:12:42,441 * Delete one or several timeseries 2022-12-06T01:12:42,441 ```python 2022-12-06T01:12:42,442 session.delete_time_series(paths_list) 2022-12-06T01:12:42,442 ``` 2022-12-06T01:12:42,442 * Check whether the specific timeseries exists 2022-12-06T01:12:42,443 ```python 2022-12-06T01:12:42,443 session.check_time_series_exists(path) 2022-12-06T01:12:42,444 ``` 2022-12-06T01:12:42,444 ### Data Manipulation Interface (DML Interface) 2022-12-06T01:12:42,445 #### Insert 2022-12-06T01:12:42,445 It is recommended to use insertTablet to help improve write efficiency. 2022-12-06T01:12:42,446 * Insert a Tablet,which is multiple rows of a device, each row has the same measurements 2022-12-06T01:12:42,446 * **Better Write Performance** 2022-12-06T01:12:42,447 * **Support null values**: fill the null value with any value, and then mark the null value via BitMap (from v0.13) 2022-12-06T01:12:42,448 We have two implementations of Tablet in Python API. 2022-12-06T01:12:42,448 * Normal Tablet 2022-12-06T01:12:42,449 ```python 2022-12-06T01:12:42,449 values_ = [ 2022-12-06T01:12:42,449 [False, 10, 11, 1.1, 10011.1, "test01"], 2022-12-06T01:12:42,450 [True, 100, 11111, 1.25, 101.0, "test02"], 2022-12-06T01:12:42,450 [False, 100, 1, 188.1, 688.25, "test03"], 2022-12-06T01:12:42,450 [True, 0, 0, 0, 6.25, "test04"], 2022-12-06T01:12:42,451 ] 2022-12-06T01:12:42,451 timestamps_ = [1, 2, 3, 4] 2022-12-06T01:12:42,451 tablet_ = Tablet( 2022-12-06T01:12:42,451 device_id, measurements_, data_types_, values_, timestamps_ 2022-12-06T01:12:42,452 ) 2022-12-06T01:12:42,452 session.insert_tablet(tablet_) 2022-12-06T01:12:42,452 ``` 2022-12-06T01:12:42,453 * Numpy Tablet 2022-12-06T01:12:42,453 Comparing with Tablet, Numpy Tablet is using [numpy.ndarray](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html) to record data. 2022-12-06T01:12:42,453 With less memory footprint and time cost of serialization, the insert performance will be better. 2022-12-06T01:12:42,454 **Notice** 2022-12-06T01:12:42,454 1. time and value columns in Tablet are ndarray. 2022-12-06T01:12:42,455 2. recommended to use the specific dtypes to each ndarray, see the example below 2022-12-06T01:12:42,455 (if not, the default dtypes are also ok). 2022-12-06T01:12:42,456 ```python 2022-12-06T01:12:42,456 import numpy as np 2022-12-06T01:12:42,456 data_types_ = [ 2022-12-06T01:12:42,457 TSDataType.BOOLEAN, 2022-12-06T01:12:42,457 TSDataType.INT32, 2022-12-06T01:12:42,457 TSDataType.INT64, 2022-12-06T01:12:42,458 TSDataType.FLOAT, 2022-12-06T01:12:42,458 TSDataType.DOUBLE, 2022-12-06T01:12:42,458 TSDataType.TEXT, 2022-12-06T01:12:42,458 ] 2022-12-06T01:12:42,459 np_values_ = [ 2022-12-06T01:12:42,459 np.array([False, True, False, True], TSDataType.BOOLEAN.np_dtype()), 2022-12-06T01:12:42,459 np.array([10, 100, 100, 0], TSDataType.INT32.np_dtype()), 2022-12-06T01:12:42,460 np.array([11, 11111, 1, 0], TSDataType.INT64.np_dtype()), 2022-12-06T01:12:42,460 np.array([1.1, 1.25, 188.1, 0], TSDataType.FLOAT.np_dtype()), 2022-12-06T01:12:42,460 np.array([10011.1, 101.0, 688.25, 6.25], TSDataType.DOUBLE.np_dtype()), 2022-12-06T01:12:42,460 np.array(["test01", "test02", "test03", "test04"], TSDataType.TEXT.np_dtype()), 2022-12-06T01:12:42,461 ] 2022-12-06T01:12:42,461 np_timestamps_ = np.array([1, 2, 3, 4], TSDataType.INT64.np_dtype()) 2022-12-06T01:12:42,461 np_tablet_ = NumpyTablet( 2022-12-06T01:12:42,462 "root.sg_test_01.d_02", measurements_, data_types_, np_values_, np_timestamps_ 2022-12-06T01:12:42,462 ) 2022-12-06T01:12:42,462 session.insert_tablet(np_tablet_) 2022-12-06T01:12:42,463 ``` 2022-12-06T01:12:42,463 * Insert multiple Tablets 2022-12-06T01:12:42,464 ```python 2022-12-06T01:12:42,464 session.insert_tablets(tablet_lst) 2022-12-06T01:12:42,464 ``` 2022-12-06T01:12:42,465 * Insert a Record 2022-12-06T01:12:42,465 ```python 2022-12-06T01:12:42,466 session.insert_record(device_id, timestamp, measurements_, data_types_, values_) 2022-12-06T01:12:42,466 ``` 2022-12-06T01:12:42,467 * Insert multiple Records 2022-12-06T01:12:42,467 ```python 2022-12-06T01:12:42,468 session.insert_records( 2022-12-06T01:12:42,468 device_ids_, time_list_, measurements_list_, data_type_list_, values_list_ 2022-12-06T01:12:42,468 ) 2022-12-06T01:12:42,469 ``` 2022-12-06T01:12:42,469 * Insert multiple Records that belong to the same device. 2022-12-06T01:12:42,469 With type info the server has no need to do type inference, which leads a better performance 2022-12-06T01:12:42,470 ```python 2022-12-06T01:12:42,471 session.insert_records_of_one_device(device_id, time_list, measurements_list, data_types_list, values_list) 2022-12-06T01:12:42,471 ``` 2022-12-06T01:12:42,472 #### Insert with type inference 2022-12-06T01:12:42,472 When the data is of String type, we can use the following interface to perform type inference based on the value of the value itself. For example, if value is "true" , it can be automatically inferred to be a boolean type. If value is "3.2" , it can be automatically inferred as a flout type. Without type information, server has to do type inference, which may cost some time. 2022-12-06T01:12:42,473 * Insert a Record, which contains multiple measurement value of a device at a timestamp 2022-12-06T01:12:42,473 ```python 2022-12-06T01:12:42,474 session.insert_str_record(device_id, timestamp, measurements, string_values) 2022-12-06T01:12:42,474 ``` 2022-12-06T01:12:42,475 #### Insert of Aligned Timeseries 2022-12-06T01:12:42,475 The Insert of aligned timeseries uses interfaces like insert_aligned_XXX, and others are similar to the above interfaces: 2022-12-06T01:12:42,476 * insert_aligned_record 2022-12-06T01:12:42,476 * insert_aligned_records 2022-12-06T01:12:42,477 * insert_aligned_records_of_one_device 2022-12-06T01:12:42,477 * insert_aligned_tablet 2022-12-06T01:12:42,477 * insert_aligned_tablets 2022-12-06T01:12:42,478 ### IoTDB-SQL Interface 2022-12-06T01:12:42,479 * Execute query statement 2022-12-06T01:12:42,479 ```python 2022-12-06T01:12:42,480 session.execute_query_statement(sql) 2022-12-06T01:12:42,480 ``` 2022-12-06T01:12:42,481 * Execute non query statement 2022-12-06T01:12:42,481 ```python 2022-12-06T01:12:42,482 session.execute_non_query_statement(sql) 2022-12-06T01:12:42,482 ``` 2022-12-06T01:12:42,482 * Execute statement 2022-12-06T01:12:42,483 ```python 2022-12-06T01:12:42,483 session.execute_statement(sql) 2022-12-06T01:12:42,484 ``` 2022-12-06T01:12:42,484 ### Schema Template 2022-12-06T01:12:42,485 #### Create Schema Template 2022-12-06T01:12:42,485 The step for creating a metadata template is as follows 2022-12-06T01:12:42,485 1. Create the template class 2022-12-06T01:12:42,485 2. Adding child Node,InternalNode and MeasurementNode can be chose 2022-12-06T01:12:42,486 3. Execute create schema template function 2022-12-06T01:12:42,486 ```python 2022-12-06T01:12:42,487 template = Template(name=template_name, share_time=True) 2022-12-06T01:12:42,487 i_node_gps = InternalNode(name="GPS", share_time=False) 2022-12-06T01:12:42,488 i_node_v = InternalNode(name="vehicle", share_time=True) 2022-12-06T01:12:42,488 m_node_x = MeasurementNode("x", TSDataType.FLOAT, TSEncoding.RLE, Compressor.SNAPPY) 2022-12-06T01:12:42,488 i_node_gps.add_child(m_node_x) 2022-12-06T01:12:42,489 i_node_v.add_child(m_node_x) 2022-12-06T01:12:42,489 template.add_template(i_node_gps) 2022-12-06T01:12:42,490 template.add_template(i_node_v) 2022-12-06T01:12:42,490 template.add_template(m_node_x) 2022-12-06T01:12:42,490 session.create_schema_template(template) 2022-12-06T01:12:42,491 ``` 2022-12-06T01:12:42,491 #### Modify Schema Template nodes 2022-12-06T01:12:42,491 Modify nodes in a template, the template must be already created. These are functions that add or delete some measurement nodes. 2022-12-06T01:12:42,492 * add node in template 2022-12-06T01:12:42,492 ```python 2022-12-06T01:12:42,492 session.add_measurements_in_template(template_name, measurements_path, data_types, encodings, compressors, is_aligned) 2022-12-06T01:12:42,493 ``` 2022-12-06T01:12:42,493 * delete node in template 2022-12-06T01:12:42,493 ```python 2022-12-06T01:12:42,494 session.delete_node_in_template(template_name, path) 2022-12-06T01:12:42,494 ``` 2022-12-06T01:12:42,495 #### Set Schema Template 2022-12-06T01:12:42,495 ```python 2022-12-06T01:12:42,495 session.set_schema_template(template_name, prefix_path) 2022-12-06T01:12:42,496 ``` 2022-12-06T01:12:42,496 #### Uset Schema Template 2022-12-06T01:12:42,497 ```python 2022-12-06T01:12:42,497 session.unset_schema_template(template_name, prefix_path) 2022-12-06T01:12:42,497 ``` 2022-12-06T01:12:42,498 #### Show Schema Template 2022-12-06T01:12:42,498 * Show all schema templates 2022-12-06T01:12:42,498 ```python 2022-12-06T01:12:42,499 session.show_all_templates() 2022-12-06T01:12:42,499 ``` 2022-12-06T01:12:42,499 * Count all nodes in templates 2022-12-06T01:12:42,499 ```python 2022-12-06T01:12:42,500 session.count_measurements_in_template(template_name) 2022-12-06T01:12:42,500 ``` 2022-12-06T01:12:42,501 * Judge whether the path is measurement or not in templates, This measurement must be in the template 2022-12-06T01:12:42,501 ```python 2022-12-06T01:12:42,501 session.count_measurements_in_template(template_name, path) 2022-12-06T01:12:42,501 ``` 2022-12-06T01:12:42,502 * Judge whether the path is exist or not in templates, This path may not belong to the template 2022-12-06T01:12:42,502 ```python 2022-12-06T01:12:42,503 session.is_path_exist_in_template(template_name, path) 2022-12-06T01:12:42,503 ``` 2022-12-06T01:12:42,504 * Show nodes under in schema template 2022-12-06T01:12:42,504 ```python 2022-12-06T01:12:42,504 session.show_measurements_in_template(template_name) 2022-12-06T01:12:42,504 ``` 2022-12-06T01:12:42,505 * Show the path prefix where a schema template is set 2022-12-06T01:12:42,505 ```python 2022-12-06T01:12:42,506 session.show_paths_template_set_on(template_name) 2022-12-06T01:12:42,506 ``` 2022-12-06T01:12:42,506 * Show the path prefix where a schema template is used (i.e. the time series has been created) 2022-12-06T01:12:42,507 ```python 2022-12-06T01:12:42,507 session.show_paths_template_using_on(template_name) 2022-12-06T01:12:42,507 ``` 2022-12-06T01:12:42,508 #### Drop Schema Template 2022-12-06T01:12:42,508 Delete an existing metadata template,dropping an already set template is not supported 2022-12-06T01:12:42,508 ```python 2022-12-06T01:12:42,509 session.drop_schema_template("template_python") 2022-12-06T01:12:42,509 ``` 2022-12-06T01:12:42,510 ### Pandas Support 2022-12-06T01:12:42,511 To easily transform a query result to a [Pandas Dataframe](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html) 2022-12-06T01:12:42,511 the SessionDataSet has a method `.todf()` which consumes the dataset and transforms it to a pandas dataframe. 2022-12-06T01:12:42,511 Example: 2022-12-06T01:12:42,512 ```python 2022-12-06T01:12:42,512 from iotdb.Session import Session 2022-12-06T01:12:42,513 ip = "127.0.0.1" 2022-12-06T01:12:42,513 port_ = "6667" 2022-12-06T01:12:42,513 username_ = "root" 2022-12-06T01:12:42,514 password_ = "root" 2022-12-06T01:12:42,514 session = Session(ip, port_, username_, password_) 2022-12-06T01:12:42,514 session.open(False) 2022-12-06T01:12:42,515 result = session.execute_query_statement("SELECT * FROM root.*") 2022-12-06T01:12:42,515 # Transform to Pandas Dataset 2022-12-06T01:12:42,515 df = result.todf() 2022-12-06T01:12:42,516 session.close() 2022-12-06T01:12:42,517 # Now you can work with the dataframe 2022-12-06T01:12:42,517 df = ... 2022-12-06T01:12:42,517 ``` 2022-12-06T01:12:42,518 ### IoTDB Testcontainer 2022-12-06T01:12:42,519 The Test Support is based on the lib `testcontainers` (https://testcontainers-python.readthedocs.io/en/latest/index.html) which you need to install in your project if you want to use the feature. 2022-12-06T01:12:42,519 To start (and stop) an IoTDB Database in a Docker container simply do: 2022-12-06T01:12:42,520 ```python 2022-12-06T01:12:42,520 class MyTestCase(unittest.TestCase): 2022-12-06T01:12:42,520 def test_something(self): 2022-12-06T01:12:42,521 with IoTDBContainer() as c: 2022-12-06T01:12:42,521 session = Session("localhost", c.get_exposed_port(6667), "root", "root") 2022-12-06T01:12:42,521 session.open(False) 2022-12-06T01:12:42,522 result = session.execute_query_statement("SHOW TIMESERIES") 2022-12-06T01:12:42,522 print(result) 2022-12-06T01:12:42,522 session.close() 2022-12-06T01:12:42,522 ``` 2022-12-06T01:12:42,523 by default it will load the image `apache/iotdb:latest`, if you want a specific version just pass it like e.g. `IoTDBContainer("apache/iotdb:0.12.0")` to get version `0.12.0` running. 2022-12-06T01:12:42,524 ### IoTDB DBAPI 2022-12-06T01:12:42,524 IoTDB DBAPI implements the Python DB API 2.0 specification (https://peps.python.org/pep-0249/), which defines a common 2022-12-06T01:12:42,525 interface for accessing databases in Python. 2022-12-06T01:12:42,525 #### Examples 2022-12-06T01:12:42,526 + Initialization 2022-12-06T01:12:42,526 The initialized parameters are consistent with the session part (except for the sqlalchemy_mode). 2022-12-06T01:12:42,527 ```python 2022-12-06T01:12:42,527 from iotdb.dbapi import connect 2022-12-06T01:12:42,527 ip = "127.0.0.1" 2022-12-06T01:12:42,528 port_ = "6667" 2022-12-06T01:12:42,528 username_ = "root" 2022-12-06T01:12:42,528 password_ = "root" 2022-12-06T01:12:42,529 conn = connect(ip, port_, username_, password_,fetch_size=1024,zone_id="UTC+8",sqlalchemy_mode=False) 2022-12-06T01:12:42,529 cursor = conn.cursor() 2022-12-06T01:12:42,529 ``` 2022-12-06T01:12:42,530 + simple SQL statement execution 2022-12-06T01:12:42,530 ```python 2022-12-06T01:12:42,530 cursor.execute("SELECT * FROM root.*") 2022-12-06T01:12:42,530 for row in cursor.fetchall(): 2022-12-06T01:12:42,531 print(row) 2022-12-06T01:12:42,531 ``` 2022-12-06T01:12:42,532 + execute SQL with parameter 2022-12-06T01:12:42,532 IoTDB DBAPI supports pyformat style parameters 2022-12-06T01:12:42,532 ```python 2022-12-06T01:12:42,533 cursor.execute("SELECT * FROM root.* WHERE time < %(time)s",{"time":"2017-11-01T00:08:00.000"}) 2022-12-06T01:12:42,533 for row in cursor.fetchall(): 2022-12-06T01:12:42,533 print(row) 2022-12-06T01:12:42,534 ``` 2022-12-06T01:12:42,534 + execute SQL with parameter sequences 2022-12-06T01:12:42,534 ```python 2022-12-06T01:12:42,535 seq_of_parameters = [ 2022-12-06T01:12:42,535 {"timestamp": 1, "temperature": 1}, 2022-12-06T01:12:42,535 {"timestamp": 2, "temperature": 2}, 2022-12-06T01:12:42,536 {"timestamp": 3, "temperature": 3}, 2022-12-06T01:12:42,536 {"timestamp": 4, "temperature": 4}, 2022-12-06T01:12:42,536 {"timestamp": 5, "temperature": 5}, 2022-12-06T01:12:42,537 ] 2022-12-06T01:12:42,537 sql = "insert into root.cursor(timestamp,temperature) values(%(timestamp)s,%(temperature)s)" 2022-12-06T01:12:42,537 cursor.executemany(sql,seq_of_parameters) 2022-12-06T01:12:42,538 ``` 2022-12-06T01:12:42,538 + close the connection and cursor 2022-12-06T01:12:42,538 ```python 2022-12-06T01:12:42,539 cursor.close() 2022-12-06T01:12:42,539 conn.close() 2022-12-06T01:12:42,539 ``` 2022-12-06T01:12:42,540 ### IoTDB SQLAlchemy Dialect (Experimental) 2022-12-06T01:12:42,540 The SQLAlchemy dialect of IoTDB is written to adapt to Apache Superset. 2022-12-06T01:12:42,540 This part is still being improved. 2022-12-06T01:12:42,541 Please do not use it in the production environment! 2022-12-06T01:12:42,541 #### Mapping of the metadata 2022-12-06T01:12:42,541 The data model used by SQLAlchemy is a relational data model, which describes the relationships between different entities through tables. 2022-12-06T01:12:42,542 While the data model of IoTDB is a hierarchical data model, which organizes the data through a tree structure. 2022-12-06T01:12:42,542 In order to adapt IoTDB to the dialect of SQLAlchemy, the original data model in IoTDB needs to be reorganized. 2022-12-06T01:12:42,542 Converting the data model of IoTDB into the data model of SQLAlchemy. 2022-12-06T01:12:42,543 The metadata in the IoTDB are: 2022-12-06T01:12:42,543 1. Database 2022-12-06T01:12:42,544 2. Path 2022-12-06T01:12:42,544 3. Entity 2022-12-06T01:12:42,544 4. Measurement 2022-12-06T01:12:42,545 The metadata in the SQLAlchemy are: 2022-12-06T01:12:42,545 1. Schema 2022-12-06T01:12:42,545 2. Table 2022-12-06T01:12:42,546 3. Column 2022-12-06T01:12:42,546 The mapping relationship between them is: 2022-12-06T01:12:42,547 | The metadata in the SQLAlchemy | The metadata in the IoTDB | 2022-12-06T01:12:42,547 | -------------------- | ---------------------------------------------- | 2022-12-06T01:12:42,547 | Schema | Database | 2022-12-06T01:12:42,548 | Table | Path ( from database to entity ) + Entity | 2022-12-06T01:12:42,548 | Column | Measurement | 2022-12-06T01:12:42,548 The following figure shows the relationship between the two more intuitively: 2022-12-06T01:12:42,549 ![sqlalchemy-to-iotdb](https://github.com/apache/iotdb-bin-resources/blob/main/docs/UserGuide/API/IoTDB-SQLAlchemy/sqlalchemy-to-iotdb.png?raw=true) 2022-12-06T01:12:42,550 #### Data type mapping 2022-12-06T01:12:42,550 | data type in IoTDB | data type in SQLAlchemy | 2022-12-06T01:12:42,550 |--------------------|-------------------------| 2022-12-06T01:12:42,551 | BOOLEAN | Boolean | 2022-12-06T01:12:42,551 | INT32 | Integer | 2022-12-06T01:12:42,551 | INT64 | BigInteger | 2022-12-06T01:12:42,551 | FLOAT | Float | 2022-12-06T01:12:42,552 | DOUBLE | Float | 2022-12-06T01:12:42,552 | TEXT | Text | 2022-12-06T01:12:42,552 | LONG | BigInteger | 2022-12-06T01:12:42,553 #### Example 2022-12-06T01:12:42,553 + execute statement 2022-12-06T01:12:42,554 ```python 2022-12-06T01:12:42,554 from sqlalchemy import create_engine 2022-12-06T01:12:42,555 engine = create_engine("iotdb://root:root@127.0.0.1:6667") 2022-12-06T01:12:42,555 connect = engine.connect() 2022-12-06T01:12:42,555 result = connect.execute("SELECT ** FROM root") 2022-12-06T01:12:42,556 for row in result.fetchall(): 2022-12-06T01:12:42,556 print(row) 2022-12-06T01:12:42,556 ``` 2022-12-06T01:12:42,557 + ORM (now only simple queries are supported) 2022-12-06T01:12:42,558 ```python 2022-12-06T01:12:42,558 from sqlalchemy import create_engine, Column, Float, BigInteger, MetaData 2022-12-06T01:12:42,558 from sqlalchemy.ext.declarative import declarative_base 2022-12-06T01:12:42,558 from sqlalchemy.orm import sessionmaker 2022-12-06T01:12:42,559 metadata = MetaData( 2022-12-06T01:12:42,559 schema='root.factory' 2022-12-06T01:12:42,560 ) 2022-12-06T01:12:42,560 Base = declarative_base(metadata=metadata) 2022-12-06T01:12:42,561 class Device(Base): 2022-12-06T01:12:42,561 __tablename__ = "room2.device1" 2022-12-06T01:12:42,561 Time = Column(BigInteger, primary_key=True) 2022-12-06T01:12:42,562 temperature = Column(Float) 2022-12-06T01:12:42,562 status = Column(Float) 2022-12-06T01:12:42,563 engine = create_engine("iotdb://root:root@127.0.0.1:6667") 2022-12-06T01:12:42,564 DbSession = sessionmaker(bind=engine) 2022-12-06T01:12:42,564 session = DbSession() 2022-12-06T01:12:42,564 res = session.query(Device.status).filter(Device.temperature > 1) 2022-12-06T01:12:42,565 for row in res: 2022-12-06T01:12:42,565 print(row) 2022-12-06T01:12:42,566 ``` 2022-12-06T01:12:42,567 ## Developers 2022-12-06T01:12:42,567 ### Introduction 2022-12-06T01:12:42,568 This is an example of how to connect to IoTDB with python, using the thrift rpc interfaces. Things are almost the same on Windows or Linux, but pay attention to the difference like path separator. 2022-12-06T01:12:42,569 ### Prerequisites 2022-12-06T01:12:42,569 Python3.7 or later is preferred. 2022-12-06T01:12:42,570 You have to install Thrift (0.11.0 or later) to compile our thrift file into python code. Below is the official tutorial of installation, eventually, you should have a thrift executable. 2022-12-06T01:12:42,571 ``` 2022-12-06T01:12:42,571 http://thrift.apache.org/docs/install/ 2022-12-06T01:12:42,571 ``` 2022-12-06T01:12:42,572 Before starting you need to install `requirements_dev.txt` in your python environment, e.g. by calling 2022-12-06T01:12:42,572 ```shell 2022-12-06T01:12:42,573 pip install -r requirements_dev.txt 2022-12-06T01:12:42,573 ``` 2022-12-06T01:12:42,574 ### Compile the thrift library and Debug 2022-12-06T01:12:42,575 In the root of IoTDB's source code folder, run `mvn clean generate-sources -pl client-py -am`. 2022-12-06T01:12:42,575 This will automatically delete and repopulate the folder `iotdb/thrift` with the generated thrift files. 2022-12-06T01:12:42,575 This folder is ignored from git and should **never be pushed to git!** 2022-12-06T01:12:42,576 **Notice** Do not upload `iotdb/thrift` to the git repo. 2022-12-06T01:12:42,578 ### Session Client & Example 2022-12-06T01:12:42,578 We packed up the Thrift interface in `client-py/src/iotdb/Session.py` (similar with its Java counterpart), also provided an example file `client-py/src/SessionExample.py` of how to use the session module. please read it carefully. 2022-12-06T01:12:42,579 Or, another simple example: 2022-12-06T01:12:42,580 ```python 2022-12-06T01:12:42,580 from iotdb.Session import Session 2022-12-06T01:12:42,581 ip = "127.0.0.1" 2022-12-06T01:12:42,581 port_ = "6667" 2022-12-06T01:12:42,581 username_ = "root" 2022-12-06T01:12:42,582 password_ = "root" 2022-12-06T01:12:42,582 session = Session(ip, port_, username_, password_) 2022-12-06T01:12:42,582 session.open(False) 2022-12-06T01:12:42,583 zone = session.get_time_zone() 2022-12-06T01:12:42,583 session.close() 2022-12-06T01:12:42,583 ``` 2022-12-06T01:12:42,584 ### Tests 2022-12-06T01:12:42,585 Please add your custom tests in `tests` folder. 2022-12-06T01:12:42,585 To run all defined tests just type `pytest .` in the root folder. 2022-12-06T01:12:42,586 **Notice** Some tests need docker to be started on your system as a test instance is started in a docker container using [testcontainers](https://testcontainers-python.readthedocs.io/en/latest/index.html). 2022-12-06T01:12:42,587 ### Futher Tools 2022-12-06T01:12:42,588 [black](https://pypi.org/project/black/) and [flake8](https://pypi.org/project/flake8/) are installed for autoformatting and linting. 2022-12-06T01:12:42,588 Both can be run by `black .` or `flake8 .` respectively. 2022-12-06T01:12:42,589 ## Releasing 2022-12-06T01:12:42,590 To do a release just ensure that you have the right set of generated thrift files. 2022-12-06T01:12:42,590 Then run linting and auto-formatting. 2022-12-06T01:12:42,590 Then, ensure that all tests work (via `pytest .`). 2022-12-06T01:12:42,590 Then you are good to go to do a release! 2022-12-06T01:12:42,592 ### Preparing your environment 2022-12-06T01:12:42,592 First, install all necessary dev dependencies via `pip install -r requirements_dev.txt`. 2022-12-06T01:12:42,593 ### Doing the Release 2022-12-06T01:12:42,594 There is a convenient script `release.sh` to do all steps for a release. 2022-12-06T01:12:42,594 Namely, these are 2022-12-06T01:12:42,595 * Remove all transient directories from last release (if exists) 2022-12-06T01:12:42,595 * (Re-)generate all generated sources via mvn 2022-12-06T01:12:42,595 * Run Linting (flake8) 2022-12-06T01:12:42,595 * Run Tests via pytest 2022-12-06T01:12:42,596 * Build 2022-12-06T01:12:42,596 * Release to pypi 2022-12-06T01:12:42,670 running egg_info 2022-12-06T01:12:42,684 writing apache_iotdb.egg-info/PKG-INFO 2022-12-06T01:12:42,690 writing dependency_links to apache_iotdb.egg-info/dependency_links.txt 2022-12-06T01:12:42,694 writing entry points to apache_iotdb.egg-info/entry_points.txt 2022-12-06T01:12:42,697 writing requirements to apache_iotdb.egg-info/requires.txt 2022-12-06T01:12:42,699 writing top-level names to apache_iotdb.egg-info/top_level.txt 2022-12-06T01:12:42,765 reading manifest file 'apache_iotdb.egg-info/SOURCES.txt' 2022-12-06T01:12:42,773 adding license file 'LICENSE' 2022-12-06T01:12:42,785 writing manifest file 'apache_iotdb.egg-info/SOURCES.txt' 2022-12-06T01:12:42,789 /tmp/pip-build-env-8invdbgq/overlay/lib/python3.7/site-packages/setuptools/_distutils/dist.py:265: UserWarning: Unknown distribution option: 'website' 2022-12-06T01:12:42,789 warnings.warn(msg) 2022-12-06T01:12:42,987 Getting requirements to build wheel: finished with status 'done' 2022-12-06T01:12:43,007 Created temporary directory: /tmp/pip-modern-metadata-p7hoqije 2022-12-06T01:12:43,013 Preparing metadata (pyproject.toml): started 2022-12-06T01:12:43,015 Running command Preparing metadata (pyproject.toml) 2022-12-06T01:12:44,659 2022-12-06T01:12:44,667 # Apache IoTDB 2022-12-06T01:12:44,667 [![Python Client](https://github.com/apache/iotdb/actions/workflows/client-python.yml/badge.svg?branch=rel%2F1.0)](https://github.com/apache/iotdb/actions/workflows/client-python.yml) 2022-12-06T01:12:44,668 [![GitHub release](https://img.shields.io/github/release/apache/iotdb.svg)](https://github.com/apache/iotdb/releases) 2022-12-06T01:12:44,668 [![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html) 2022-12-06T01:12:44,669 ![](https://github-size-badge.herokuapp.com/apache/iotdb.svg) 2022-12-06T01:12:44,669 ![](https://img.shields.io/github/downloads/apache/iotdb/total.svg) 2022-12-06T01:12:44,669 ![](https://img.shields.io/badge/platform-win%20%7C%20macos%20%7C%20linux-yellow.svg) 2022-12-06T01:12:44,669 [![IoTDB Website](https://img.shields.io/website-up-down-green-red/https/shields.io.svg?label=iotdb-website)](https://iotdb.apache.org/) 2022-12-06T01:12:44,670 Apache IoTDB (Database for Internet of Things) is an IoT native database with high performance for 2022-12-06T01:12:44,671 data management and analysis, deployable on the edge and the cloud. Due to its light-weight 2022-12-06T01:12:44,671 architecture, high performance and rich feature set together with its deep integration with 2022-12-06T01:12:44,671 Apache Hadoop, Spark and Flink, Apache IoTDB can meet the requirements of massive data storage, 2022-12-06T01:12:44,672 high-speed data ingestion and complex data analysis in the IoT industrial fields. 2022-12-06T01:12:44,672 ## Python Native API 2022-12-06T01:12:44,673 ### Requirements 2022-12-06T01:12:44,673 You have to install thrift (>=0.13) before using the package. 2022-12-06T01:12:44,675 ### How to use (Example) 2022-12-06T01:12:44,675 First, download the latest package: `pip3 install apache-iotdb` 2022-12-06T01:12:44,676 *Notice: If you are installing Python API v0.13.0, DO NOT install by `pip install apache-iotdb==0.13.0`, use `pip install apache-iotdb==0.13.0.post1` instead!* 2022-12-06T01:12:44,677 You can get an example of using the package to read and write data at here: [Example](https://github.com/apache/iotdb/blob/master/client-py/SessionExample.py) 2022-12-06T01:12:44,677 An example of aligned timeseries: [Aligned Timeseries Session Example](https://github.com/apache/iotdb/blob/master/client-py/SessionAlignedTimeseriesExample.py) 2022-12-06T01:12:44,678 (you need to add `import iotdb` in the head of the file) 2022-12-06T01:12:44,678 Or: 2022-12-06T01:12:44,679 ```python 2022-12-06T01:12:44,679 from iotdb.Session import Session 2022-12-06T01:12:44,680 ip = "127.0.0.1" 2022-12-06T01:12:44,680 port_ = "6667" 2022-12-06T01:12:44,681 username_ = "root" 2022-12-06T01:12:44,681 password_ = "root" 2022-12-06T01:12:44,681 session = Session(ip, port_, username_, password_) 2022-12-06T01:12:44,681 session.open(False) 2022-12-06T01:12:44,682 zone = session.get_time_zone() 2022-12-06T01:12:44,682 session.close() 2022-12-06T01:12:44,682 ``` 2022-12-06T01:12:44,683 ### Initialization 2022-12-06T01:12:44,684 * Initialize a Session 2022-12-06T01:12:44,684 ```python 2022-12-06T01:12:44,685 session = Session(ip, port_, username_, password_, fetch_size=1024, zone_id="UTC+8") 2022-12-06T01:12:44,685 ``` 2022-12-06T01:12:44,686 * Open a session, with a parameter to specify whether to enable RPC compression 2022-12-06T01:12:44,686 ```python 2022-12-06T01:12:44,687 session.open(enable_rpc_compression=False) 2022-12-06T01:12:44,687 ``` 2022-12-06T01:12:44,688 Notice: this RPC compression status of client must comply with that of IoTDB server 2022-12-06T01:12:44,688 * Close a Session 2022-12-06T01:12:44,689 ```python 2022-12-06T01:12:44,689 session.close() 2022-12-06T01:12:44,689 ``` 2022-12-06T01:12:44,690 ### Data Definition Interface (DDL Interface) 2022-12-06T01:12:44,690 #### DATABASE Management 2022-12-06T01:12:44,691 * CREATE DATABASE 2022-12-06T01:12:44,692 ```python 2022-12-06T01:12:44,692 session.set_storage_group(group_name) 2022-12-06T01:12:44,692 ``` 2022-12-06T01:12:44,693 * Delete one or several databases 2022-12-06T01:12:44,693 ```python 2022-12-06T01:12:44,694 session.delete_storage_group(group_name) 2022-12-06T01:12:44,694 session.delete_storage_groups(group_name_lst) 2022-12-06T01:12:44,694 ``` 2022-12-06T01:12:44,695 #### Timeseries Management 2022-12-06T01:12:44,695 * Create one or multiple timeseries 2022-12-06T01:12:44,696 ```python 2022-12-06T01:12:44,696 session.create_time_series(ts_path, data_type, encoding, compressor, 2022-12-06T01:12:44,696 props=None, tags=None, attributes=None, alias=None) 2022-12-06T01:12:44,697 session.create_multi_time_series( 2022-12-06T01:12:44,697 ts_path_lst, data_type_lst, encoding_lst, compressor_lst, 2022-12-06T01:12:44,698 props_lst=None, tags_lst=None, attributes_lst=None, alias_lst=None 2022-12-06T01:12:44,698 ) 2022-12-06T01:12:44,698 ``` 2022-12-06T01:12:44,699 * Create aligned timeseries 2022-12-06T01:12:44,700 ```python 2022-12-06T01:12:44,700 session.create_aligned_time_series( 2022-12-06T01:12:44,700 device_id, measurements_lst, data_type_lst, encoding_lst, compressor_lst 2022-12-06T01:12:44,700 ) 2022-12-06T01:12:44,701 ``` 2022-12-06T01:12:44,701 Attention: Alias of measurements are **not supported** currently. 2022-12-06T01:12:44,702 * Delete one or several timeseries 2022-12-06T01:12:44,702 ```python 2022-12-06T01:12:44,703 session.delete_time_series(paths_list) 2022-12-06T01:12:44,703 ``` 2022-12-06T01:12:44,703 * Check whether the specific timeseries exists 2022-12-06T01:12:44,704 ```python 2022-12-06T01:12:44,704 session.check_time_series_exists(path) 2022-12-06T01:12:44,705 ``` 2022-12-06T01:12:44,705 ### Data Manipulation Interface (DML Interface) 2022-12-06T01:12:44,706 #### Insert 2022-12-06T01:12:44,707 It is recommended to use insertTablet to help improve write efficiency. 2022-12-06T01:12:44,707 * Insert a Tablet,which is multiple rows of a device, each row has the same measurements 2022-12-06T01:12:44,708 * **Better Write Performance** 2022-12-06T01:12:44,708 * **Support null values**: fill the null value with any value, and then mark the null value via BitMap (from v0.13) 2022-12-06T01:12:44,709 We have two implementations of Tablet in Python API. 2022-12-06T01:12:44,710 * Normal Tablet 2022-12-06T01:12:44,710 ```python 2022-12-06T01:12:44,710 values_ = [ 2022-12-06T01:12:44,711 [False, 10, 11, 1.1, 10011.1, "test01"], 2022-12-06T01:12:44,711 [True, 100, 11111, 1.25, 101.0, "test02"], 2022-12-06T01:12:44,711 [False, 100, 1, 188.1, 688.25, "test03"], 2022-12-06T01:12:44,711 [True, 0, 0, 0, 6.25, "test04"], 2022-12-06T01:12:44,712 ] 2022-12-06T01:12:44,712 timestamps_ = [1, 2, 3, 4] 2022-12-06T01:12:44,712 tablet_ = Tablet( 2022-12-06T01:12:44,713 device_id, measurements_, data_types_, values_, timestamps_ 2022-12-06T01:12:44,713 ) 2022-12-06T01:12:44,713 session.insert_tablet(tablet_) 2022-12-06T01:12:44,714 ``` 2022-12-06T01:12:44,714 * Numpy Tablet 2022-12-06T01:12:44,714 Comparing with Tablet, Numpy Tablet is using [numpy.ndarray](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html) to record data. 2022-12-06T01:12:44,715 With less memory footprint and time cost of serialization, the insert performance will be better. 2022-12-06T01:12:44,715 **Notice** 2022-12-06T01:12:44,716 1. time and value columns in Tablet are ndarray. 2022-12-06T01:12:44,716 2. recommended to use the specific dtypes to each ndarray, see the example below 2022-12-06T01:12:44,716 (if not, the default dtypes are also ok). 2022-12-06T01:12:44,717 ```python 2022-12-06T01:12:44,717 import numpy as np 2022-12-06T01:12:44,717 data_types_ = [ 2022-12-06T01:12:44,718 TSDataType.BOOLEAN, 2022-12-06T01:12:44,718 TSDataType.INT32, 2022-12-06T01:12:44,718 TSDataType.INT64, 2022-12-06T01:12:44,719 TSDataType.FLOAT, 2022-12-06T01:12:44,719 TSDataType.DOUBLE, 2022-12-06T01:12:44,719 TSDataType.TEXT, 2022-12-06T01:12:44,720 ] 2022-12-06T01:12:44,720 np_values_ = [ 2022-12-06T01:12:44,720 np.array([False, True, False, True], TSDataType.BOOLEAN.np_dtype()), 2022-12-06T01:12:44,721 np.array([10, 100, 100, 0], TSDataType.INT32.np_dtype()), 2022-12-06T01:12:44,721 np.array([11, 11111, 1, 0], TSDataType.INT64.np_dtype()), 2022-12-06T01:12:44,721 np.array([1.1, 1.25, 188.1, 0], TSDataType.FLOAT.np_dtype()), 2022-12-06T01:12:44,721 np.array([10011.1, 101.0, 688.25, 6.25], TSDataType.DOUBLE.np_dtype()), 2022-12-06T01:12:44,722 np.array(["test01", "test02", "test03", "test04"], TSDataType.TEXT.np_dtype()), 2022-12-06T01:12:44,722 ] 2022-12-06T01:12:44,722 np_timestamps_ = np.array([1, 2, 3, 4], TSDataType.INT64.np_dtype()) 2022-12-06T01:12:44,723 np_tablet_ = NumpyTablet( 2022-12-06T01:12:44,723 "root.sg_test_01.d_02", measurements_, data_types_, np_values_, np_timestamps_ 2022-12-06T01:12:44,723 ) 2022-12-06T01:12:44,723 session.insert_tablet(np_tablet_) 2022-12-06T01:12:44,724 ``` 2022-12-06T01:12:44,724 * Insert multiple Tablets 2022-12-06T01:12:44,725 ```python 2022-12-06T01:12:44,725 session.insert_tablets(tablet_lst) 2022-12-06T01:12:44,726 ``` 2022-12-06T01:12:44,726 * Insert a Record 2022-12-06T01:12:44,727 ```python 2022-12-06T01:12:44,727 session.insert_record(device_id, timestamp, measurements_, data_types_, values_) 2022-12-06T01:12:44,728 ``` 2022-12-06T01:12:44,728 * Insert multiple Records 2022-12-06T01:12:44,729 ```python 2022-12-06T01:12:44,729 session.insert_records( 2022-12-06T01:12:44,729 device_ids_, time_list_, measurements_list_, data_type_list_, values_list_ 2022-12-06T01:12:44,730 ) 2022-12-06T01:12:44,730 ``` 2022-12-06T01:12:44,731 * Insert multiple Records that belong to the same device. 2022-12-06T01:12:44,731 With type info the server has no need to do type inference, which leads a better performance 2022-12-06T01:12:44,732 ```python 2022-12-06T01:12:44,732 session.insert_records_of_one_device(device_id, time_list, measurements_list, data_types_list, values_list) 2022-12-06T01:12:44,732 ``` 2022-12-06T01:12:44,733 #### Insert with type inference 2022-12-06T01:12:44,733 When the data is of String type, we can use the following interface to perform type inference based on the value of the value itself. For example, if value is "true" , it can be automatically inferred to be a boolean type. If value is "3.2" , it can be automatically inferred as a flout type. Without type information, server has to do type inference, which may cost some time. 2022-12-06T01:12:44,734 * Insert a Record, which contains multiple measurement value of a device at a timestamp 2022-12-06T01:12:44,735 ```python 2022-12-06T01:12:44,735 session.insert_str_record(device_id, timestamp, measurements, string_values) 2022-12-06T01:12:44,735 ``` 2022-12-06T01:12:44,736 #### Insert of Aligned Timeseries 2022-12-06T01:12:44,736 The Insert of aligned timeseries uses interfaces like insert_aligned_XXX, and others are similar to the above interfaces: 2022-12-06T01:12:44,737 * insert_aligned_record 2022-12-06T01:12:44,737 * insert_aligned_records 2022-12-06T01:12:44,738 * insert_aligned_records_of_one_device 2022-12-06T01:12:44,738 * insert_aligned_tablet 2022-12-06T01:12:44,738 * insert_aligned_tablets 2022-12-06T01:12:44,739 ### IoTDB-SQL Interface 2022-12-06T01:12:44,740 * Execute query statement 2022-12-06T01:12:44,740 ```python 2022-12-06T01:12:44,741 session.execute_query_statement(sql) 2022-12-06T01:12:44,741 ``` 2022-12-06T01:12:44,742 * Execute non query statement 2022-12-06T01:12:44,742 ```python 2022-12-06T01:12:44,742 session.execute_non_query_statement(sql) 2022-12-06T01:12:44,743 ``` 2022-12-06T01:12:44,743 * Execute statement 2022-12-06T01:12:44,744 ```python 2022-12-06T01:12:44,744 session.execute_statement(sql) 2022-12-06T01:12:44,744 ``` 2022-12-06T01:12:44,745 ### Schema Template 2022-12-06T01:12:44,745 #### Create Schema Template 2022-12-06T01:12:44,746 The step for creating a metadata template is as follows 2022-12-06T01:12:44,746 1. Create the template class 2022-12-06T01:12:44,746 2. Adding child Node,InternalNode and MeasurementNode can be chose 2022-12-06T01:12:44,747 3. Execute create schema template function 2022-12-06T01:12:44,747 ```python 2022-12-06T01:12:44,748 template = Template(name=template_name, share_time=True) 2022-12-06T01:12:44,748 i_node_gps = InternalNode(name="GPS", share_time=False) 2022-12-06T01:12:44,748 i_node_v = InternalNode(name="vehicle", share_time=True) 2022-12-06T01:12:44,749 m_node_x = MeasurementNode("x", TSDataType.FLOAT, TSEncoding.RLE, Compressor.SNAPPY) 2022-12-06T01:12:44,749 i_node_gps.add_child(m_node_x) 2022-12-06T01:12:44,750 i_node_v.add_child(m_node_x) 2022-12-06T01:12:44,750 template.add_template(i_node_gps) 2022-12-06T01:12:44,750 template.add_template(i_node_v) 2022-12-06T01:12:44,751 template.add_template(m_node_x) 2022-12-06T01:12:44,751 session.create_schema_template(template) 2022-12-06T01:12:44,752 ``` 2022-12-06T01:12:44,752 #### Modify Schema Template nodes 2022-12-06T01:12:44,752 Modify nodes in a template, the template must be already created. These are functions that add or delete some measurement nodes. 2022-12-06T01:12:44,752 * add node in template 2022-12-06T01:12:44,753 ```python 2022-12-06T01:12:44,753 session.add_measurements_in_template(template_name, measurements_path, data_types, encodings, compressors, is_aligned) 2022-12-06T01:12:44,753 ``` 2022-12-06T01:12:44,754 * delete node in template 2022-12-06T01:12:44,754 ```python 2022-12-06T01:12:44,754 session.delete_node_in_template(template_name, path) 2022-12-06T01:12:44,755 ``` 2022-12-06T01:12:44,755 #### Set Schema Template 2022-12-06T01:12:44,756 ```python 2022-12-06T01:12:44,756 session.set_schema_template(template_name, prefix_path) 2022-12-06T01:12:44,756 ``` 2022-12-06T01:12:44,757 #### Uset Schema Template 2022-12-06T01:12:44,757 ```python 2022-12-06T01:12:44,758 session.unset_schema_template(template_name, prefix_path) 2022-12-06T01:12:44,758 ``` 2022-12-06T01:12:44,758 #### Show Schema Template 2022-12-06T01:12:44,759 * Show all schema templates 2022-12-06T01:12:44,759 ```python 2022-12-06T01:12:44,759 session.show_all_templates() 2022-12-06T01:12:44,760 ``` 2022-12-06T01:12:44,760 * Count all nodes in templates 2022-12-06T01:12:44,760 ```python 2022-12-06T01:12:44,760 session.count_measurements_in_template(template_name) 2022-12-06T01:12:44,761 ``` 2022-12-06T01:12:44,761 * Judge whether the path is measurement or not in templates, This measurement must be in the template 2022-12-06T01:12:44,762 ```python 2022-12-06T01:12:44,762 session.count_measurements_in_template(template_name, path) 2022-12-06T01:12:44,762 ``` 2022-12-06T01:12:44,763 * Judge whether the path is exist or not in templates, This path may not belong to the template 2022-12-06T01:12:44,763 ```python 2022-12-06T01:12:44,763 session.is_path_exist_in_template(template_name, path) 2022-12-06T01:12:44,764 ``` 2022-12-06T01:12:44,764 * Show nodes under in schema template 2022-12-06T01:12:44,765 ```python 2022-12-06T01:12:44,765 session.show_measurements_in_template(template_name) 2022-12-06T01:12:44,765 ``` 2022-12-06T01:12:44,766 * Show the path prefix where a schema template is set 2022-12-06T01:12:44,766 ```python 2022-12-06T01:12:44,766 session.show_paths_template_set_on(template_name) 2022-12-06T01:12:44,767 ``` 2022-12-06T01:12:44,767 * Show the path prefix where a schema template is used (i.e. the time series has been created) 2022-12-06T01:12:44,768 ```python 2022-12-06T01:12:44,768 session.show_paths_template_using_on(template_name) 2022-12-06T01:12:44,768 ``` 2022-12-06T01:12:44,769 #### Drop Schema Template 2022-12-06T01:12:44,769 Delete an existing metadata template,dropping an already set template is not supported 2022-12-06T01:12:44,770 ```python 2022-12-06T01:12:44,770 session.drop_schema_template("template_python") 2022-12-06T01:12:44,770 ``` 2022-12-06T01:12:44,771 ### Pandas Support 2022-12-06T01:12:44,772 To easily transform a query result to a [Pandas Dataframe](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html) 2022-12-06T01:12:44,772 the SessionDataSet has a method `.todf()` which consumes the dataset and transforms it to a pandas dataframe. 2022-12-06T01:12:44,773 Example: 2022-12-06T01:12:44,773 ```python 2022-12-06T01:12:44,774 from iotdb.Session import Session 2022-12-06T01:12:44,774 ip = "127.0.0.1" 2022-12-06T01:12:44,774 port_ = "6667" 2022-12-06T01:12:44,775 username_ = "root" 2022-12-06T01:12:44,775 password_ = "root" 2022-12-06T01:12:44,775 session = Session(ip, port_, username_, password_) 2022-12-06T01:12:44,776 session.open(False) 2022-12-06T01:12:44,776 result = session.execute_query_statement("SELECT * FROM root.*") 2022-12-06T01:12:44,777 # Transform to Pandas Dataset 2022-12-06T01:12:44,777 df = result.todf() 2022-12-06T01:12:44,777 session.close() 2022-12-06T01:12:44,778 # Now you can work with the dataframe 2022-12-06T01:12:44,778 df = ... 2022-12-06T01:12:44,779 ``` 2022-12-06T01:12:44,780 ### IoTDB Testcontainer 2022-12-06T01:12:44,780 The Test Support is based on the lib `testcontainers` (https://testcontainers-python.readthedocs.io/en/latest/index.html) which you need to install in your project if you want to use the feature. 2022-12-06T01:12:44,781 To start (and stop) an IoTDB Database in a Docker container simply do: 2022-12-06T01:12:44,781 ```python 2022-12-06T01:12:44,781 class MyTestCase(unittest.TestCase): 2022-12-06T01:12:44,782 def test_something(self): 2022-12-06T01:12:44,782 with IoTDBContainer() as c: 2022-12-06T01:12:44,782 session = Session("localhost", c.get_exposed_port(6667), "root", "root") 2022-12-06T01:12:44,783 session.open(False) 2022-12-06T01:12:44,783 result = session.execute_query_statement("SHOW TIMESERIES") 2022-12-06T01:12:44,783 print(result) 2022-12-06T01:12:44,784 session.close() 2022-12-06T01:12:44,784 ``` 2022-12-06T01:12:44,784 by default it will load the image `apache/iotdb:latest`, if you want a specific version just pass it like e.g. `IoTDBContainer("apache/iotdb:0.12.0")` to get version `0.12.0` running. 2022-12-06T01:12:44,785 ### IoTDB DBAPI 2022-12-06T01:12:44,786 IoTDB DBAPI implements the Python DB API 2.0 specification (https://peps.python.org/pep-0249/), which defines a common 2022-12-06T01:12:44,786 interface for accessing databases in Python. 2022-12-06T01:12:44,787 #### Examples 2022-12-06T01:12:44,787 + Initialization 2022-12-06T01:12:44,788 The initialized parameters are consistent with the session part (except for the sqlalchemy_mode). 2022-12-06T01:12:44,788 ```python 2022-12-06T01:12:44,789 from iotdb.dbapi import connect 2022-12-06T01:12:44,789 ip = "127.0.0.1" 2022-12-06T01:12:44,789 port_ = "6667" 2022-12-06T01:12:44,790 username_ = "root" 2022-12-06T01:12:44,790 password_ = "root" 2022-12-06T01:12:44,790 conn = connect(ip, port_, username_, password_,fetch_size=1024,zone_id="UTC+8",sqlalchemy_mode=False) 2022-12-06T01:12:44,791 cursor = conn.cursor() 2022-12-06T01:12:44,791 ``` 2022-12-06T01:12:44,791 + simple SQL statement execution 2022-12-06T01:12:44,792 ```python 2022-12-06T01:12:44,792 cursor.execute("SELECT * FROM root.*") 2022-12-06T01:12:44,792 for row in cursor.fetchall(): 2022-12-06T01:12:44,792 print(row) 2022-12-06T01:12:44,793 ``` 2022-12-06T01:12:44,793 + execute SQL with parameter 2022-12-06T01:12:44,794 IoTDB DBAPI supports pyformat style parameters 2022-12-06T01:12:44,794 ```python 2022-12-06T01:12:44,795 cursor.execute("SELECT * FROM root.* WHERE time < %(time)s",{"time":"2017-11-01T00:08:00.000"}) 2022-12-06T01:12:44,795 for row in cursor.fetchall(): 2022-12-06T01:12:44,795 print(row) 2022-12-06T01:12:44,796 ``` 2022-12-06T01:12:44,796 + execute SQL with parameter sequences 2022-12-06T01:12:44,796 ```python 2022-12-06T01:12:44,797 seq_of_parameters = [ 2022-12-06T01:12:44,797 {"timestamp": 1, "temperature": 1}, 2022-12-06T01:12:44,797 {"timestamp": 2, "temperature": 2}, 2022-12-06T01:12:44,798 {"timestamp": 3, "temperature": 3}, 2022-12-06T01:12:44,798 {"timestamp": 4, "temperature": 4}, 2022-12-06T01:12:44,798 {"timestamp": 5, "temperature": 5}, 2022-12-06T01:12:44,798 ] 2022-12-06T01:12:44,799 sql = "insert into root.cursor(timestamp,temperature) values(%(timestamp)s,%(temperature)s)" 2022-12-06T01:12:44,799 cursor.executemany(sql,seq_of_parameters) 2022-12-06T01:12:44,799 ``` 2022-12-06T01:12:44,800 + close the connection and cursor 2022-12-06T01:12:44,800 ```python 2022-12-06T01:12:44,800 cursor.close() 2022-12-06T01:12:44,801 conn.close() 2022-12-06T01:12:44,801 ``` 2022-12-06T01:12:44,802 ### IoTDB SQLAlchemy Dialect (Experimental) 2022-12-06T01:12:44,802 The SQLAlchemy dialect of IoTDB is written to adapt to Apache Superset. 2022-12-06T01:12:44,802 This part is still being improved. 2022-12-06T01:12:44,802 Please do not use it in the production environment! 2022-12-06T01:12:44,803 #### Mapping of the metadata 2022-12-06T01:12:44,803 The data model used by SQLAlchemy is a relational data model, which describes the relationships between different entities through tables. 2022-12-06T01:12:44,803 While the data model of IoTDB is a hierarchical data model, which organizes the data through a tree structure. 2022-12-06T01:12:44,804 In order to adapt IoTDB to the dialect of SQLAlchemy, the original data model in IoTDB needs to be reorganized. 2022-12-06T01:12:44,804 Converting the data model of IoTDB into the data model of SQLAlchemy. 2022-12-06T01:12:44,804 The metadata in the IoTDB are: 2022-12-06T01:12:44,805 1. Database 2022-12-06T01:12:44,805 2. Path 2022-12-06T01:12:44,806 3. Entity 2022-12-06T01:12:44,806 4. Measurement 2022-12-06T01:12:44,806 The metadata in the SQLAlchemy are: 2022-12-06T01:12:44,807 1. Schema 2022-12-06T01:12:44,807 2. Table 2022-12-06T01:12:44,807 3. Column 2022-12-06T01:12:44,808 The mapping relationship between them is: 2022-12-06T01:12:44,808 | The metadata in the SQLAlchemy | The metadata in the IoTDB | 2022-12-06T01:12:44,809 | -------------------- | ---------------------------------------------- | 2022-12-06T01:12:44,809 | Schema | Database | 2022-12-06T01:12:44,809 | Table | Path ( from database to entity ) + Entity | 2022-12-06T01:12:44,810 | Column | Measurement | 2022-12-06T01:12:44,810 The following figure shows the relationship between the two more intuitively: 2022-12-06T01:12:44,811 ![sqlalchemy-to-iotdb](https://github.com/apache/iotdb-bin-resources/blob/main/docs/UserGuide/API/IoTDB-SQLAlchemy/sqlalchemy-to-iotdb.png?raw=true) 2022-12-06T01:12:44,811 #### Data type mapping 2022-12-06T01:12:44,812 | data type in IoTDB | data type in SQLAlchemy | 2022-12-06T01:12:44,812 |--------------------|-------------------------| 2022-12-06T01:12:44,812 | BOOLEAN | Boolean | 2022-12-06T01:12:44,813 | INT32 | Integer | 2022-12-06T01:12:44,813 | INT64 | BigInteger | 2022-12-06T01:12:44,813 | FLOAT | Float | 2022-12-06T01:12:44,814 | DOUBLE | Float | 2022-12-06T01:12:44,814 | TEXT | Text | 2022-12-06T01:12:44,814 | LONG | BigInteger | 2022-12-06T01:12:44,814 #### Example 2022-12-06T01:12:44,815 + execute statement 2022-12-06T01:12:44,816 ```python 2022-12-06T01:12:44,816 from sqlalchemy import create_engine 2022-12-06T01:12:44,817 engine = create_engine("iotdb://root:root@127.0.0.1:6667") 2022-12-06T01:12:44,817 connect = engine.connect() 2022-12-06T01:12:44,817 result = connect.execute("SELECT ** FROM root") 2022-12-06T01:12:44,818 for row in result.fetchall(): 2022-12-06T01:12:44,818 print(row) 2022-12-06T01:12:44,818 ``` 2022-12-06T01:12:44,819 + ORM (now only simple queries are supported) 2022-12-06T01:12:44,819 ```python 2022-12-06T01:12:44,820 from sqlalchemy import create_engine, Column, Float, BigInteger, MetaData 2022-12-06T01:12:44,820 from sqlalchemy.ext.declarative import declarative_base 2022-12-06T01:12:44,820 from sqlalchemy.orm import sessionmaker 2022-12-06T01:12:44,821 metadata = MetaData( 2022-12-06T01:12:44,821 schema='root.factory' 2022-12-06T01:12:44,821 ) 2022-12-06T01:12:44,822 Base = declarative_base(metadata=metadata) 2022-12-06T01:12:44,823 class Device(Base): 2022-12-06T01:12:44,823 __tablename__ = "room2.device1" 2022-12-06T01:12:44,823 Time = Column(BigInteger, primary_key=True) 2022-12-06T01:12:44,824 temperature = Column(Float) 2022-12-06T01:12:44,824 status = Column(Float) 2022-12-06T01:12:44,825 engine = create_engine("iotdb://root:root@127.0.0.1:6667") 2022-12-06T01:12:44,825 DbSession = sessionmaker(bind=engine) 2022-12-06T01:12:44,826 session = DbSession() 2022-12-06T01:12:44,826 res = session.query(Device.status).filter(Device.temperature > 1) 2022-12-06T01:12:44,827 for row in res: 2022-12-06T01:12:44,827 print(row) 2022-12-06T01:12:44,827 ``` 2022-12-06T01:12:44,828 ## Developers 2022-12-06T01:12:44,829 ### Introduction 2022-12-06T01:12:44,829 This is an example of how to connect to IoTDB with python, using the thrift rpc interfaces. Things are almost the same on Windows or Linux, but pay attention to the difference like path separator. 2022-12-06T01:12:44,831 ### Prerequisites 2022-12-06T01:12:44,831 Python3.7 or later is preferred. 2022-12-06T01:12:44,832 You have to install Thrift (0.11.0 or later) to compile our thrift file into python code. Below is the official tutorial of installation, eventually, you should have a thrift executable. 2022-12-06T01:12:44,832 ``` 2022-12-06T01:12:44,833 http://thrift.apache.org/docs/install/ 2022-12-06T01:12:44,833 ``` 2022-12-06T01:12:44,833 Before starting you need to install `requirements_dev.txt` in your python environment, e.g. by calling 2022-12-06T01:12:44,834 ```shell 2022-12-06T01:12:44,834 pip install -r requirements_dev.txt 2022-12-06T01:12:44,834 ``` 2022-12-06T01:12:44,835 ### Compile the thrift library and Debug 2022-12-06T01:12:44,836 In the root of IoTDB's source code folder, run `mvn clean generate-sources -pl client-py -am`. 2022-12-06T01:12:44,837 This will automatically delete and repopulate the folder `iotdb/thrift` with the generated thrift files. 2022-12-06T01:12:44,837 This folder is ignored from git and should **never be pushed to git!** 2022-12-06T01:12:44,838 **Notice** Do not upload `iotdb/thrift` to the git repo. 2022-12-06T01:12:44,839 ### Session Client & Example 2022-12-06T01:12:44,840 We packed up the Thrift interface in `client-py/src/iotdb/Session.py` (similar with its Java counterpart), also provided an example file `client-py/src/SessionExample.py` of how to use the session module. please read it carefully. 2022-12-06T01:12:44,841 Or, another simple example: 2022-12-06T01:12:44,841 ```python 2022-12-06T01:12:44,841 from iotdb.Session import Session 2022-12-06T01:12:44,842 ip = "127.0.0.1" 2022-12-06T01:12:44,842 port_ = "6667" 2022-12-06T01:12:44,843 username_ = "root" 2022-12-06T01:12:44,843 password_ = "root" 2022-12-06T01:12:44,843 session = Session(ip, port_, username_, password_) 2022-12-06T01:12:44,844 session.open(False) 2022-12-06T01:12:44,844 zone = session.get_time_zone() 2022-12-06T01:12:44,844 session.close() 2022-12-06T01:12:44,844 ``` 2022-12-06T01:12:44,846 ### Tests 2022-12-06T01:12:44,846 Please add your custom tests in `tests` folder. 2022-12-06T01:12:44,847 To run all defined tests just type `pytest .` in the root folder. 2022-12-06T01:12:44,848 **Notice** Some tests need docker to be started on your system as a test instance is started in a docker container using [testcontainers](https://testcontainers-python.readthedocs.io/en/latest/index.html). 2022-12-06T01:12:44,849 ### Futher Tools 2022-12-06T01:12:44,849 [black](https://pypi.org/project/black/) and [flake8](https://pypi.org/project/flake8/) are installed for autoformatting and linting. 2022-12-06T01:12:44,850 Both can be run by `black .` or `flake8 .` respectively. 2022-12-06T01:12:44,851 ## Releasing 2022-12-06T01:12:44,852 To do a release just ensure that you have the right set of generated thrift files. 2022-12-06T01:12:44,852 Then run linting and auto-formatting. 2022-12-06T01:12:44,852 Then, ensure that all tests work (via `pytest .`). 2022-12-06T01:12:44,852 Then you are good to go to do a release! 2022-12-06T01:12:44,854 ### Preparing your environment 2022-12-06T01:12:44,854 First, install all necessary dev dependencies via `pip install -r requirements_dev.txt`. 2022-12-06T01:12:44,855 ### Doing the Release 2022-12-06T01:12:44,856 There is a convenient script `release.sh` to do all steps for a release. 2022-12-06T01:12:44,856 Namely, these are 2022-12-06T01:12:44,857 * Remove all transient directories from last release (if exists) 2022-12-06T01:12:44,857 * (Re-)generate all generated sources via mvn 2022-12-06T01:12:44,857 * Run Linting (flake8) 2022-12-06T01:12:44,858 * Run Tests via pytest 2022-12-06T01:12:44,858 * Build 2022-12-06T01:12:44,858 * Release to pypi 2022-12-06T01:12:44,862 running dist_info 2022-12-06T01:12:44,907 creating /tmp/pip-modern-metadata-p7hoqije/apache_iotdb.egg-info 2022-12-06T01:12:44,918 writing /tmp/pip-modern-metadata-p7hoqije/apache_iotdb.egg-info/PKG-INFO 2022-12-06T01:12:44,924 writing dependency_links to /tmp/pip-modern-metadata-p7hoqije/apache_iotdb.egg-info/dependency_links.txt 2022-12-06T01:12:44,928 writing entry points to /tmp/pip-modern-metadata-p7hoqije/apache_iotdb.egg-info/entry_points.txt 2022-12-06T01:12:44,931 writing requirements to /tmp/pip-modern-metadata-p7hoqije/apache_iotdb.egg-info/requires.txt 2022-12-06T01:12:44,933 writing top-level names to /tmp/pip-modern-metadata-p7hoqije/apache_iotdb.egg-info/top_level.txt 2022-12-06T01:12:44,936 writing manifest file '/tmp/pip-modern-metadata-p7hoqije/apache_iotdb.egg-info/SOURCES.txt' 2022-12-06T01:12:44,998 reading manifest file '/tmp/pip-modern-metadata-p7hoqije/apache_iotdb.egg-info/SOURCES.txt' 2022-12-06T01:12:45,005 adding license file 'LICENSE' 2022-12-06T01:12:45,015 writing manifest file '/tmp/pip-modern-metadata-p7hoqije/apache_iotdb.egg-info/SOURCES.txt' 2022-12-06T01:12:45,017 creating '/tmp/pip-modern-metadata-p7hoqije/apache_iotdb-1.0.0.dist-info' 2022-12-06T01:12:45,212 /tmp/pip-build-env-8invdbgq/overlay/lib/python3.7/site-packages/setuptools/_distutils/dist.py:265: UserWarning: Unknown distribution option: 'website' 2022-12-06T01:12:45,212 warnings.warn(msg) 2022-12-06T01:12:45,419 Preparing metadata (pyproject.toml): finished with status 'done' 2022-12-06T01:12:45,438 Source in /tmp/pip-wheel-u9q8tpfy/apache-iotdb_375355d01e6e48f7946961fe6ca72f16 has version 1.0.0, which satisfies requirement apache-iotdb==1.0.0 from https://files.pythonhosted.org/packages/49/91/11702001bdc0af0266d5f4dd222b5f937684e8c08e5044735ade6748cd58/apache-iotdb-1.0.0.tar.gz 2022-12-06T01:12:45,440 Removed apache-iotdb==1.0.0 from https://files.pythonhosted.org/packages/49/91/11702001bdc0af0266d5f4dd222b5f937684e8c08e5044735ade6748cd58/apache-iotdb-1.0.0.tar.gz from build tracker '/tmp/pip-build-tracker-epsjtati' 2022-12-06T01:12:45,458 Created temporary directory: /tmp/pip-unpack-yafbf32_ 2022-12-06T01:12:45,459 Building wheels for collected packages: apache-iotdb 2022-12-06T01:12:45,468 Created temporary directory: /tmp/pip-wheel-6pi8p1na 2022-12-06T01:12:45,469 Destination directory: /tmp/pip-wheel-6pi8p1na 2022-12-06T01:12:45,473 Building wheel for apache-iotdb (pyproject.toml): started 2022-12-06T01:12:45,475 Running command Building wheel for apache-iotdb (pyproject.toml) 2022-12-06T01:12:47,093 2022-12-06T01:12:47,100 # Apache IoTDB 2022-12-06T01:12:47,101 [![Python Client](https://github.com/apache/iotdb/actions/workflows/client-python.yml/badge.svg?branch=rel%2F1.0)](https://github.com/apache/iotdb/actions/workflows/client-python.yml) 2022-12-06T01:12:47,101 [![GitHub release](https://img.shields.io/github/release/apache/iotdb.svg)](https://github.com/apache/iotdb/releases) 2022-12-06T01:12:47,102 [![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html) 2022-12-06T01:12:47,102 ![](https://github-size-badge.herokuapp.com/apache/iotdb.svg) 2022-12-06T01:12:47,102 ![](https://img.shields.io/github/downloads/apache/iotdb/total.svg) 2022-12-06T01:12:47,103 ![](https://img.shields.io/badge/platform-win%20%7C%20macos%20%7C%20linux-yellow.svg) 2022-12-06T01:12:47,103 [![IoTDB Website](https://img.shields.io/website-up-down-green-red/https/shields.io.svg?label=iotdb-website)](https://iotdb.apache.org/) 2022-12-06T01:12:47,104 Apache IoTDB (Database for Internet of Things) is an IoT native database with high performance for 2022-12-06T01:12:47,104 data management and analysis, deployable on the edge and the cloud. Due to its light-weight 2022-12-06T01:12:47,105 architecture, high performance and rich feature set together with its deep integration with 2022-12-06T01:12:47,105 Apache Hadoop, Spark and Flink, Apache IoTDB can meet the requirements of massive data storage, 2022-12-06T01:12:47,105 high-speed data ingestion and complex data analysis in the IoT industrial fields. 2022-12-06T01:12:47,106 ## Python Native API 2022-12-06T01:12:47,107 ### Requirements 2022-12-06T01:12:47,107 You have to install thrift (>=0.13) before using the package. 2022-12-06T01:12:47,108 ### How to use (Example) 2022-12-06T01:12:47,109 First, download the latest package: `pip3 install apache-iotdb` 2022-12-06T01:12:47,110 *Notice: If you are installing Python API v0.13.0, DO NOT install by `pip install apache-iotdb==0.13.0`, use `pip install apache-iotdb==0.13.0.post1` instead!* 2022-12-06T01:12:47,110 You can get an example of using the package to read and write data at here: [Example](https://github.com/apache/iotdb/blob/master/client-py/SessionExample.py) 2022-12-06T01:12:47,111 An example of aligned timeseries: [Aligned Timeseries Session Example](https://github.com/apache/iotdb/blob/master/client-py/SessionAlignedTimeseriesExample.py) 2022-12-06T01:12:47,111 (you need to add `import iotdb` in the head of the file) 2022-12-06T01:12:47,112 Or: 2022-12-06T01:12:47,113 ```python 2022-12-06T01:12:47,113 from iotdb.Session import Session 2022-12-06T01:12:47,114 ip = "127.0.0.1" 2022-12-06T01:12:47,114 port_ = "6667" 2022-12-06T01:12:47,114 username_ = "root" 2022-12-06T01:12:47,114 password_ = "root" 2022-12-06T01:12:47,115 session = Session(ip, port_, username_, password_) 2022-12-06T01:12:47,115 session.open(False) 2022-12-06T01:12:47,115 zone = session.get_time_zone() 2022-12-06T01:12:47,116 session.close() 2022-12-06T01:12:47,116 ``` 2022-12-06T01:12:47,117 ### Initialization 2022-12-06T01:12:47,117 * Initialize a Session 2022-12-06T01:12:47,118 ```python 2022-12-06T01:12:47,118 session = Session(ip, port_, username_, password_, fetch_size=1024, zone_id="UTC+8") 2022-12-06T01:12:47,118 ``` 2022-12-06T01:12:47,119 * Open a session, with a parameter to specify whether to enable RPC compression 2022-12-06T01:12:47,120 ```python 2022-12-06T01:12:47,120 session.open(enable_rpc_compression=False) 2022-12-06T01:12:47,120 ``` 2022-12-06T01:12:47,121 Notice: this RPC compression status of client must comply with that of IoTDB server 2022-12-06T01:12:47,121 * Close a Session 2022-12-06T01:12:47,122 ```python 2022-12-06T01:12:47,122 session.close() 2022-12-06T01:12:47,123 ``` 2022-12-06T01:12:47,123 ### Data Definition Interface (DDL Interface) 2022-12-06T01:12:47,124 #### DATABASE Management 2022-12-06T01:12:47,124 * CREATE DATABASE 2022-12-06T01:12:47,125 ```python 2022-12-06T01:12:47,125 session.set_storage_group(group_name) 2022-12-06T01:12:47,125 ``` 2022-12-06T01:12:47,126 * Delete one or several databases 2022-12-06T01:12:47,127 ```python 2022-12-06T01:12:47,127 session.delete_storage_group(group_name) 2022-12-06T01:12:47,128 session.delete_storage_groups(group_name_lst) 2022-12-06T01:12:47,128 ``` 2022-12-06T01:12:47,128 #### Timeseries Management 2022-12-06T01:12:47,129 * Create one or multiple timeseries 2022-12-06T01:12:47,129 ```python 2022-12-06T01:12:47,130 session.create_time_series(ts_path, data_type, encoding, compressor, 2022-12-06T01:12:47,130 props=None, tags=None, attributes=None, alias=None) 2022-12-06T01:12:47,131 session.create_multi_time_series( 2022-12-06T01:12:47,131 ts_path_lst, data_type_lst, encoding_lst, compressor_lst, 2022-12-06T01:12:47,131 props_lst=None, tags_lst=None, attributes_lst=None, alias_lst=None 2022-12-06T01:12:47,131 ) 2022-12-06T01:12:47,132 ``` 2022-12-06T01:12:47,132 * Create aligned timeseries 2022-12-06T01:12:47,133 ```python 2022-12-06T01:12:47,133 session.create_aligned_time_series( 2022-12-06T01:12:47,134 device_id, measurements_lst, data_type_lst, encoding_lst, compressor_lst 2022-12-06T01:12:47,134 ) 2022-12-06T01:12:47,134 ``` 2022-12-06T01:12:47,135 Attention: Alias of measurements are **not supported** currently. 2022-12-06T01:12:47,135 * Delete one or several timeseries 2022-12-06T01:12:47,136 ```python 2022-12-06T01:12:47,136 session.delete_time_series(paths_list) 2022-12-06T01:12:47,137 ``` 2022-12-06T01:12:47,137 * Check whether the specific timeseries exists 2022-12-06T01:12:47,138 ```python 2022-12-06T01:12:47,138 session.check_time_series_exists(path) 2022-12-06T01:12:47,138 ``` 2022-12-06T01:12:47,139 ### Data Manipulation Interface (DML Interface) 2022-12-06T01:12:47,140 #### Insert 2022-12-06T01:12:47,140 It is recommended to use insertTablet to help improve write efficiency. 2022-12-06T01:12:47,141 * Insert a Tablet,which is multiple rows of a device, each row has the same measurements 2022-12-06T01:12:47,141 * **Better Write Performance** 2022-12-06T01:12:47,142 * **Support null values**: fill the null value with any value, and then mark the null value via BitMap (from v0.13) 2022-12-06T01:12:47,142 We have two implementations of Tablet in Python API. 2022-12-06T01:12:47,143 * Normal Tablet 2022-12-06T01:12:47,144 ```python 2022-12-06T01:12:47,144 values_ = [ 2022-12-06T01:12:47,144 [False, 10, 11, 1.1, 10011.1, "test01"], 2022-12-06T01:12:47,145 [True, 100, 11111, 1.25, 101.0, "test02"], 2022-12-06T01:12:47,145 [False, 100, 1, 188.1, 688.25, "test03"], 2022-12-06T01:12:47,145 [True, 0, 0, 0, 6.25, "test04"], 2022-12-06T01:12:47,145 ] 2022-12-06T01:12:47,146 timestamps_ = [1, 2, 3, 4] 2022-12-06T01:12:47,146 tablet_ = Tablet( 2022-12-06T01:12:47,146 device_id, measurements_, data_types_, values_, timestamps_ 2022-12-06T01:12:47,147 ) 2022-12-06T01:12:47,147 session.insert_tablet(tablet_) 2022-12-06T01:12:47,147 ``` 2022-12-06T01:12:47,148 * Numpy Tablet 2022-12-06T01:12:47,148 Comparing with Tablet, Numpy Tablet is using [numpy.ndarray](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html) to record data. 2022-12-06T01:12:47,148 With less memory footprint and time cost of serialization, the insert performance will be better. 2022-12-06T01:12:47,149 **Notice** 2022-12-06T01:12:47,149 1. time and value columns in Tablet are ndarray. 2022-12-06T01:12:47,150 2. recommended to use the specific dtypes to each ndarray, see the example below 2022-12-06T01:12:47,150 (if not, the default dtypes are also ok). 2022-12-06T01:12:47,151 ```python 2022-12-06T01:12:47,151 import numpy as np 2022-12-06T01:12:47,151 data_types_ = [ 2022-12-06T01:12:47,151 TSDataType.BOOLEAN, 2022-12-06T01:12:47,152 TSDataType.INT32, 2022-12-06T01:12:47,152 TSDataType.INT64, 2022-12-06T01:12:47,152 TSDataType.FLOAT, 2022-12-06T01:12:47,153 TSDataType.DOUBLE, 2022-12-06T01:12:47,153 TSDataType.TEXT, 2022-12-06T01:12:47,153 ] 2022-12-06T01:12:47,153 np_values_ = [ 2022-12-06T01:12:47,154 np.array([False, True, False, True], TSDataType.BOOLEAN.np_dtype()), 2022-12-06T01:12:47,154 np.array([10, 100, 100, 0], TSDataType.INT32.np_dtype()), 2022-12-06T01:12:47,154 np.array([11, 11111, 1, 0], TSDataType.INT64.np_dtype()), 2022-12-06T01:12:47,155 np.array([1.1, 1.25, 188.1, 0], TSDataType.FLOAT.np_dtype()), 2022-12-06T01:12:47,155 np.array([10011.1, 101.0, 688.25, 6.25], TSDataType.DOUBLE.np_dtype()), 2022-12-06T01:12:47,155 np.array(["test01", "test02", "test03", "test04"], TSDataType.TEXT.np_dtype()), 2022-12-06T01:12:47,155 ] 2022-12-06T01:12:47,156 np_timestamps_ = np.array([1, 2, 3, 4], TSDataType.INT64.np_dtype()) 2022-12-06T01:12:47,156 np_tablet_ = NumpyTablet( 2022-12-06T01:12:47,156 "root.sg_test_01.d_02", measurements_, data_types_, np_values_, np_timestamps_ 2022-12-06T01:12:47,157 ) 2022-12-06T01:12:47,157 session.insert_tablet(np_tablet_) 2022-12-06T01:12:47,157 ``` 2022-12-06T01:12:47,158 * Insert multiple Tablets 2022-12-06T01:12:47,158 ```python 2022-12-06T01:12:47,159 session.insert_tablets(tablet_lst) 2022-12-06T01:12:47,159 ``` 2022-12-06T01:12:47,160 * Insert a Record 2022-12-06T01:12:47,160 ```python 2022-12-06T01:12:47,160 session.insert_record(device_id, timestamp, measurements_, data_types_, values_) 2022-12-06T01:12:47,161 ``` 2022-12-06T01:12:47,161 * Insert multiple Records 2022-12-06T01:12:47,162 ```python 2022-12-06T01:12:47,162 session.insert_records( 2022-12-06T01:12:47,162 device_ids_, time_list_, measurements_list_, data_type_list_, values_list_ 2022-12-06T01:12:47,163 ) 2022-12-06T01:12:47,163 ``` 2022-12-06T01:12:47,164 * Insert multiple Records that belong to the same device. 2022-12-06T01:12:47,164 With type info the server has no need to do type inference, which leads a better performance 2022-12-06T01:12:47,165 ```python 2022-12-06T01:12:47,165 session.insert_records_of_one_device(device_id, time_list, measurements_list, data_types_list, values_list) 2022-12-06T01:12:47,165 ``` 2022-12-06T01:12:47,166 #### Insert with type inference 2022-12-06T01:12:47,167 When the data is of String type, we can use the following interface to perform type inference based on the value of the value itself. For example, if value is "true" , it can be automatically inferred to be a boolean type. If value is "3.2" , it can be automatically inferred as a flout type. Without type information, server has to do type inference, which may cost some time. 2022-12-06T01:12:47,167 * Insert a Record, which contains multiple measurement value of a device at a timestamp 2022-12-06T01:12:47,168 ```python 2022-12-06T01:12:47,168 session.insert_str_record(device_id, timestamp, measurements, string_values) 2022-12-06T01:12:47,168 ``` 2022-12-06T01:12:47,169 #### Insert of Aligned Timeseries 2022-12-06T01:12:47,170 The Insert of aligned timeseries uses interfaces like insert_aligned_XXX, and others are similar to the above interfaces: 2022-12-06T01:12:47,170 * insert_aligned_record 2022-12-06T01:12:47,170 * insert_aligned_records 2022-12-06T01:12:47,171 * insert_aligned_records_of_one_device 2022-12-06T01:12:47,171 * insert_aligned_tablet 2022-12-06T01:12:47,171 * insert_aligned_tablets 2022-12-06T01:12:47,172 ### IoTDB-SQL Interface 2022-12-06T01:12:47,173 * Execute query statement 2022-12-06T01:12:47,174 ```python 2022-12-06T01:12:47,174 session.execute_query_statement(sql) 2022-12-06T01:12:47,174 ``` 2022-12-06T01:12:47,175 * Execute non query statement 2022-12-06T01:12:47,175 ```python 2022-12-06T01:12:47,176 session.execute_non_query_statement(sql) 2022-12-06T01:12:47,176 ``` 2022-12-06T01:12:47,177 * Execute statement 2022-12-06T01:12:47,177 ```python 2022-12-06T01:12:47,177 session.execute_statement(sql) 2022-12-06T01:12:47,178 ``` 2022-12-06T01:12:47,178 ### Schema Template 2022-12-06T01:12:47,179 #### Create Schema Template 2022-12-06T01:12:47,179 The step for creating a metadata template is as follows 2022-12-06T01:12:47,179 1. Create the template class 2022-12-06T01:12:47,180 2. Adding child Node,InternalNode and MeasurementNode can be chose 2022-12-06T01:12:47,180 3. Execute create schema template function 2022-12-06T01:12:47,180 ```python 2022-12-06T01:12:47,181 template = Template(name=template_name, share_time=True) 2022-12-06T01:12:47,181 i_node_gps = InternalNode(name="GPS", share_time=False) 2022-12-06T01:12:47,182 i_node_v = InternalNode(name="vehicle", share_time=True) 2022-12-06T01:12:47,182 m_node_x = MeasurementNode("x", TSDataType.FLOAT, TSEncoding.RLE, Compressor.SNAPPY) 2022-12-06T01:12:47,183 i_node_gps.add_child(m_node_x) 2022-12-06T01:12:47,183 i_node_v.add_child(m_node_x) 2022-12-06T01:12:47,183 template.add_template(i_node_gps) 2022-12-06T01:12:47,184 template.add_template(i_node_v) 2022-12-06T01:12:47,184 template.add_template(m_node_x) 2022-12-06T01:12:47,185 session.create_schema_template(template) 2022-12-06T01:12:47,185 ``` 2022-12-06T01:12:47,185 #### Modify Schema Template nodes 2022-12-06T01:12:47,185 Modify nodes in a template, the template must be already created. These are functions that add or delete some measurement nodes. 2022-12-06T01:12:47,186 * add node in template 2022-12-06T01:12:47,186 ```python 2022-12-06T01:12:47,186 session.add_measurements_in_template(template_name, measurements_path, data_types, encodings, compressors, is_aligned) 2022-12-06T01:12:47,187 ``` 2022-12-06T01:12:47,187 * delete node in template 2022-12-06T01:12:47,188 ```python 2022-12-06T01:12:47,188 session.delete_node_in_template(template_name, path) 2022-12-06T01:12:47,188 ``` 2022-12-06T01:12:47,189 #### Set Schema Template 2022-12-06T01:12:47,189 ```python 2022-12-06T01:12:47,189 session.set_schema_template(template_name, prefix_path) 2022-12-06T01:12:47,190 ``` 2022-12-06T01:12:47,190 #### Uset Schema Template 2022-12-06T01:12:47,191 ```python 2022-12-06T01:12:47,191 session.unset_schema_template(template_name, prefix_path) 2022-12-06T01:12:47,191 ``` 2022-12-06T01:12:47,192 #### Show Schema Template 2022-12-06T01:12:47,192 * Show all schema templates 2022-12-06T01:12:47,192 ```python 2022-12-06T01:12:47,193 session.show_all_templates() 2022-12-06T01:12:47,193 ``` 2022-12-06T01:12:47,193 * Count all nodes in templates 2022-12-06T01:12:47,193 ```python 2022-12-06T01:12:47,194 session.count_measurements_in_template(template_name) 2022-12-06T01:12:47,194 ``` 2022-12-06T01:12:47,195 * Judge whether the path is measurement or not in templates, This measurement must be in the template 2022-12-06T01:12:47,195 ```python 2022-12-06T01:12:47,195 session.count_measurements_in_template(template_name, path) 2022-12-06T01:12:47,195 ``` 2022-12-06T01:12:47,196 * Judge whether the path is exist or not in templates, This path may not belong to the template 2022-12-06T01:12:47,196 ```python 2022-12-06T01:12:47,197 session.is_path_exist_in_template(template_name, path) 2022-12-06T01:12:47,197 ``` 2022-12-06T01:12:47,197 * Show nodes under in schema template 2022-12-06T01:12:47,198 ```python 2022-12-06T01:12:47,198 session.show_measurements_in_template(template_name) 2022-12-06T01:12:47,198 ``` 2022-12-06T01:12:47,199 * Show the path prefix where a schema template is set 2022-12-06T01:12:47,199 ```python 2022-12-06T01:12:47,199 session.show_paths_template_set_on(template_name) 2022-12-06T01:12:47,200 ``` 2022-12-06T01:12:47,200 * Show the path prefix where a schema template is used (i.e. the time series has been created) 2022-12-06T01:12:47,201 ```python 2022-12-06T01:12:47,201 session.show_paths_template_using_on(template_name) 2022-12-06T01:12:47,201 ``` 2022-12-06T01:12:47,202 #### Drop Schema Template 2022-12-06T01:12:47,202 Delete an existing metadata template,dropping an already set template is not supported 2022-12-06T01:12:47,202 ```python 2022-12-06T01:12:47,203 session.drop_schema_template("template_python") 2022-12-06T01:12:47,203 ``` 2022-12-06T01:12:47,204 ### Pandas Support 2022-12-06T01:12:47,205 To easily transform a query result to a [Pandas Dataframe](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html) 2022-12-06T01:12:47,205 the SessionDataSet has a method `.todf()` which consumes the dataset and transforms it to a pandas dataframe. 2022-12-06T01:12:47,205 Example: 2022-12-06T01:12:47,206 ```python 2022-12-06T01:12:47,206 from iotdb.Session import Session 2022-12-06T01:12:47,207 ip = "127.0.0.1" 2022-12-06T01:12:47,207 port_ = "6667" 2022-12-06T01:12:47,208 username_ = "root" 2022-12-06T01:12:47,208 password_ = "root" 2022-12-06T01:12:47,208 session = Session(ip, port_, username_, password_) 2022-12-06T01:12:47,209 session.open(False) 2022-12-06T01:12:47,209 result = session.execute_query_statement("SELECT * FROM root.*") 2022-12-06T01:12:47,209 # Transform to Pandas Dataset 2022-12-06T01:12:47,210 df = result.todf() 2022-12-06T01:12:47,210 session.close() 2022-12-06T01:12:47,211 # Now you can work with the dataframe 2022-12-06T01:12:47,211 df = ... 2022-12-06T01:12:47,211 ``` 2022-12-06T01:12:47,212 ### IoTDB Testcontainer 2022-12-06T01:12:47,213 The Test Support is based on the lib `testcontainers` (https://testcontainers-python.readthedocs.io/en/latest/index.html) which you need to install in your project if you want to use the feature. 2022-12-06T01:12:47,213 To start (and stop) an IoTDB Database in a Docker container simply do: 2022-12-06T01:12:47,214 ```python 2022-12-06T01:12:47,214 class MyTestCase(unittest.TestCase): 2022-12-06T01:12:47,215 def test_something(self): 2022-12-06T01:12:47,215 with IoTDBContainer() as c: 2022-12-06T01:12:47,215 session = Session("localhost", c.get_exposed_port(6667), "root", "root") 2022-12-06T01:12:47,215 session.open(False) 2022-12-06T01:12:47,216 result = session.execute_query_statement("SHOW TIMESERIES") 2022-12-06T01:12:47,216 print(result) 2022-12-06T01:12:47,216 session.close() 2022-12-06T01:12:47,217 ``` 2022-12-06T01:12:47,217 by default it will load the image `apache/iotdb:latest`, if you want a specific version just pass it like e.g. `IoTDBContainer("apache/iotdb:0.12.0")` to get version `0.12.0` running. 2022-12-06T01:12:47,218 ### IoTDB DBAPI 2022-12-06T01:12:47,219 IoTDB DBAPI implements the Python DB API 2.0 specification (https://peps.python.org/pep-0249/), which defines a common 2022-12-06T01:12:47,219 interface for accessing databases in Python. 2022-12-06T01:12:47,220 #### Examples 2022-12-06T01:12:47,220 + Initialization 2022-12-06T01:12:47,221 The initialized parameters are consistent with the session part (except for the sqlalchemy_mode). 2022-12-06T01:12:47,221 ```python 2022-12-06T01:12:47,221 from iotdb.dbapi import connect 2022-12-06T01:12:47,222 ip = "127.0.0.1" 2022-12-06T01:12:47,222 port_ = "6667" 2022-12-06T01:12:47,223 username_ = "root" 2022-12-06T01:12:47,223 password_ = "root" 2022-12-06T01:12:47,223 conn = connect(ip, port_, username_, password_,fetch_size=1024,zone_id="UTC+8",sqlalchemy_mode=False) 2022-12-06T01:12:47,223 cursor = conn.cursor() 2022-12-06T01:12:47,224 ``` 2022-12-06T01:12:47,224 + simple SQL statement execution 2022-12-06T01:12:47,224 ```python 2022-12-06T01:12:47,225 cursor.execute("SELECT * FROM root.*") 2022-12-06T01:12:47,225 for row in cursor.fetchall(): 2022-12-06T01:12:47,225 print(row) 2022-12-06T01:12:47,226 ``` 2022-12-06T01:12:47,226 + execute SQL with parameter 2022-12-06T01:12:47,227 IoTDB DBAPI supports pyformat style parameters 2022-12-06T01:12:47,227 ```python 2022-12-06T01:12:47,228 cursor.execute("SELECT * FROM root.* WHERE time < %(time)s",{"time":"2017-11-01T00:08:00.000"}) 2022-12-06T01:12:47,228 for row in cursor.fetchall(): 2022-12-06T01:12:47,228 print(row) 2022-12-06T01:12:47,229 ``` 2022-12-06T01:12:47,229 + execute SQL with parameter sequences 2022-12-06T01:12:47,229 ```python 2022-12-06T01:12:47,230 seq_of_parameters = [ 2022-12-06T01:12:47,230 {"timestamp": 1, "temperature": 1}, 2022-12-06T01:12:47,230 {"timestamp": 2, "temperature": 2}, 2022-12-06T01:12:47,231 {"timestamp": 3, "temperature": 3}, 2022-12-06T01:12:47,231 {"timestamp": 4, "temperature": 4}, 2022-12-06T01:12:47,231 {"timestamp": 5, "temperature": 5}, 2022-12-06T01:12:47,231 ] 2022-12-06T01:12:47,232 sql = "insert into root.cursor(timestamp,temperature) values(%(timestamp)s,%(temperature)s)" 2022-12-06T01:12:47,232 cursor.executemany(sql,seq_of_parameters) 2022-12-06T01:12:47,232 ``` 2022-12-06T01:12:47,233 + close the connection and cursor 2022-12-06T01:12:47,233 ```python 2022-12-06T01:12:47,233 cursor.close() 2022-12-06T01:12:47,234 conn.close() 2022-12-06T01:12:47,234 ``` 2022-12-06T01:12:47,235 ### IoTDB SQLAlchemy Dialect (Experimental) 2022-12-06T01:12:47,235 The SQLAlchemy dialect of IoTDB is written to adapt to Apache Superset. 2022-12-06T01:12:47,235 This part is still being improved. 2022-12-06T01:12:47,235 Please do not use it in the production environment! 2022-12-06T01:12:47,236 #### Mapping of the metadata 2022-12-06T01:12:47,236 The data model used by SQLAlchemy is a relational data model, which describes the relationships between different entities through tables. 2022-12-06T01:12:47,236 While the data model of IoTDB is a hierarchical data model, which organizes the data through a tree structure. 2022-12-06T01:12:47,237 In order to adapt IoTDB to the dialect of SQLAlchemy, the original data model in IoTDB needs to be reorganized. 2022-12-06T01:12:47,237 Converting the data model of IoTDB into the data model of SQLAlchemy. 2022-12-06T01:12:47,237 The metadata in the IoTDB are: 2022-12-06T01:12:47,238 1. Database 2022-12-06T01:12:47,238 2. Path 2022-12-06T01:12:47,239 3. Entity 2022-12-06T01:12:47,239 4. Measurement 2022-12-06T01:12:47,239 The metadata in the SQLAlchemy are: 2022-12-06T01:12:47,240 1. Schema 2022-12-06T01:12:47,240 2. Table 2022-12-06T01:12:47,240 3. Column 2022-12-06T01:12:47,241 The mapping relationship between them is: 2022-12-06T01:12:47,241 | The metadata in the SQLAlchemy | The metadata in the IoTDB | 2022-12-06T01:12:47,242 | -------------------- | ---------------------------------------------- | 2022-12-06T01:12:47,242 | Schema | Database | 2022-12-06T01:12:47,242 | Table | Path ( from database to entity ) + Entity | 2022-12-06T01:12:47,242 | Column | Measurement | 2022-12-06T01:12:47,243 The following figure shows the relationship between the two more intuitively: 2022-12-06T01:12:47,244 ![sqlalchemy-to-iotdb](https://github.com/apache/iotdb-bin-resources/blob/main/docs/UserGuide/API/IoTDB-SQLAlchemy/sqlalchemy-to-iotdb.png?raw=true) 2022-12-06T01:12:47,244 #### Data type mapping 2022-12-06T01:12:47,244 | data type in IoTDB | data type in SQLAlchemy | 2022-12-06T01:12:47,245 |--------------------|-------------------------| 2022-12-06T01:12:47,245 | BOOLEAN | Boolean | 2022-12-06T01:12:47,245 | INT32 | Integer | 2022-12-06T01:12:47,246 | INT64 | BigInteger | 2022-12-06T01:12:47,246 | FLOAT | Float | 2022-12-06T01:12:47,246 | DOUBLE | Float | 2022-12-06T01:12:47,247 | TEXT | Text | 2022-12-06T01:12:47,247 | LONG | BigInteger | 2022-12-06T01:12:47,247 #### Example 2022-12-06T01:12:47,248 + execute statement 2022-12-06T01:12:47,248 ```python 2022-12-06T01:12:47,249 from sqlalchemy import create_engine 2022-12-06T01:12:47,249 engine = create_engine("iotdb://root:root@127.0.0.1:6667") 2022-12-06T01:12:47,250 connect = engine.connect() 2022-12-06T01:12:47,250 result = connect.execute("SELECT ** FROM root") 2022-12-06T01:12:47,250 for row in result.fetchall(): 2022-12-06T01:12:47,250 print(row) 2022-12-06T01:12:47,251 ``` 2022-12-06T01:12:47,251 + ORM (now only simple queries are supported) 2022-12-06T01:12:47,252 ```python 2022-12-06T01:12:47,252 from sqlalchemy import create_engine, Column, Float, BigInteger, MetaData 2022-12-06T01:12:47,252 from sqlalchemy.ext.declarative import declarative_base 2022-12-06T01:12:47,253 from sqlalchemy.orm import sessionmaker 2022-12-06T01:12:47,253 metadata = MetaData( 2022-12-06T01:12:47,254 schema='root.factory' 2022-12-06T01:12:47,254 ) 2022-12-06T01:12:47,254 Base = declarative_base(metadata=metadata) 2022-12-06T01:12:47,255 class Device(Base): 2022-12-06T01:12:47,255 __tablename__ = "room2.device1" 2022-12-06T01:12:47,256 Time = Column(BigInteger, primary_key=True) 2022-12-06T01:12:47,256 temperature = Column(Float) 2022-12-06T01:12:47,256 status = Column(Float) 2022-12-06T01:12:47,257 engine = create_engine("iotdb://root:root@127.0.0.1:6667") 2022-12-06T01:12:47,258 DbSession = sessionmaker(bind=engine) 2022-12-06T01:12:47,258 session = DbSession() 2022-12-06T01:12:47,259 res = session.query(Device.status).filter(Device.temperature > 1) 2022-12-06T01:12:47,259 for row in res: 2022-12-06T01:12:47,260 print(row) 2022-12-06T01:12:47,260 ``` 2022-12-06T01:12:47,261 ## Developers 2022-12-06T01:12:47,261 ### Introduction 2022-12-06T01:12:47,262 This is an example of how to connect to IoTDB with python, using the thrift rpc interfaces. Things are almost the same on Windows or Linux, but pay attention to the difference like path separator. 2022-12-06T01:12:47,263 ### Prerequisites 2022-12-06T01:12:47,264 Python3.7 or later is preferred. 2022-12-06T01:12:47,264 You have to install Thrift (0.11.0 or later) to compile our thrift file into python code. Below is the official tutorial of installation, eventually, you should have a thrift executable. 2022-12-06T01:12:47,265 ``` 2022-12-06T01:12:47,265 http://thrift.apache.org/docs/install/ 2022-12-06T01:12:47,265 ``` 2022-12-06T01:12:47,266 Before starting you need to install `requirements_dev.txt` in your python environment, e.g. by calling 2022-12-06T01:12:47,266 ```shell 2022-12-06T01:12:47,267 pip install -r requirements_dev.txt 2022-12-06T01:12:47,267 ``` 2022-12-06T01:12:47,268 ### Compile the thrift library and Debug 2022-12-06T01:12:47,269 In the root of IoTDB's source code folder, run `mvn clean generate-sources -pl client-py -am`. 2022-12-06T01:12:47,269 This will automatically delete and repopulate the folder `iotdb/thrift` with the generated thrift files. 2022-12-06T01:12:47,269 This folder is ignored from git and should **never be pushed to git!** 2022-12-06T01:12:47,270 **Notice** Do not upload `iotdb/thrift` to the git repo. 2022-12-06T01:12:47,272 ### Session Client & Example 2022-12-06T01:12:47,272 We packed up the Thrift interface in `client-py/src/iotdb/Session.py` (similar with its Java counterpart), also provided an example file `client-py/src/SessionExample.py` of how to use the session module. please read it carefully. 2022-12-06T01:12:47,273 Or, another simple example: 2022-12-06T01:12:47,274 ```python 2022-12-06T01:12:47,274 from iotdb.Session import Session 2022-12-06T01:12:47,275 ip = "127.0.0.1" 2022-12-06T01:12:47,275 port_ = "6667" 2022-12-06T01:12:47,275 username_ = "root" 2022-12-06T01:12:47,275 password_ = "root" 2022-12-06T01:12:47,276 session = Session(ip, port_, username_, password_) 2022-12-06T01:12:47,276 session.open(False) 2022-12-06T01:12:47,276 zone = session.get_time_zone() 2022-12-06T01:12:47,277 session.close() 2022-12-06T01:12:47,277 ``` 2022-12-06T01:12:47,278 ### Tests 2022-12-06T01:12:47,279 Please add your custom tests in `tests` folder. 2022-12-06T01:12:47,279 To run all defined tests just type `pytest .` in the root folder. 2022-12-06T01:12:47,280 **Notice** Some tests need docker to be started on your system as a test instance is started in a docker container using [testcontainers](https://testcontainers-python.readthedocs.io/en/latest/index.html). 2022-12-06T01:12:47,281 ### Futher Tools 2022-12-06T01:12:47,282 [black](https://pypi.org/project/black/) and [flake8](https://pypi.org/project/flake8/) are installed for autoformatting and linting. 2022-12-06T01:12:47,282 Both can be run by `black .` or `flake8 .` respectively. 2022-12-06T01:12:47,283 ## Releasing 2022-12-06T01:12:47,284 To do a release just ensure that you have the right set of generated thrift files. 2022-12-06T01:12:47,284 Then run linting and auto-formatting. 2022-12-06T01:12:47,284 Then, ensure that all tests work (via `pytest .`). 2022-12-06T01:12:47,285 Then you are good to go to do a release! 2022-12-06T01:12:47,286 ### Preparing your environment 2022-12-06T01:12:47,286 First, install all necessary dev dependencies via `pip install -r requirements_dev.txt`. 2022-12-06T01:12:47,288 ### Doing the Release 2022-12-06T01:12:47,288 There is a convenient script `release.sh` to do all steps for a release. 2022-12-06T01:12:47,288 Namely, these are 2022-12-06T01:12:47,289 * Remove all transient directories from last release (if exists) 2022-12-06T01:12:47,289 * (Re-)generate all generated sources via mvn 2022-12-06T01:12:47,290 * Run Linting (flake8) 2022-12-06T01:12:47,290 * Run Tests via pytest 2022-12-06T01:12:47,290 * Build 2022-12-06T01:12:47,291 * Release to pypi 2022-12-06T01:12:47,359 running bdist_wheel 2022-12-06T01:12:47,435 running build 2022-12-06T01:12:47,435 running build_py 2022-12-06T01:12:47,457 creating build 2022-12-06T01:12:47,458 creating build/lib 2022-12-06T01:12:47,459 creating build/lib/tests 2022-12-06T01:12:47,461 copying tests/test_one_device.py -> build/lib/tests 2022-12-06T01:12:47,465 copying tests/test_aligned_timeseries.py -> build/lib/tests 2022-12-06T01:12:47,470 copying tests/test_tablet.py -> build/lib/tests 2022-12-06T01:12:47,474 copying tests/test_numpy_tablet.py -> build/lib/tests 2022-12-06T01:12:47,478 copying tests/test_session.py -> build/lib/tests 2022-12-06T01:12:47,482 copying tests/test_dataframe.py -> build/lib/tests 2022-12-06T01:12:47,486 copying tests/test_todf.py -> build/lib/tests 2022-12-06T01:12:47,490 copying tests/test_template.py -> build/lib/tests 2022-12-06T01:12:47,493 copying tests/__init__.py -> build/lib/tests 2022-12-06T01:12:47,496 copying tests/tablet_performance_comparison.py -> build/lib/tests 2022-12-06T01:12:47,501 creating build/lib/iotdb 2022-12-06T01:12:47,503 copying iotdb/IoTDBContainer.py -> build/lib/iotdb 2022-12-06T01:12:47,507 copying iotdb/Session.py -> build/lib/iotdb 2022-12-06T01:12:47,514 copying iotdb/__init__.py -> build/lib/iotdb 2022-12-06T01:12:47,518 creating build/lib/iotdb/thrift 2022-12-06T01:12:47,520 copying iotdb/thrift/__init__.py -> build/lib/iotdb/thrift 2022-12-06T01:12:47,524 creating build/lib/iotdb/template 2022-12-06T01:12:47,526 copying iotdb/template/InternalNode.py -> build/lib/iotdb/template 2022-12-06T01:12:47,529 copying iotdb/template/TemplateNode.py -> build/lib/iotdb/template 2022-12-06T01:12:47,532 copying iotdb/template/Template.py -> build/lib/iotdb/template 2022-12-06T01:12:47,536 copying iotdb/template/MeasurementNode.py -> build/lib/iotdb/template 2022-12-06T01:12:47,539 copying iotdb/template/TemplateQueryType.py -> build/lib/iotdb/template 2022-12-06T01:12:47,542 copying iotdb/template/__init__.py -> build/lib/iotdb/template 2022-12-06T01:12:47,547 creating build/lib/iotdb/sqlalchemy 2022-12-06T01:12:47,549 copying iotdb/sqlalchemy/IoTDBIdentifierPreparer.py -> build/lib/iotdb/sqlalchemy 2022-12-06T01:12:47,552 copying iotdb/sqlalchemy/IoTDBSQLCompiler.py -> build/lib/iotdb/sqlalchemy 2022-12-06T01:12:47,556 copying iotdb/sqlalchemy/IoTDBDialect.py -> build/lib/iotdb/sqlalchemy 2022-12-06T01:12:47,560 copying iotdb/sqlalchemy/IoTDBTypeCompiler.py -> build/lib/iotdb/sqlalchemy 2022-12-06T01:12:47,564 copying iotdb/sqlalchemy/__init__.py -> build/lib/iotdb/sqlalchemy 2022-12-06T01:12:47,568 creating build/lib/iotdb/dbapi 2022-12-06T01:12:47,570 copying iotdb/dbapi/Cursor.py -> build/lib/iotdb/dbapi 2022-12-06T01:12:47,575 copying iotdb/dbapi/Connection.py -> build/lib/iotdb/dbapi 2022-12-06T01:12:47,578 copying iotdb/dbapi/Exceptions.py -> build/lib/iotdb/dbapi 2022-12-06T01:12:47,582 copying iotdb/dbapi/__init__.py -> build/lib/iotdb/dbapi 2022-12-06T01:12:47,588 creating build/lib/iotdb/utils 2022-12-06T01:12:47,589 copying iotdb/utils/Tablet.py -> build/lib/iotdb/utils 2022-12-06T01:12:47,594 copying iotdb/utils/NumpyTablet.py -> build/lib/iotdb/utils 2022-12-06T01:12:47,598 copying iotdb/utils/RowRecord.py -> build/lib/iotdb/utils 2022-12-06T01:12:47,601 copying iotdb/utils/BitMap.py -> build/lib/iotdb/utils 2022-12-06T01:12:47,605 copying iotdb/utils/SessionDataSet.py -> build/lib/iotdb/utils 2022-12-06T01:12:47,609 copying iotdb/utils/IoTDBConstants.py -> build/lib/iotdb/utils 2022-12-06T01:12:47,612 copying iotdb/utils/Field.py -> build/lib/iotdb/utils 2022-12-06T01:12:47,616 copying iotdb/utils/IoTDBRpcDataSet.py -> build/lib/iotdb/utils 2022-12-06T01:12:47,621 copying iotdb/utils/__init__.py -> build/lib/iotdb/utils 2022-12-06T01:12:47,625 creating build/lib/iotdb/tsfile 2022-12-06T01:12:47,627 copying iotdb/tsfile/__init__.py -> build/lib/iotdb/tsfile 2022-12-06T01:12:47,632 creating build/lib/iotdb/thrift/rpc 2022-12-06T01:12:47,633 copying iotdb/thrift/rpc/constants.py -> build/lib/iotdb/thrift/rpc 2022-12-06T01:12:47,637 copying iotdb/thrift/rpc/ttypes.py -> build/lib/iotdb/thrift/rpc 2022-12-06T01:12:47,653 copying iotdb/thrift/rpc/IClientRPCService.py -> build/lib/iotdb/thrift/rpc 2022-12-06T01:12:47,673 copying iotdb/thrift/rpc/__init__.py -> build/lib/iotdb/thrift/rpc 2022-12-06T01:12:47,679 creating build/lib/iotdb/thrift/common 2022-12-06T01:12:47,681 copying iotdb/thrift/common/constants.py -> build/lib/iotdb/thrift/common 2022-12-06T01:12:47,685 copying iotdb/thrift/common/ttypes.py -> build/lib/iotdb/thrift/common 2022-12-06T01:12:47,691 copying iotdb/thrift/common/__init__.py -> build/lib/iotdb/thrift/common 2022-12-06T01:12:47,696 creating build/lib/iotdb/sqlalchemy/tests 2022-12-06T01:12:47,698 copying iotdb/sqlalchemy/tests/test_dialect.py -> build/lib/iotdb/sqlalchemy/tests 2022-12-06T01:12:47,701 copying iotdb/sqlalchemy/tests/__init__.py -> build/lib/iotdb/sqlalchemy/tests 2022-12-06T01:12:47,706 creating build/lib/iotdb/dbapi/tests 2022-12-06T01:12:47,708 copying iotdb/dbapi/tests/test_connection.py -> build/lib/iotdb/dbapi/tests 2022-12-06T01:12:47,712 copying iotdb/dbapi/tests/__init__.py -> build/lib/iotdb/dbapi/tests 2022-12-06T01:12:47,715 copying iotdb/dbapi/tests/test_cursor.py -> build/lib/iotdb/dbapi/tests 2022-12-06T01:12:47,721 creating build/lib/iotdb/tsfile/common 2022-12-06T01:12:47,722 copying iotdb/tsfile/common/__init__.py -> build/lib/iotdb/tsfile/common 2022-12-06T01:12:47,728 creating build/lib/iotdb/tsfile/utils 2022-12-06T01:12:47,729 copying iotdb/tsfile/utils/Pair.py -> build/lib/iotdb/tsfile/utils 2022-12-06T01:12:47,733 copying iotdb/tsfile/utils/ReadWriteIOUtils.py -> build/lib/iotdb/tsfile/utils 2022-12-06T01:12:47,737 copying iotdb/tsfile/utils/__init__.py -> build/lib/iotdb/tsfile/utils 2022-12-06T01:12:47,742 creating build/lib/iotdb/tsfile/common/constant 2022-12-06T01:12:47,744 copying iotdb/tsfile/common/constant/TsFileConstant.py -> build/lib/iotdb/tsfile/common/constant 2022-12-06T01:12:47,747 copying iotdb/tsfile/common/constant/__init__.py -> build/lib/iotdb/tsfile/common/constant 2022-12-06T01:12:47,806 installing to build/bdist.linux-armv7l/wheel 2022-12-06T01:12:47,807 running install 2022-12-06T01:12:47,871 running install_lib 2022-12-06T01:12:47,887 creating build/bdist.linux-armv7l 2022-12-06T01:12:47,887 creating build/bdist.linux-armv7l/wheel 2022-12-06T01:12:47,891 creating build/bdist.linux-armv7l/wheel/tests 2022-12-06T01:12:47,893 copying build/lib/tests/test_one_device.py -> build/bdist.linux-armv7l/wheel/tests 2022-12-06T01:12:47,898 copying build/lib/tests/test_aligned_timeseries.py -> build/bdist.linux-armv7l/wheel/tests 2022-12-06T01:12:47,903 copying build/lib/tests/test_tablet.py -> build/bdist.linux-armv7l/wheel/tests 2022-12-06T01:12:47,907 copying build/lib/tests/test_numpy_tablet.py -> build/bdist.linux-armv7l/wheel/tests 2022-12-06T01:12:47,911 copying build/lib/tests/test_session.py -> build/bdist.linux-armv7l/wheel/tests 2022-12-06T01:12:47,916 copying build/lib/tests/test_dataframe.py -> build/bdist.linux-armv7l/wheel/tests 2022-12-06T01:12:47,920 copying build/lib/tests/test_todf.py -> build/bdist.linux-armv7l/wheel/tests 2022-12-06T01:12:47,924 copying build/lib/tests/test_template.py -> build/bdist.linux-armv7l/wheel/tests 2022-12-06T01:12:47,928 copying build/lib/tests/__init__.py -> build/bdist.linux-armv7l/wheel/tests 2022-12-06T01:12:47,932 copying build/lib/tests/tablet_performance_comparison.py -> build/bdist.linux-armv7l/wheel/tests 2022-12-06T01:12:47,937 creating build/bdist.linux-armv7l/wheel/iotdb 2022-12-06T01:12:47,940 creating build/bdist.linux-armv7l/wheel/iotdb/thrift 2022-12-06T01:12:47,943 creating build/bdist.linux-armv7l/wheel/iotdb/thrift/rpc 2022-12-06T01:12:47,945 copying build/lib/iotdb/thrift/rpc/constants.py -> build/bdist.linux-armv7l/wheel/iotdb/thrift/rpc 2022-12-06T01:12:47,949 copying build/lib/iotdb/thrift/rpc/ttypes.py -> build/bdist.linux-armv7l/wheel/iotdb/thrift/rpc 2022-12-06T01:12:47,968 copying build/lib/iotdb/thrift/rpc/IClientRPCService.py -> build/bdist.linux-armv7l/wheel/iotdb/thrift/rpc 2022-12-06T01:12:47,988 copying build/lib/iotdb/thrift/rpc/__init__.py -> build/bdist.linux-armv7l/wheel/iotdb/thrift/rpc 2022-12-06T01:12:47,993 creating build/bdist.linux-armv7l/wheel/iotdb/thrift/common 2022-12-06T01:12:47,995 copying build/lib/iotdb/thrift/common/constants.py -> build/bdist.linux-armv7l/wheel/iotdb/thrift/common 2022-12-06T01:12:48,000 copying build/lib/iotdb/thrift/common/ttypes.py -> build/bdist.linux-armv7l/wheel/iotdb/thrift/common 2022-12-06T01:12:48,007 copying build/lib/iotdb/thrift/common/__init__.py -> build/bdist.linux-armv7l/wheel/iotdb/thrift/common 2022-12-06T01:12:48,011 copying build/lib/iotdb/thrift/__init__.py -> build/bdist.linux-armv7l/wheel/iotdb/thrift 2022-12-06T01:12:48,016 creating build/bdist.linux-armv7l/wheel/iotdb/template 2022-12-06T01:12:48,019 copying build/lib/iotdb/template/InternalNode.py -> build/bdist.linux-armv7l/wheel/iotdb/template 2022-12-06T01:12:48,023 copying build/lib/iotdb/template/TemplateNode.py -> build/bdist.linux-armv7l/wheel/iotdb/template 2022-12-06T01:12:48,027 copying build/lib/iotdb/template/Template.py -> build/bdist.linux-armv7l/wheel/iotdb/template 2022-12-06T01:12:48,032 copying build/lib/iotdb/template/MeasurementNode.py -> build/bdist.linux-armv7l/wheel/iotdb/template 2022-12-06T01:12:48,036 copying build/lib/iotdb/template/TemplateQueryType.py -> build/bdist.linux-armv7l/wheel/iotdb/template 2022-12-06T01:12:48,040 copying build/lib/iotdb/template/__init__.py -> build/bdist.linux-armv7l/wheel/iotdb/template 2022-12-06T01:12:48,045 copying build/lib/iotdb/IoTDBContainer.py -> build/bdist.linux-armv7l/wheel/iotdb 2022-12-06T01:12:48,050 creating build/bdist.linux-armv7l/wheel/iotdb/sqlalchemy 2022-12-06T01:12:48,052 copying build/lib/iotdb/sqlalchemy/IoTDBIdentifierPreparer.py -> build/bdist.linux-armv7l/wheel/iotdb/sqlalchemy 2022-12-06T01:12:48,057 copying build/lib/iotdb/sqlalchemy/IoTDBSQLCompiler.py -> build/bdist.linux-armv7l/wheel/iotdb/sqlalchemy 2022-12-06T01:12:48,063 creating build/bdist.linux-armv7l/wheel/iotdb/sqlalchemy/tests 2022-12-06T01:12:48,065 copying build/lib/iotdb/sqlalchemy/tests/test_dialect.py -> build/bdist.linux-armv7l/wheel/iotdb/sqlalchemy/tests 2022-12-06T01:12:48,070 copying build/lib/iotdb/sqlalchemy/tests/__init__.py -> build/bdist.linux-armv7l/wheel/iotdb/sqlalchemy/tests 2022-12-06T01:12:48,074 copying build/lib/iotdb/sqlalchemy/IoTDBDialect.py -> build/bdist.linux-armv7l/wheel/iotdb/sqlalchemy 2022-12-06T01:12:48,079 copying build/lib/iotdb/sqlalchemy/IoTDBTypeCompiler.py -> build/bdist.linux-armv7l/wheel/iotdb/sqlalchemy 2022-12-06T01:12:48,083 copying build/lib/iotdb/sqlalchemy/__init__.py -> build/bdist.linux-armv7l/wheel/iotdb/sqlalchemy 2022-12-06T01:12:48,088 copying build/lib/iotdb/Session.py -> build/bdist.linux-armv7l/wheel/iotdb 2022-12-06T01:12:48,096 creating build/bdist.linux-armv7l/wheel/iotdb/dbapi 2022-12-06T01:12:48,100 creating build/bdist.linux-armv7l/wheel/iotdb/dbapi/tests 2022-12-06T01:12:48,104 copying build/lib/iotdb/dbapi/tests/test_connection.py -> build/bdist.linux-armv7l/wheel/iotdb/dbapi/tests 2022-12-06T01:12:48,108 copying build/lib/iotdb/dbapi/tests/__init__.py -> build/bdist.linux-armv7l/wheel/iotdb/dbapi/tests 2022-12-06T01:12:48,113 copying build/lib/iotdb/dbapi/tests/test_cursor.py -> build/bdist.linux-armv7l/wheel/iotdb/dbapi/tests 2022-12-06T01:12:48,117 copying build/lib/iotdb/dbapi/Cursor.py -> build/bdist.linux-armv7l/wheel/iotdb/dbapi 2022-12-06T01:12:48,123 copying build/lib/iotdb/dbapi/Connection.py -> build/bdist.linux-armv7l/wheel/iotdb/dbapi 2022-12-06T01:12:48,127 copying build/lib/iotdb/dbapi/Exceptions.py -> build/bdist.linux-armv7l/wheel/iotdb/dbapi 2022-12-06T01:12:48,131 copying build/lib/iotdb/dbapi/__init__.py -> build/bdist.linux-armv7l/wheel/iotdb/dbapi 2022-12-06T01:12:48,136 copying build/lib/iotdb/__init__.py -> build/bdist.linux-armv7l/wheel/iotdb 2022-12-06T01:12:48,141 creating build/bdist.linux-armv7l/wheel/iotdb/utils 2022-12-06T01:12:48,143 copying build/lib/iotdb/utils/Tablet.py -> build/bdist.linux-armv7l/wheel/iotdb/utils 2022-12-06T01:12:48,148 copying build/lib/iotdb/utils/NumpyTablet.py -> build/bdist.linux-armv7l/wheel/iotdb/utils 2022-12-06T01:12:48,152 copying build/lib/iotdb/utils/RowRecord.py -> build/bdist.linux-armv7l/wheel/iotdb/utils 2022-12-06T01:12:48,156 copying build/lib/iotdb/utils/BitMap.py -> build/bdist.linux-armv7l/wheel/iotdb/utils 2022-12-06T01:12:48,159 copying build/lib/iotdb/utils/SessionDataSet.py -> build/bdist.linux-armv7l/wheel/iotdb/utils 2022-12-06T01:12:48,163 copying build/lib/iotdb/utils/IoTDBConstants.py -> build/bdist.linux-armv7l/wheel/iotdb/utils 2022-12-06T01:12:48,167 copying build/lib/iotdb/utils/Field.py -> build/bdist.linux-armv7l/wheel/iotdb/utils 2022-12-06T01:12:48,172 copying build/lib/iotdb/utils/IoTDBRpcDataSet.py -> build/bdist.linux-armv7l/wheel/iotdb/utils 2022-12-06T01:12:48,177 copying build/lib/iotdb/utils/__init__.py -> build/bdist.linux-armv7l/wheel/iotdb/utils 2022-12-06T01:12:48,181 creating build/bdist.linux-armv7l/wheel/iotdb/tsfile 2022-12-06T01:12:48,184 creating build/bdist.linux-armv7l/wheel/iotdb/tsfile/common 2022-12-06T01:12:48,187 creating build/bdist.linux-armv7l/wheel/iotdb/tsfile/common/constant 2022-12-06T01:12:48,189 copying build/lib/iotdb/tsfile/common/constant/TsFileConstant.py -> build/bdist.linux-armv7l/wheel/iotdb/tsfile/common/constant 2022-12-06T01:12:48,193 copying build/lib/iotdb/tsfile/common/constant/__init__.py -> build/bdist.linux-armv7l/wheel/iotdb/tsfile/common/constant 2022-12-06T01:12:48,197 copying build/lib/iotdb/tsfile/common/__init__.py -> build/bdist.linux-armv7l/wheel/iotdb/tsfile/common 2022-12-06T01:12:48,201 copying build/lib/iotdb/tsfile/__init__.py -> build/bdist.linux-armv7l/wheel/iotdb/tsfile 2022-12-06T01:12:48,205 creating build/bdist.linux-armv7l/wheel/iotdb/tsfile/utils 2022-12-06T01:12:48,207 copying build/lib/iotdb/tsfile/utils/Pair.py -> build/bdist.linux-armv7l/wheel/iotdb/tsfile/utils 2022-12-06T01:12:48,211 copying build/lib/iotdb/tsfile/utils/ReadWriteIOUtils.py -> build/bdist.linux-armv7l/wheel/iotdb/tsfile/utils 2022-12-06T01:12:48,215 copying build/lib/iotdb/tsfile/utils/__init__.py -> build/bdist.linux-armv7l/wheel/iotdb/tsfile/utils 2022-12-06T01:12:48,219 running install_egg_info 2022-12-06T01:12:48,279 running egg_info 2022-12-06T01:12:48,289 writing apache_iotdb.egg-info/PKG-INFO 2022-12-06T01:12:48,295 writing dependency_links to apache_iotdb.egg-info/dependency_links.txt 2022-12-06T01:12:48,299 writing entry points to apache_iotdb.egg-info/entry_points.txt 2022-12-06T01:12:48,302 writing requirements to apache_iotdb.egg-info/requires.txt 2022-12-06T01:12:48,305 writing top-level names to apache_iotdb.egg-info/top_level.txt 2022-12-06T01:12:48,342 reading manifest file 'apache_iotdb.egg-info/SOURCES.txt' 2022-12-06T01:12:48,350 adding license file 'LICENSE' 2022-12-06T01:12:48,362 writing manifest file 'apache_iotdb.egg-info/SOURCES.txt' 2022-12-06T01:12:48,366 Copying apache_iotdb.egg-info to build/bdist.linux-armv7l/wheel/apache_iotdb-1.0.0-py3.7.egg-info 2022-12-06T01:12:48,393 running install_scripts 2022-12-06T01:12:48,568 creating build/bdist.linux-armv7l/wheel/apache_iotdb-1.0.0.dist-info/WHEEL 2022-12-06T01:12:48,574 creating '/tmp/pip-wheel-6pi8p1na/.tmp-2i2n5lp0/apache_iotdb-1.0.0-py3-none-any.whl' and adding 'build/bdist.linux-armv7l/wheel' to it 2022-12-06T01:12:48,583 adding 'iotdb/IoTDBContainer.py' 2022-12-06T01:12:48,596 adding 'iotdb/Session.py' 2022-12-06T01:12:48,600 adding 'iotdb/__init__.py' 2022-12-06T01:12:48,605 adding 'iotdb/dbapi/Connection.py' 2022-12-06T01:12:48,609 adding 'iotdb/dbapi/Cursor.py' 2022-12-06T01:12:48,613 adding 'iotdb/dbapi/Exceptions.py' 2022-12-06T01:12:48,616 adding 'iotdb/dbapi/__init__.py' 2022-12-06T01:12:48,620 adding 'iotdb/dbapi/tests/__init__.py' 2022-12-06T01:12:48,624 adding 'iotdb/dbapi/tests/test_connection.py' 2022-12-06T01:12:48,627 adding 'iotdb/dbapi/tests/test_cursor.py' 2022-12-06T01:12:48,633 adding 'iotdb/sqlalchemy/IoTDBDialect.py' 2022-12-06T01:12:48,636 adding 'iotdb/sqlalchemy/IoTDBIdentifierPreparer.py' 2022-12-06T01:12:48,642 adding 'iotdb/sqlalchemy/IoTDBSQLCompiler.py' 2022-12-06T01:12:48,645 adding 'iotdb/sqlalchemy/IoTDBTypeCompiler.py' 2022-12-06T01:12:48,648 adding 'iotdb/sqlalchemy/__init__.py' 2022-12-06T01:12:48,653 adding 'iotdb/sqlalchemy/tests/__init__.py' 2022-12-06T01:12:48,656 adding 'iotdb/sqlalchemy/tests/test_dialect.py' 2022-12-06T01:12:48,661 adding 'iotdb/template/InternalNode.py' 2022-12-06T01:12:48,665 adding 'iotdb/template/MeasurementNode.py' 2022-12-06T01:12:48,669 adding 'iotdb/template/Template.py' 2022-12-06T01:12:48,672 adding 'iotdb/template/TemplateNode.py' 2022-12-06T01:12:48,675 adding 'iotdb/template/TemplateQueryType.py' 2022-12-06T01:12:48,679 adding 'iotdb/template/__init__.py' 2022-12-06T01:12:48,683 adding 'iotdb/thrift/__init__.py' 2022-12-06T01:12:48,687 adding 'iotdb/thrift/common/__init__.py' 2022-12-06T01:12:48,690 adding 'iotdb/thrift/common/constants.py' 2022-12-06T01:12:48,698 adding 'iotdb/thrift/common/ttypes.py' 2022-12-06T01:12:48,731 adding 'iotdb/thrift/rpc/IClientRPCService.py' 2022-12-06T01:12:48,741 adding 'iotdb/thrift/rpc/__init__.py' 2022-12-06T01:12:48,745 adding 'iotdb/thrift/rpc/constants.py' 2022-12-06T01:12:48,774 adding 'iotdb/thrift/rpc/ttypes.py' 2022-12-06T01:12:48,784 adding 'iotdb/tsfile/__init__.py' 2022-12-06T01:12:48,788 adding 'iotdb/tsfile/common/__init__.py' 2022-12-06T01:12:48,792 adding 'iotdb/tsfile/common/constant/TsFileConstant.py' 2022-12-06T01:12:48,796 adding 'iotdb/tsfile/common/constant/__init__.py' 2022-12-06T01:12:48,800 adding 'iotdb/tsfile/utils/Pair.py' 2022-12-06T01:12:48,803 adding 'iotdb/tsfile/utils/ReadWriteIOUtils.py' 2022-12-06T01:12:48,805 adding 'iotdb/tsfile/utils/__init__.py' 2022-12-06T01:12:48,809 adding 'iotdb/utils/BitMap.py' 2022-12-06T01:12:48,813 adding 'iotdb/utils/Field.py' 2022-12-06T01:12:48,815 adding 'iotdb/utils/IoTDBConstants.py' 2022-12-06T01:12:48,820 adding 'iotdb/utils/IoTDBRpcDataSet.py' 2022-12-06T01:12:48,824 adding 'iotdb/utils/NumpyTablet.py' 2022-12-06T01:12:48,827 adding 'iotdb/utils/RowRecord.py' 2022-12-06T01:12:48,830 adding 'iotdb/utils/SessionDataSet.py' 2022-12-06T01:12:48,833 adding 'iotdb/utils/Tablet.py' 2022-12-06T01:12:48,836 adding 'iotdb/utils/__init__.py' 2022-12-06T01:12:48,840 adding 'tests/__init__.py' 2022-12-06T01:12:48,844 adding 'tests/tablet_performance_comparison.py' 2022-12-06T01:12:48,848 adding 'tests/test_aligned_timeseries.py' 2022-12-06T01:12:48,851 adding 'tests/test_dataframe.py' 2022-12-06T01:12:48,854 adding 'tests/test_numpy_tablet.py' 2022-12-06T01:12:48,858 adding 'tests/test_one_device.py' 2022-12-06T01:12:48,862 adding 'tests/test_session.py' 2022-12-06T01:12:48,865 adding 'tests/test_tablet.py' 2022-12-06T01:12:48,868 adding 'tests/test_template.py' 2022-12-06T01:12:48,871 adding 'tests/test_todf.py' 2022-12-06T01:12:48,877 adding 'apache_iotdb-1.0.0.dist-info/LICENSE' 2022-12-06T01:12:48,883 adding 'apache_iotdb-1.0.0.dist-info/METADATA' 2022-12-06T01:12:48,885 adding 'apache_iotdb-1.0.0.dist-info/WHEEL' 2022-12-06T01:12:48,887 adding 'apache_iotdb-1.0.0.dist-info/entry_points.txt' 2022-12-06T01:12:48,889 adding 'apache_iotdb-1.0.0.dist-info/top_level.txt' 2022-12-06T01:12:48,892 adding 'apache_iotdb-1.0.0.dist-info/RECORD' 2022-12-06T01:12:48,900 removing build/bdist.linux-armv7l/wheel 2022-12-06T01:12:48,956 /tmp/pip-build-env-8invdbgq/overlay/lib/python3.7/site-packages/setuptools/_distutils/dist.py:265: UserWarning: Unknown distribution option: 'website' 2022-12-06T01:12:48,957 warnings.warn(msg) 2022-12-06T01:12:49,181 Building wheel for apache-iotdb (pyproject.toml): finished with status 'done' 2022-12-06T01:12:49,200 Created wheel for apache-iotdb: filename=apache_iotdb-1.0.0-py3-none-any.whl size=117578 sha256=85d0bb3ddb1c79359fec18e85c6d515dc3639752d77dea32c09c8afe0fefc906 2022-12-06T01:12:49,202 Stored in directory: /tmp/pip-ephem-wheel-cache-k2cko101/wheels/b2/08/3c/c5f24e62f3029a323b1aa42691cc276d03671bd924fef744e9 2022-12-06T01:12:49,240 Successfully built apache-iotdb 2022-12-06T01:12:49,255 Removed build tracker: '/tmp/pip-build-tracker-epsjtati'