2023-09-29T21:21:39,483 Created temporary directory: /tmp/pip-build-tracker-3je7a8fk 2023-09-29T21:21:39,484 Initialized build tracking at /tmp/pip-build-tracker-3je7a8fk 2023-09-29T21:21:39,484 Created build tracker: /tmp/pip-build-tracker-3je7a8fk 2023-09-29T21:21:39,485 Entered build tracker: /tmp/pip-build-tracker-3je7a8fk 2023-09-29T21:21:39,486 Created temporary directory: /tmp/pip-wheel-m8bh8obi 2023-09-29T21:21:39,489 Created temporary directory: /tmp/pip-ephem-wheel-cache-zmt4q7vq 2023-09-29T21:21:39,510 Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple 2023-09-29T21:21:39,514 2 location(s) to search for versions of apache-iotdb: 2023-09-29T21:21:39,514 * https://pypi.org/simple/apache-iotdb/ 2023-09-29T21:21:39,514 * https://www.piwheels.org/simple/apache-iotdb/ 2023-09-29T21:21:39,515 Fetching project page and analyzing links: https://pypi.org/simple/apache-iotdb/ 2023-09-29T21:21:39,516 Getting page https://pypi.org/simple/apache-iotdb/ 2023-09-29T21:21:39,517 Found index url https://pypi.org/simple/ 2023-09-29T21:21:39,780 Fetched page https://pypi.org/simple/apache-iotdb/ as application/vnd.pypi.simple.v1+json 2023-09-29T21:21:39,792 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 2023-09-29T21:21:39,793 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) 2023-09-29T21:21:39,793 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 2023-09-29T21:21:39,794 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) 2023-09-29T21:21:39,795 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 2023-09-29T21:21:39,796 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) 2023-09-29T21:21:39,797 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 2023-09-29T21:21:39,798 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) 2023-09-29T21:21:39,799 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 2023-09-29T21:21:39,799 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) 2023-09-29T21:21:39,800 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 2023-09-29T21:21:39,801 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) 2023-09-29T21:21:39,802 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 2023-09-29T21:21:39,803 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) 2023-09-29T21:21:39,804 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 2023-09-29T21:21:39,804 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) 2023-09-29T21:21:39,805 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 2023-09-29T21:21:39,806 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) 2023-09-29T21:21:39,807 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 2023-09-29T21:21:39,807 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) 2023-09-29T21:21:39,808 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 2023-09-29T21:21:39,809 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) 2023-09-29T21:21:39,810 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 2023-09-29T21:21:39,811 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) 2023-09-29T21:21:39,812 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 2023-09-29T21:21:39,812 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) 2023-09-29T21:21:39,813 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 2023-09-29T21:21:39,814 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) 2023-09-29T21:21:39,815 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 2023-09-29T21:21:39,816 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) 2023-09-29T21:21:39,816 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 2023-09-29T21:21:39,817 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) 2023-09-29T21:21:39,818 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 2023-09-29T21:21:39,818 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) 2023-09-29T21:21:39,819 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 2023-09-29T21:21:39,820 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) 2023-09-29T21:21:39,821 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 2023-09-29T21:21:39,822 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) 2023-09-29T21:21:39,822 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 2023-09-29T21:21:39,823 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) 2023-09-29T21:21:39,824 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 2023-09-29T21:21:39,825 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) 2023-09-29T21:21:39,826 Found link https://files.pythonhosted.org/packages/30/a0/0153c56e1af8653bfdcf47423949dd6b23e53882c9009acc25e661a44dbe/apache-iotdb-0.13.3.tar.gz (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7), version: 0.13.3 2023-09-29T21:21:39,826 Skipping link: No binaries permitted for apache-iotdb: https://files.pythonhosted.org/packages/a0/51/7e8405405f7f0ef8eabab31b4860cb747a8acfa53e30f56939c115b53db9/apache_iotdb-0.13.3-py3-none-any.whl (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7) 2023-09-29T21:21:39,827 Found link https://files.pythonhosted.org/packages/42/eb/3d7ac8d794238b75997ff3f55db6e02436bfa558a8df4ea21e58bf8db6fd/apache-iotdb-0.13.5.tar.gz (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7), version: 0.13.5 2023-09-29T21:21:39,828 Skipping link: No binaries permitted for apache-iotdb: https://files.pythonhosted.org/packages/51/a3/9117edfd3d72a1d338b7cff8060e672dd7b39dfeb2ca0d6c22db51bf9b90/apache_iotdb-0.13.5-py3-none-any.whl (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7) 2023-09-29T21:21:39,828 Found link https://files.pythonhosted.org/packages/95/c9/5d7a22003e57fe3c1637928926a73d11815830ee63c62f2cefeaa8eed28f/apache-iotdb-0.13.5.1.tar.gz (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7), version: 0.13.5.1 2023-09-29T21:21:39,829 Skipping link: No binaries permitted for apache-iotdb: https://files.pythonhosted.org/packages/89/0a/816b8a85f6be9f8fe3534f79ea12341dad900b59ba0ac126835640a09db0/apache_iotdb-0.13.5.1-py3-none-any.whl (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7) 2023-09-29T21:21:39,830 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 2023-09-29T21:21:39,831 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) 2023-09-29T21:21:39,831 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 2023-09-29T21:21:39,832 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) 2023-09-29T21:21:39,833 Found link https://files.pythonhosted.org/packages/0b/d7/475e11d05f2d4bc65f9b7d14691158489fbb7726a26cee5a016e94e6640a/apache-iotdb-1.0.1.tar.gz (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7), version: 1.0.1 2023-09-29T21:21:39,834 Skipping link: No binaries permitted for apache-iotdb: https://files.pythonhosted.org/packages/06/82/b658ff03f52072e1afde6bb9f1f1933427ef776a78e246965943fba552d8/apache_iotdb-1.0.1-py3-none-any.whl (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7) 2023-09-29T21:21:39,835 Found link https://files.pythonhosted.org/packages/15/99/bf0d6eae0c005a4dcc88068be36ea3e5b4dcb26e50b6698b4bd814d052e9/apache-iotdb-1.1.0.tar.gz (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7), version: 1.1.0 2023-09-29T21:21:39,835 Skipping link: No binaries permitted for apache-iotdb: https://files.pythonhosted.org/packages/3b/cd/72bfb3f3f3684bfe0c054dfd8c34fdb8a85f7572a6ec27b7a6ff99127516/apache_iotdb-1.1.0-py3-none-any.whl (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7) 2023-09-29T21:21:39,837 Found link https://files.pythonhosted.org/packages/51/36/6e73e46e1d6b2d2272a5a1b369da16dd36a3120aa883ea86d2a9a85ce105/apache-iotdb-1.1.2.tar.gz (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7), version: 1.1.2 2023-09-29T21:21:39,838 Skipping link: No binaries permitted for apache-iotdb: https://files.pythonhosted.org/packages/74/d6/3ad8c98fc4321ba99120a231634801b6bf1eea9520e5aa5d153b6fab6f61/apache_iotdb-1.1.2-py3-none-any.whl (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7) 2023-09-29T21:21:39,838 Found link https://files.pythonhosted.org/packages/49/bb/4a9f741d7ff483481ee9db619807e8835bcdd590eb9893de33ed091f7ec7/apache-iotdb-1.2.0.tar.gz (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7), version: 1.2.0 2023-09-29T21:21:39,839 Skipping link: No binaries permitted for apache-iotdb: https://files.pythonhosted.org/packages/93/b9/84d2d8e158ef2d5317f4f6ce0f14be616ec2b93c090fbf06a84e41d1cedd/apache_iotdb-1.2.0-py3-none-any.whl (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7) 2023-09-29T21:21:39,840 Found link https://files.pythonhosted.org/packages/86/cd/f88e673287faf21660046a1ec14dc917a5e598f2145ea2f1da0767dae759/apache-iotdb-1.2.1.tar.gz (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7), version: 1.2.1 2023-09-29T21:21:39,840 Skipping link: No binaries permitted for apache-iotdb: https://files.pythonhosted.org/packages/c6/a6/8f5f10ad95e5a2c2f54c78011ff2848a7b96860a439eeecdf136c3364795/apache_iotdb-1.2.1-py3-none-any.whl (from https://pypi.org/simple/apache-iotdb/) (requires-python:>=3.7) 2023-09-29T21:21:39,841 Fetching project page and analyzing links: https://www.piwheels.org/simple/apache-iotdb/ 2023-09-29T21:21:39,842 Getting page https://www.piwheels.org/simple/apache-iotdb/ 2023-09-29T21:21:39,843 Found index url https://www.piwheels.org/simple/ 2023-09-29T21:21:40,021 Fetched page https://www.piwheels.org/simple/apache-iotdb/ as text/html 2023-09-29T21:21:40,030 Skipping link: No binaries permitted for apache-iotdb: https://www.piwheels.org/simple/apache-iotdb/apache_iotdb-1.2.0-py3-none-any.whl#sha256=e6253fd0619e108f72e54769a1fdec7500f43db062b603e1bed07ebb989698b2 (from https://www.piwheels.org/simple/apache-iotdb/) (requires-python:>=3.7) 2023-09-29T21:21:40,031 Skipping link: No binaries permitted for apache-iotdb: https://www.piwheels.org/simple/apache-iotdb/apache_iotdb-1.1.2-py3-none-any.whl#sha256=47e1ea2a866155bd45db05471a074cd1b4bede6e798d2b6a63e218767c92ae12 (from https://www.piwheels.org/simple/apache-iotdb/) (requires-python:>=3.7) 2023-09-29T21:21:40,032 Skipping link: No binaries permitted for apache-iotdb: https://www.piwheels.org/simple/apache-iotdb/apache_iotdb-1.1.0-py3-none-any.whl#sha256=17b0261e5e0602df730baf1bdd055750c850a2fd0163d2ce09d0083dfcf169f4 (from https://www.piwheels.org/simple/apache-iotdb/) (requires-python:>=3.7) 2023-09-29T21:21:40,032 Skipping link: No binaries permitted for apache-iotdb: https://www.piwheels.org/simple/apache-iotdb/apache_iotdb-1.0.1-py3-none-any.whl#sha256=9fc3d243ca97c88bd3ca1f5092686e3ab5c99a6e5206fd6a6c6fdaab15c796b6 (from https://www.piwheels.org/simple/apache-iotdb/) (requires-python:>=3.7) 2023-09-29T21:21:40,033 Skipping link: No binaries permitted for apache-iotdb: https://www.piwheels.org/simple/apache-iotdb/apache_iotdb-1.0.0-py3-none-any.whl#sha256=85d0bb3ddb1c79359fec18e85c6d515dc3639752d77dea32c09c8afe0fefc906 (from https://www.piwheels.org/simple/apache-iotdb/) (requires-python:>=3.7) 2023-09-29T21:21:40,034 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) 2023-09-29T21:21:40,034 Skipping link: No binaries permitted for apache-iotdb: https://www.piwheels.org/simple/apache-iotdb/apache_iotdb-0.13.5.1-py3-none-any.whl#sha256=43316f1302a0f1a08a1842964fb611e34f317e908b76d1872954c09f2c5f5919 (from https://www.piwheels.org/simple/apache-iotdb/) (requires-python:>=3.7) 2023-09-29T21:21:40,035 Skipping link: No binaries permitted for apache-iotdb: https://www.piwheels.org/simple/apache-iotdb/apache_iotdb-0.13.5-py3-none-any.whl#sha256=e25dac25664b9ff8313cbb697f634269ef857ec9217d3256b893c43c8b0c151f (from https://www.piwheels.org/simple/apache-iotdb/) (requires-python:>=3.7) 2023-09-29T21:21:40,035 Skipping link: No binaries permitted for apache-iotdb: https://www.piwheels.org/simple/apache-iotdb/apache_iotdb-0.13.3-py3-none-any.whl#sha256=c3be87cabc4d19ad9fd999f524ac8547b971adb4a304bf8874fdb56a6ecca371 (from https://www.piwheels.org/simple/apache-iotdb/) (requires-python:>=3.7) 2023-09-29T21:21:40,036 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) 2023-09-29T21:21:40,036 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) 2023-09-29T21:21:40,037 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) 2023-09-29T21:21:40,037 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) 2023-09-29T21:21:40,038 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) 2023-09-29T21:21:40,038 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) 2023-09-29T21:21:40,039 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) 2023-09-29T21:21:40,039 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) 2023-09-29T21:21:40,040 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) 2023-09-29T21:21:40,040 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) 2023-09-29T21:21:40,041 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) 2023-09-29T21:21:40,042 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) 2023-09-29T21:21:40,042 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) 2023-09-29T21:21:40,043 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) 2023-09-29T21:21:40,043 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) 2023-09-29T21:21:40,044 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) 2023-09-29T21:21:40,044 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) 2023-09-29T21:21:40,045 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) 2023-09-29T21:21:40,045 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) 2023-09-29T21:21:40,046 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) 2023-09-29T21:21:40,046 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) 2023-09-29T21:21:40,047 Skipping link: not a file: https://www.piwheels.org/simple/apache-iotdb/ 2023-09-29T21:21:40,048 Skipping link: not a file: https://pypi.org/simple/apache-iotdb/ 2023-09-29T21:21:40,071 Given no hashes to check 1 links for project 'apache-iotdb': discarding no candidates 2023-09-29T21:21:40,090 Collecting apache-iotdb==1.2.1 2023-09-29T21:21:40,093 Created temporary directory: /tmp/pip-unpack-0_oc_sbp 2023-09-29T21:21:40,312 Downloading apache-iotdb-1.2.1.tar.gz (88 kB) 2023-09-29T21:21:40,528 Added apache-iotdb==1.2.1 from https://files.pythonhosted.org/packages/86/cd/f88e673287faf21660046a1ec14dc917a5e598f2145ea2f1da0767dae759/apache-iotdb-1.2.1.tar.gz to build tracker '/tmp/pip-build-tracker-3je7a8fk' 2023-09-29T21:21:40,533 Created temporary directory: /tmp/pip-build-env-_gufnjd1 2023-09-29T21:21:40,537 Installing build dependencies: started 2023-09-29T21:21:40,539 Running command pip subprocess to install build dependencies 2023-09-29T21:21:41,710 Using pip 23.2.1 from /home/piwheels/.local/lib/python3.11/site-packages/pip (python 3.11) 2023-09-29T21:21:42,233 Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple 2023-09-29T21:21:43,824 Collecting setuptools>=40.8.0 2023-09-29T21:21:43,898 Using cached https://www.piwheels.org/simple/setuptools/setuptools-68.2.2-py3-none-any.whl (807 kB) 2023-09-29T21:21:44,136 Collecting wheel 2023-09-29T21:21:44,152 Using cached https://www.piwheels.org/simple/wheel/wheel-0.41.2-py3-none-any.whl (64 kB) 2023-09-29T21:21:46,871 Installing collected packages: wheel, setuptools 2023-09-29T21:21:47,093 Creating /tmp/pip-build-env-_gufnjd1/overlay/local/bin 2023-09-29T21:21:47,095 changing mode of /tmp/pip-build-env-_gufnjd1/overlay/local/bin/wheel to 755 2023-09-29T21:21:49,309 Successfully installed setuptools-68.2.2 wheel-0.41.2 2023-09-29T21:21:49,816 Installing build dependencies: finished with status 'done' 2023-09-29T21:21:49,819 Getting requirements to build wheel: started 2023-09-29T21:21:49,820 Running command Getting requirements to build wheel 2023-09-29T21:21:50,268 2023-09-29T21:21:50,278 # Apache IoTDB 2023-09-29T21:21:50,279 [![Python Client](https://github.com/apache/iotdb/actions/workflows/client-python.yml/badge.svg?branch=master)](https://github.com/apache/iotdb/actions/workflows/client-python.yml) 2023-09-29T21:21:50,280 [![GitHub release](https://img.shields.io/github/release/apache/iotdb.svg)](https://github.com/apache/iotdb/releases) 2023-09-29T21:21:50,280 [![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html) 2023-09-29T21:21:50,281 ![](https://github-size-badge.herokuapp.com/apache/iotdb.svg) 2023-09-29T21:21:50,281 ![](https://img.shields.io/github/downloads/apache/iotdb/total.svg) 2023-09-29T21:21:50,282 ![](https://img.shields.io/badge/platform-win%20%7C%20macos%20%7C%20linux-yellow.svg) 2023-09-29T21:21:50,282 [![IoTDB Website](https://img.shields.io/website-up-down-green-red/https/shields.io.svg?label=iotdb-website)](https://iotdb.apache.org/) 2023-09-29T21:21:50,284 Apache IoTDB (Database for Internet of Things) is an IoT native database with high performance for 2023-09-29T21:21:50,284 data management and analysis, deployable on the edge and the cloud. Due to its light-weight 2023-09-29T21:21:50,285 architecture, high performance and rich feature set together with its deep integration with 2023-09-29T21:21:50,285 Apache Hadoop, Spark and Flink, Apache IoTDB can meet the requirements of massive data storage, 2023-09-29T21:21:50,286 high-speed data ingestion and complex data analysis in the IoT industrial fields. 2023-09-29T21:21:50,287 ## Python Native API 2023-09-29T21:21:50,288 ### Requirements 2023-09-29T21:21:50,289 You have to install thrift (>=0.13) before using the package. 2023-09-29T21:21:50,291 ### How to use (Example) 2023-09-29T21:21:50,292 First, download the latest package: `pip3 install apache-iotdb` 2023-09-29T21:21:50,293 *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!* 2023-09-29T21:21:50,293 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) 2023-09-29T21:21:50,294 An example of aligned timeseries: [Aligned Timeseries Session Example](https://github.com/apache/iotdb/blob/master/client-py/SessionAlignedTimeseriesExample.py) 2023-09-29T21:21:50,295 (you need to add `import iotdb` in the head of the file) 2023-09-29T21:21:50,296 Or: 2023-09-29T21:21:50,297 ```python 2023-09-29T21:21:50,298 from iotdb.Session import Session 2023-09-29T21:21:50,299 ip = "127.0.0.1" 2023-09-29T21:21:50,299 port_ = "6667" 2023-09-29T21:21:50,299 username_ = "root" 2023-09-29T21:21:50,300 password_ = "root" 2023-09-29T21:21:50,300 session = Session(ip, port_, username_, password_) 2023-09-29T21:21:50,301 session.open(False) 2023-09-29T21:21:50,301 zone = session.get_time_zone() 2023-09-29T21:21:50,302 session.close() 2023-09-29T21:21:50,302 ``` 2023-09-29T21:21:50,303 ### Initialization 2023-09-29T21:21:50,304 * Initialize a Session 2023-09-29T21:21:50,305 ```python 2023-09-29T21:21:50,306 session = Session(ip, port_, username_, password_, fetch_size=1024, zone_id="UTC+8") 2023-09-29T21:21:50,307 ``` 2023-09-29T21:21:50,308 * Open a session, with a parameter to specify whether to enable RPC compression 2023-09-29T21:21:50,309 ```python 2023-09-29T21:21:50,309 session.open(enable_rpc_compression=False) 2023-09-29T21:21:50,310 ``` 2023-09-29T21:21:50,311 Notice: this RPC compression status of client must comply with that of IoTDB server 2023-09-29T21:21:50,312 * Close a Session 2023-09-29T21:21:50,313 ```python 2023-09-29T21:21:50,314 session.close() 2023-09-29T21:21:50,315 ``` 2023-09-29T21:21:50,316 ### Data Definition Interface (DDL Interface) 2023-09-29T21:21:50,317 #### DATABASE Management 2023-09-29T21:21:50,318 * CREATE DATABASE 2023-09-29T21:21:50,320 ```python 2023-09-29T21:21:50,320 session.set_storage_group(group_name) 2023-09-29T21:21:50,321 ``` 2023-09-29T21:21:50,322 * Delete one or several databases 2023-09-29T21:21:50,323 ```python 2023-09-29T21:21:50,324 session.delete_storage_group(group_name) 2023-09-29T21:21:50,324 session.delete_storage_groups(group_name_lst) 2023-09-29T21:21:50,325 ``` 2023-09-29T21:21:50,326 #### Timeseries Management 2023-09-29T21:21:50,327 * Create one or multiple timeseries 2023-09-29T21:21:50,328 ```python 2023-09-29T21:21:50,329 session.create_time_series(ts_path, data_type, encoding, compressor, 2023-09-29T21:21:50,329 props=None, tags=None, attributes=None, alias=None) 2023-09-29T21:21:50,330 session.create_multi_time_series( 2023-09-29T21:21:50,331 ts_path_lst, data_type_lst, encoding_lst, compressor_lst, 2023-09-29T21:21:50,332 props_lst=None, tags_lst=None, attributes_lst=None, alias_lst=None 2023-09-29T21:21:50,332 ) 2023-09-29T21:21:50,333 ``` 2023-09-29T21:21:50,334 * Create aligned timeseries 2023-09-29T21:21:50,335 ```python 2023-09-29T21:21:50,336 session.create_aligned_time_series( 2023-09-29T21:21:50,337 device_id, measurements_lst, data_type_lst, encoding_lst, compressor_lst 2023-09-29T21:21:50,337 ) 2023-09-29T21:21:50,338 ``` 2023-09-29T21:21:50,339 Attention: Alias of measurements are **not supported** currently. 2023-09-29T21:21:50,340 * Delete one or several timeseries 2023-09-29T21:21:50,342 ```python 2023-09-29T21:21:50,342 session.delete_time_series(paths_list) 2023-09-29T21:21:50,343 ``` 2023-09-29T21:21:50,344 * Check whether the specific timeseries exists 2023-09-29T21:21:50,344 ```python 2023-09-29T21:21:50,345 session.check_time_series_exists(path) 2023-09-29T21:21:50,345 ``` 2023-09-29T21:21:50,346 ### Data Manipulation Interface (DML Interface) 2023-09-29T21:21:50,347 #### Insert 2023-09-29T21:21:50,348 It is recommended to use insertTablet to help improve write efficiency. 2023-09-29T21:21:50,349 * Insert a Tablet,which is multiple rows of a device, each row has the same measurements 2023-09-29T21:21:50,349 * **Better Write Performance** 2023-09-29T21:21:50,350 * **Support null values**: fill the null value with any value, and then mark the null value via BitMap (from v0.13) 2023-09-29T21:21:50,351 We have two implementations of Tablet in Python API. 2023-09-29T21:21:50,352 * Normal Tablet 2023-09-29T21:21:50,353 ```python 2023-09-29T21:21:50,354 values_ = [ 2023-09-29T21:21:50,354 [False, 10, 11, 1.1, 10011.1, "test01"], 2023-09-29T21:21:50,355 [True, 100, 11111, 1.25, 101.0, "test02"], 2023-09-29T21:21:50,355 [False, 100, 1, 188.1, 688.25, "test03"], 2023-09-29T21:21:50,356 [True, 0, 0, 0, 6.25, "test04"], 2023-09-29T21:21:50,356 ] 2023-09-29T21:21:50,357 timestamps_ = [1, 2, 3, 4] 2023-09-29T21:21:50,357 tablet_ = Tablet( 2023-09-29T21:21:50,358 device_id, measurements_, data_types_, values_, timestamps_ 2023-09-29T21:21:50,358 ) 2023-09-29T21:21:50,359 session.insert_tablet(tablet_) 2023-09-29T21:21:50,360 values_ = [ 2023-09-29T21:21:50,360 [None, 10, 11, 1.1, 10011.1, "test01"], 2023-09-29T21:21:50,361 [True, None, 11111, 1.25, 101.0, "test02"], 2023-09-29T21:21:50,361 [False, 100, None, 188.1, 688.25, "test03"], 2023-09-29T21:21:50,362 [True, 0, 0, 0, None, None], 2023-09-29T21:21:50,362 ] 2023-09-29T21:21:50,363 timestamps_ = [16, 17, 18, 19] 2023-09-29T21:21:50,363 tablet_ = Tablet( 2023-09-29T21:21:50,364 device_id, measurements_, data_types_, values_, timestamps_ 2023-09-29T21:21:50,365 ) 2023-09-29T21:21:50,365 session.insert_tablet(tablet_) 2023-09-29T21:21:50,366 ``` 2023-09-29T21:21:50,366 * Numpy Tablet 2023-09-29T21:21:50,367 Comparing with Tablet, Numpy Tablet is using [numpy.ndarray](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html) to record data. 2023-09-29T21:21:50,368 With less memory footprint and time cost of serialization, the insert performance will be better. 2023-09-29T21:21:50,369 **Notice** 2023-09-29T21:21:50,370 1. time and value columns in Tablet are ndarray. 2023-09-29T21:21:50,371 2. recommended to use the specific dtypes to each ndarray, see the example below 2023-09-29T21:21:50,371 (if not, the default dtypes are also ok). 2023-09-29T21:21:50,373 ```python 2023-09-29T21:21:50,373 import numpy as np 2023-09-29T21:21:50,374 data_types_ = [ 2023-09-29T21:21:50,374 TSDataType.BOOLEAN, 2023-09-29T21:21:50,375 TSDataType.INT32, 2023-09-29T21:21:50,375 TSDataType.INT64, 2023-09-29T21:21:50,376 TSDataType.FLOAT, 2023-09-29T21:21:50,377 TSDataType.DOUBLE, 2023-09-29T21:21:50,377 TSDataType.TEXT, 2023-09-29T21:21:50,378 ] 2023-09-29T21:21:50,378 np_values_ = [ 2023-09-29T21:21:50,379 np.array([False, True, False, True], TSDataType.BOOLEAN.np_dtype()), 2023-09-29T21:21:50,380 np.array([10, 100, 100, 0], TSDataType.INT32.np_dtype()), 2023-09-29T21:21:50,380 np.array([11, 11111, 1, 0], TSDataType.INT64.np_dtype()), 2023-09-29T21:21:50,381 np.array([1.1, 1.25, 188.1, 0], TSDataType.FLOAT.np_dtype()), 2023-09-29T21:21:50,382 np.array([10011.1, 101.0, 688.25, 6.25], TSDataType.DOUBLE.np_dtype()), 2023-09-29T21:21:50,382 np.array(["test01", "test02", "test03", "test04"], TSDataType.TEXT.np_dtype()), 2023-09-29T21:21:50,383 ] 2023-09-29T21:21:50,384 np_timestamps_ = np.array([1, 2, 3, 4], TSDataType.INT64.np_dtype()) 2023-09-29T21:21:50,385 np_tablet_ = NumpyTablet( 2023-09-29T21:21:50,385 device_id, measurements_, data_types_, np_values_, np_timestamps_ 2023-09-29T21:21:50,386 ) 2023-09-29T21:21:50,386 session.insert_tablet(np_tablet_) 2023-09-29T21:21:50,387 # insert one numpy tablet with none into the database. 2023-09-29T21:21:50,387 np_values_ = [ 2023-09-29T21:21:50,388 np.array([False, True, False, True], TSDataType.BOOLEAN.np_dtype()), 2023-09-29T21:21:50,388 np.array([10, 100, 100, 0], TSDataType.INT32.np_dtype()), 2023-09-29T21:21:50,389 np.array([11, 11111, 1, 0], TSDataType.INT64.np_dtype()), 2023-09-29T21:21:50,389 np.array([1.1, 1.25, 188.1, 0], TSDataType.FLOAT.np_dtype()), 2023-09-29T21:21:50,390 np.array([10011.1, 101.0, 688.25, 6.25], TSDataType.DOUBLE.np_dtype()), 2023-09-29T21:21:50,390 np.array(["test01", "test02", "test03", "test04"], TSDataType.TEXT.np_dtype()), 2023-09-29T21:21:50,390 ] 2023-09-29T21:21:50,391 np_timestamps_ = np.array([98, 99, 100, 101], TSDataType.INT64.np_dtype()) 2023-09-29T21:21:50,391 np_bitmaps_ = [] 2023-09-29T21:21:50,392 for i in range(len(measurements_)): 2023-09-29T21:21:50,392 np_bitmaps_.append(BitMap(len(np_timestamps_))) 2023-09-29T21:21:50,393 np_bitmaps_[0].mark(0) 2023-09-29T21:21:50,393 np_bitmaps_[1].mark(1) 2023-09-29T21:21:50,394 np_bitmaps_[2].mark(2) 2023-09-29T21:21:50,394 np_bitmaps_[4].mark(3) 2023-09-29T21:21:50,395 np_bitmaps_[5].mark(3) 2023-09-29T21:21:50,395 np_tablet_with_none = NumpyTablet( 2023-09-29T21:21:50,396 device_id, measurements_, data_types_, np_values_, np_timestamps_, np_bitmaps_ 2023-09-29T21:21:50,396 ) 2023-09-29T21:21:50,397 session.insert_tablet(np_tablet_with_none) 2023-09-29T21:21:50,397 ``` 2023-09-29T21:21:50,398 * Insert multiple Tablets 2023-09-29T21:21:50,400 ```python 2023-09-29T21:21:50,400 session.insert_tablets(tablet_lst) 2023-09-29T21:21:50,401 ``` 2023-09-29T21:21:50,402 * Insert a Record 2023-09-29T21:21:50,403 ```python 2023-09-29T21:21:50,404 session.insert_record(device_id, timestamp, measurements_, data_types_, values_) 2023-09-29T21:21:50,405 ``` 2023-09-29T21:21:50,406 * Insert multiple Records 2023-09-29T21:21:50,407 ```python 2023-09-29T21:21:50,407 session.insert_records( 2023-09-29T21:21:50,408 device_ids_, time_list_, measurements_list_, data_type_list_, values_list_ 2023-09-29T21:21:50,409 ) 2023-09-29T21:21:50,409 ``` 2023-09-29T21:21:50,410 * Insert multiple Records that belong to the same device. 2023-09-29T21:21:50,411 With type info the server has no need to do type inference, which leads a better performance 2023-09-29T21:21:50,412 ```python 2023-09-29T21:21:50,413 session.insert_records_of_one_device(device_id, time_list, measurements_list, data_types_list, values_list) 2023-09-29T21:21:50,414 ``` 2023-09-29T21:21:50,415 #### Insert with type inference 2023-09-29T21:21:50,416 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. 2023-09-29T21:21:50,417 * Insert a Record, which contains multiple measurement value of a device at a timestamp 2023-09-29T21:21:50,418 ```python 2023-09-29T21:21:50,418 session.insert_str_record(device_id, timestamp, measurements, string_values) 2023-09-29T21:21:50,419 ``` 2023-09-29T21:21:50,420 #### Insert of Aligned Timeseries 2023-09-29T21:21:50,421 The Insert of aligned timeseries uses interfaces like insert_aligned_XXX, and others are similar to the above interfaces: 2023-09-29T21:21:50,422 * insert_aligned_record 2023-09-29T21:21:50,423 * insert_aligned_records 2023-09-29T21:21:50,423 * insert_aligned_records_of_one_device 2023-09-29T21:21:50,424 * insert_aligned_tablet 2023-09-29T21:21:50,425 * insert_aligned_tablets 2023-09-29T21:21:50,426 ### IoTDB-SQL Interface 2023-09-29T21:21:50,427 * Execute query statement 2023-09-29T21:21:50,428 ```python 2023-09-29T21:21:50,428 session.execute_query_statement(sql) 2023-09-29T21:21:50,429 ``` 2023-09-29T21:21:50,430 * Execute non query statement 2023-09-29T21:21:50,431 ```python 2023-09-29T21:21:50,432 session.execute_non_query_statement(sql) 2023-09-29T21:21:50,433 ``` 2023-09-29T21:21:50,434 * Execute statement 2023-09-29T21:21:50,436 ```python 2023-09-29T21:21:50,436 session.execute_statement(sql) 2023-09-29T21:21:50,437 ``` 2023-09-29T21:21:50,438 ### Schema Template 2023-09-29T21:21:50,439 #### Create Schema Template 2023-09-29T21:21:50,440 The step for creating a metadata template is as follows 2023-09-29T21:21:50,440 1. Create the template class 2023-09-29T21:21:50,441 2. Adding child Node,InternalNode and MeasurementNode can be chose 2023-09-29T21:21:50,442 3. Execute create schema template function 2023-09-29T21:21:50,443 ```python 2023-09-29T21:21:50,444 template = Template(name=template_name, share_time=True) 2023-09-29T21:21:50,445 i_node_gps = InternalNode(name="GPS", share_time=False) 2023-09-29T21:21:50,446 i_node_v = InternalNode(name="vehicle", share_time=True) 2023-09-29T21:21:50,447 m_node_x = MeasurementNode("x", TSDataType.FLOAT, TSEncoding.RLE, Compressor.SNAPPY) 2023-09-29T21:21:50,448 i_node_gps.add_child(m_node_x) 2023-09-29T21:21:50,449 i_node_v.add_child(m_node_x) 2023-09-29T21:21:50,451 template.add_template(i_node_gps) 2023-09-29T21:21:50,451 template.add_template(i_node_v) 2023-09-29T21:21:50,452 template.add_template(m_node_x) 2023-09-29T21:21:50,453 session.create_schema_template(template) 2023-09-29T21:21:50,454 ``` 2023-09-29T21:21:50,455 #### Modify Schema Template nodes 2023-09-29T21:21:50,456 Modify nodes in a template, the template must be already created. These are functions that add or delete some measurement nodes. 2023-09-29T21:21:50,457 * add node in template 2023-09-29T21:21:50,457 ```python 2023-09-29T21:21:50,458 session.add_measurements_in_template(template_name, measurements_path, data_types, encodings, compressors, is_aligned) 2023-09-29T21:21:50,459 ``` 2023-09-29T21:21:50,461 * delete node in template 2023-09-29T21:21:50,462 ```python 2023-09-29T21:21:50,463 session.delete_node_in_template(template_name, path) 2023-09-29T21:21:50,464 ``` 2023-09-29T21:21:50,466 #### Set Schema Template 2023-09-29T21:21:50,466 ```python 2023-09-29T21:21:50,467 session.set_schema_template(template_name, prefix_path) 2023-09-29T21:21:50,468 ``` 2023-09-29T21:21:50,469 #### Uset Schema Template 2023-09-29T21:21:50,470 ```python 2023-09-29T21:21:50,471 session.unset_schema_template(template_name, prefix_path) 2023-09-29T21:21:50,471 ``` 2023-09-29T21:21:50,473 #### Show Schema Template 2023-09-29T21:21:50,474 * Show all schema templates 2023-09-29T21:21:50,475 ```python 2023-09-29T21:21:50,476 session.show_all_templates() 2023-09-29T21:21:50,477 ``` 2023-09-29T21:21:50,478 * Count all nodes in templates 2023-09-29T21:21:50,478 ```python 2023-09-29T21:21:50,479 session.count_measurements_in_template(template_name) 2023-09-29T21:21:50,480 ``` 2023-09-29T21:21:50,482 * Judge whether the path is measurement or not in templates, This measurement must be in the template 2023-09-29T21:21:50,483 ```python 2023-09-29T21:21:50,483 session.count_measurements_in_template(template_name, path) 2023-09-29T21:21:50,484 ``` 2023-09-29T21:21:50,486 * Judge whether the path is exist or not in templates, This path may not belong to the template 2023-09-29T21:21:50,487 ```python 2023-09-29T21:21:50,488 session.is_path_exist_in_template(template_name, path) 2023-09-29T21:21:50,489 ``` 2023-09-29T21:21:50,491 * Show nodes under in schema template 2023-09-29T21:21:50,492 ```python 2023-09-29T21:21:50,493 session.show_measurements_in_template(template_name) 2023-09-29T21:21:50,494 ``` 2023-09-29T21:21:50,495 * Show the path prefix where a schema template is set 2023-09-29T21:21:50,496 ```python 2023-09-29T21:21:50,496 session.show_paths_template_set_on(template_name) 2023-09-29T21:21:50,497 ``` 2023-09-29T21:21:50,498 * Show the path prefix where a schema template is used (i.e. the time series has been created) 2023-09-29T21:21:50,499 ```python 2023-09-29T21:21:50,499 session.show_paths_template_using_on(template_name) 2023-09-29T21:21:50,500 ``` 2023-09-29T21:21:50,501 #### Drop Schema Template 2023-09-29T21:21:50,501 Delete an existing metadata template,dropping an already set template is not supported 2023-09-29T21:21:50,502 ```python 2023-09-29T21:21:50,503 session.drop_schema_template("template_python") 2023-09-29T21:21:50,503 ``` 2023-09-29T21:21:50,505 ### Pandas Support 2023-09-29T21:21:50,506 To easily transform a query result to a [Pandas Dataframe](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html) 2023-09-29T21:21:50,507 the SessionDataSet has a method `.todf()` which consumes the dataset and transforms it to a pandas dataframe. 2023-09-29T21:21:50,508 Example: 2023-09-29T21:21:50,509 ```python 2023-09-29T21:21:50,510 from iotdb.Session import Session 2023-09-29T21:21:50,511 ip = "127.0.0.1" 2023-09-29T21:21:50,512 port_ = "6667" 2023-09-29T21:21:50,513 username_ = "root" 2023-09-29T21:21:50,513 password_ = "root" 2023-09-29T21:21:50,514 session = Session(ip, port_, username_, password_) 2023-09-29T21:21:50,514 session.open(False) 2023-09-29T21:21:50,515 result = session.execute_query_statement("SELECT * FROM root.*") 2023-09-29T21:21:50,516 # Transform to Pandas Dataset 2023-09-29T21:21:50,517 df = result.todf() 2023-09-29T21:21:50,518 session.close() 2023-09-29T21:21:50,519 # Now you can work with the dataframe 2023-09-29T21:21:50,519 df = ... 2023-09-29T21:21:50,519 ``` 2023-09-29T21:21:50,521 ### IoTDB Testcontainer 2023-09-29T21:21:50,522 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. 2023-09-29T21:21:50,523 To start (and stop) an IoTDB Database in a Docker container simply do: 2023-09-29T21:21:50,524 ```python 2023-09-29T21:21:50,524 class MyTestCase(unittest.TestCase): 2023-09-29T21:21:50,526 def test_something(self): 2023-09-29T21:21:50,526 with IoTDBContainer() as c: 2023-09-29T21:21:50,527 session = Session("localhost", c.get_exposed_port(6667), "root", "root") 2023-09-29T21:21:50,527 session.open(False) 2023-09-29T21:21:50,528 result = session.execute_query_statement("SHOW TIMESERIES") 2023-09-29T21:21:50,529 print(result) 2023-09-29T21:21:50,529 session.close() 2023-09-29T21:21:50,530 ``` 2023-09-29T21:21:50,530 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. 2023-09-29T21:21:50,532 ### IoTDB DBAPI 2023-09-29T21:21:50,533 IoTDB DBAPI implements the Python DB API 2.0 specification (https://peps.python.org/pep-0249/), which defines a common 2023-09-29T21:21:50,533 interface for accessing databases in Python. 2023-09-29T21:21:50,534 #### Examples 2023-09-29T21:21:50,535 + Initialization 2023-09-29T21:21:50,536 The initialized parameters are consistent with the session part (except for the sqlalchemy_mode). 2023-09-29T21:21:50,536 ```python 2023-09-29T21:21:50,537 from iotdb.dbapi import connect 2023-09-29T21:21:50,538 ip = "127.0.0.1" 2023-09-29T21:21:50,538 port_ = "6667" 2023-09-29T21:21:50,539 username_ = "root" 2023-09-29T21:21:50,539 password_ = "root" 2023-09-29T21:21:50,540 conn = connect(ip, port_, username_, password_,fetch_size=1024,zone_id="UTC+8",sqlalchemy_mode=False) 2023-09-29T21:21:50,540 cursor = conn.cursor() 2023-09-29T21:21:50,541 ``` 2023-09-29T21:21:50,542 + simple SQL statement execution 2023-09-29T21:21:50,542 ```python 2023-09-29T21:21:50,542 cursor.execute("SELECT * FROM root.*") 2023-09-29T21:21:50,543 for row in cursor.fetchall(): 2023-09-29T21:21:50,543 print(row) 2023-09-29T21:21:50,543 ``` 2023-09-29T21:21:50,544 + execute SQL with parameter 2023-09-29T21:21:50,545 IoTDB DBAPI supports pyformat style parameters 2023-09-29T21:21:50,545 ```python 2023-09-29T21:21:50,546 cursor.execute("SELECT * FROM root.* WHERE time < %(time)s",{"time":"2017-11-01T00:08:00.000"}) 2023-09-29T21:21:50,546 for row in cursor.fetchall(): 2023-09-29T21:21:50,546 print(row) 2023-09-29T21:21:50,547 ``` 2023-09-29T21:21:50,547 + execute SQL with parameter sequences 2023-09-29T21:21:50,548 ```python 2023-09-29T21:21:50,548 seq_of_parameters = [ 2023-09-29T21:21:50,548 {"timestamp": 1, "temperature": 1}, 2023-09-29T21:21:50,549 {"timestamp": 2, "temperature": 2}, 2023-09-29T21:21:50,549 {"timestamp": 3, "temperature": 3}, 2023-09-29T21:21:50,549 {"timestamp": 4, "temperature": 4}, 2023-09-29T21:21:50,550 {"timestamp": 5, "temperature": 5}, 2023-09-29T21:21:50,550 ] 2023-09-29T21:21:50,551 sql = "insert into root.cursor(timestamp,temperature) values(%(timestamp)s,%(temperature)s)" 2023-09-29T21:21:50,551 cursor.executemany(sql,seq_of_parameters) 2023-09-29T21:21:50,551 ``` 2023-09-29T21:21:50,552 + close the connection and cursor 2023-09-29T21:21:50,553 ```python 2023-09-29T21:21:50,553 cursor.close() 2023-09-29T21:21:50,553 conn.close() 2023-09-29T21:21:50,554 ``` 2023-09-29T21:21:50,554 ### IoTDB SQLAlchemy Dialect (Experimental) 2023-09-29T21:21:50,555 The SQLAlchemy dialect of IoTDB is written to adapt to Apache Superset. 2023-09-29T21:21:50,555 This part is still being improved. 2023-09-29T21:21:50,555 Please do not use it in the production environment! 2023-09-29T21:21:50,556 #### Mapping of the metadata 2023-09-29T21:21:50,557 The data model used by SQLAlchemy is a relational data model, which describes the relationships between different entities through tables. 2023-09-29T21:21:50,557 While the data model of IoTDB is a hierarchical data model, which organizes the data through a tree structure. 2023-09-29T21:21:50,558 In order to adapt IoTDB to the dialect of SQLAlchemy, the original data model in IoTDB needs to be reorganized. 2023-09-29T21:21:50,558 Converting the data model of IoTDB into the data model of SQLAlchemy. 2023-09-29T21:21:50,559 The metadata in the IoTDB are: 2023-09-29T21:21:50,561 1. Database 2023-09-29T21:21:50,561 2. Path 2023-09-29T21:21:50,562 3. Entity 2023-09-29T21:21:50,562 4. Measurement 2023-09-29T21:21:50,563 The metadata in the SQLAlchemy are: 2023-09-29T21:21:50,564 1. Schema 2023-09-29T21:21:50,564 2. Table 2023-09-29T21:21:50,565 3. Column 2023-09-29T21:21:50,566 The mapping relationship between them is: 2023-09-29T21:21:50,567 | The metadata in the SQLAlchemy | The metadata in the IoTDB | 2023-09-29T21:21:50,567 | -------------------- | ---------------------------------------------- | 2023-09-29T21:21:50,568 | Schema | Database | 2023-09-29T21:21:50,568 | Table | Path ( from database to entity ) + Entity | 2023-09-29T21:21:50,568 | Column | Measurement | 2023-09-29T21:21:50,569 The following figure shows the relationship between the two more intuitively: 2023-09-29T21:21:50,571 ![sqlalchemy-to-iotdb](https://github.com/apache/iotdb-bin-resources/blob/main/docs/UserGuide/API/IoTDB-SQLAlchemy/sqlalchemy-to-iotdb.png?raw=true) 2023-09-29T21:21:50,572 #### Data type mapping 2023-09-29T21:21:50,572 | data type in IoTDB | data type in SQLAlchemy | 2023-09-29T21:21:50,573 |--------------------|-------------------------| 2023-09-29T21:21:50,573 | BOOLEAN | Boolean | 2023-09-29T21:21:50,574 | INT32 | Integer | 2023-09-29T21:21:50,575 | INT64 | BigInteger | 2023-09-29T21:21:50,575 | FLOAT | Float | 2023-09-29T21:21:50,575 | DOUBLE | Float | 2023-09-29T21:21:50,576 | TEXT | Text | 2023-09-29T21:21:50,576 | LONG | BigInteger | 2023-09-29T21:21:50,577 #### Example 2023-09-29T21:21:50,577 + execute statement 2023-09-29T21:21:50,578 ```python 2023-09-29T21:21:50,578 from sqlalchemy import create_engine 2023-09-29T21:21:50,579 engine = create_engine("iotdb://root:root@127.0.0.1:6667") 2023-09-29T21:21:50,579 connect = engine.connect() 2023-09-29T21:21:50,580 result = connect.execute("SELECT ** FROM root") 2023-09-29T21:21:50,580 for row in result.fetchall(): 2023-09-29T21:21:50,580 print(row) 2023-09-29T21:21:50,581 ``` 2023-09-29T21:21:50,581 + ORM (now only simple queries are supported) 2023-09-29T21:21:50,582 ```python 2023-09-29T21:21:50,582 from sqlalchemy import create_engine, Column, Float, BigInteger, MetaData 2023-09-29T21:21:50,583 from sqlalchemy.ext.declarative import declarative_base 2023-09-29T21:21:50,583 from sqlalchemy.orm import sessionmaker 2023-09-29T21:21:50,584 metadata = MetaData( 2023-09-29T21:21:50,584 schema='root.factory' 2023-09-29T21:21:50,584 ) 2023-09-29T21:21:50,585 Base = declarative_base(metadata=metadata) 2023-09-29T21:21:50,586 class Device(Base): 2023-09-29T21:21:50,586 __tablename__ = "room2.device1" 2023-09-29T21:21:50,586 Time = Column(BigInteger, primary_key=True) 2023-09-29T21:21:50,587 temperature = Column(Float) 2023-09-29T21:21:50,587 status = Column(Float) 2023-09-29T21:21:50,588 engine = create_engine("iotdb://root:root@127.0.0.1:6667") 2023-09-29T21:21:50,590 DbSession = sessionmaker(bind=engine) 2023-09-29T21:21:50,590 session = DbSession() 2023-09-29T21:21:50,591 res = session.query(Device.status).filter(Device.temperature > 1) 2023-09-29T21:21:50,592 for row in res: 2023-09-29T21:21:50,593 print(row) 2023-09-29T21:21:50,593 ``` 2023-09-29T21:21:50,595 ## Developers 2023-09-29T21:21:50,596 ### Introduction 2023-09-29T21:21:50,597 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. 2023-09-29T21:21:50,599 ### Prerequisites 2023-09-29T21:21:50,600 Python3.7 or later is preferred. 2023-09-29T21:21:50,601 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. 2023-09-29T21:21:50,602 ``` 2023-09-29T21:21:50,602 http://thrift.apache.org/docs/install/ 2023-09-29T21:21:50,603 ``` 2023-09-29T21:21:50,604 Before starting you need to install `requirements_dev.txt` in your python environment, e.g. by calling 2023-09-29T21:21:50,604 ```shell 2023-09-29T21:21:50,605 pip install -r requirements_dev.txt 2023-09-29T21:21:50,605 ``` 2023-09-29T21:21:50,607 ### Compile the thrift library and Debug 2023-09-29T21:21:50,608 In the root of IoTDB's source code folder, run `mvn clean generate-sources -pl client-py -am`. 2023-09-29T21:21:50,609 This will automatically delete and repopulate the folder `iotdb/thrift` with the generated thrift files. 2023-09-29T21:21:50,609 This folder is ignored from git and should **never be pushed to git!** 2023-09-29T21:21:50,610 **Notice** Do not upload `iotdb/thrift` to the git repo. 2023-09-29T21:21:50,613 ### Session Client & Example 2023-09-29T21:21:50,614 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. 2023-09-29T21:21:50,615 Or, another simple example: 2023-09-29T21:21:50,616 ```python 2023-09-29T21:21:50,617 from iotdb.Session import Session 2023-09-29T21:21:50,617 ip = "127.0.0.1" 2023-09-29T21:21:50,618 port_ = "6667" 2023-09-29T21:21:50,618 username_ = "root" 2023-09-29T21:21:50,618 password_ = "root" 2023-09-29T21:21:50,619 session = Session(ip, port_, username_, password_) 2023-09-29T21:21:50,619 session.open(False) 2023-09-29T21:21:50,619 zone = session.get_time_zone() 2023-09-29T21:21:50,620 session.close() 2023-09-29T21:21:50,620 ``` 2023-09-29T21:21:50,622 ### Tests 2023-09-29T21:21:50,622 Please add your custom tests in `tests` folder. 2023-09-29T21:21:50,623 To run all defined tests just type `pytest .` in the root folder. 2023-09-29T21:21:50,624 **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). 2023-09-29T21:21:50,625 ### Futher Tools 2023-09-29T21:21:50,626 [black](https://pypi.org/project/black/) and [flake8](https://pypi.org/project/flake8/) are installed for autoformatting and linting. 2023-09-29T21:21:50,626 Both can be run by `black .` or `flake8 .` respectively. 2023-09-29T21:21:50,628 ## Releasing 2023-09-29T21:21:50,628 To do a release just ensure that you have the right set of generated thrift files. 2023-09-29T21:21:50,629 Then run linting and auto-formatting. 2023-09-29T21:21:50,629 Then, ensure that all tests work (via `pytest .`). 2023-09-29T21:21:50,629 Then you are good to go to do a release! 2023-09-29T21:21:50,631 ### Preparing your environment 2023-09-29T21:21:50,632 First, install all necessary dev dependencies via `pip install -r requirements_dev.txt`. 2023-09-29T21:21:50,633 ### Doing the Release 2023-09-29T21:21:50,634 There is a convenient script `release.sh` to do all steps for a release. 2023-09-29T21:21:50,635 Namely, these are 2023-09-29T21:21:50,636 * Remove all transient directories from last release (if exists) 2023-09-29T21:21:50,636 * (Re-)generate all generated sources via mvn 2023-09-29T21:21:50,637 * Run Linting (flake8) 2023-09-29T21:21:50,637 * Run Tests via pytest 2023-09-29T21:21:50,638 * Build 2023-09-29T21:21:50,638 * Release to pypi 2023-09-29T21:21:50,640 /tmp/pip-build-env-_gufnjd1/overlay/local/lib/python3.11/dist-packages/setuptools/_distutils/dist.py:265: UserWarning: Unknown distribution option: 'website' 2023-09-29T21:21:50,641 warnings.warn(msg) 2023-09-29T21:21:50,642 running egg_info 2023-09-29T21:21:50,642 writing apache_iotdb.egg-info/PKG-INFO 2023-09-29T21:21:50,643 writing dependency_links to apache_iotdb.egg-info/dependency_links.txt 2023-09-29T21:21:50,643 writing entry points to apache_iotdb.egg-info/entry_points.txt 2023-09-29T21:21:50,644 writing requirements to apache_iotdb.egg-info/requires.txt 2023-09-29T21:21:50,644 writing top-level names to apache_iotdb.egg-info/top_level.txt 2023-09-29T21:21:50,645 reading manifest file 'apache_iotdb.egg-info/SOURCES.txt' 2023-09-29T21:21:50,645 writing manifest file 'apache_iotdb.egg-info/SOURCES.txt' 2023-09-29T21:21:50,646 Getting requirements to build wheel: finished with status 'done' 2023-09-29T21:21:50,656 Created temporary directory: /tmp/pip-modern-metadata-aqd3v9yj 2023-09-29T21:21:50,658 Preparing metadata (pyproject.toml): started 2023-09-29T21:21:50,659 Running command Preparing metadata (pyproject.toml) 2023-09-29T21:21:51,119 2023-09-29T21:21:51,129 # Apache IoTDB 2023-09-29T21:21:51,130 [![Python Client](https://github.com/apache/iotdb/actions/workflows/client-python.yml/badge.svg?branch=master)](https://github.com/apache/iotdb/actions/workflows/client-python.yml) 2023-09-29T21:21:51,130 [![GitHub release](https://img.shields.io/github/release/apache/iotdb.svg)](https://github.com/apache/iotdb/releases) 2023-09-29T21:21:51,130 [![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html) 2023-09-29T21:21:51,131 ![](https://github-size-badge.herokuapp.com/apache/iotdb.svg) 2023-09-29T21:21:51,131 ![](https://img.shields.io/github/downloads/apache/iotdb/total.svg) 2023-09-29T21:21:51,132 ![](https://img.shields.io/badge/platform-win%20%7C%20macos%20%7C%20linux-yellow.svg) 2023-09-29T21:21:51,132 [![IoTDB Website](https://img.shields.io/website-up-down-green-red/https/shields.io.svg?label=iotdb-website)](https://iotdb.apache.org/) 2023-09-29T21:21:51,134 Apache IoTDB (Database for Internet of Things) is an IoT native database with high performance for 2023-09-29T21:21:51,134 data management and analysis, deployable on the edge and the cloud. Due to its light-weight 2023-09-29T21:21:51,135 architecture, high performance and rich feature set together with its deep integration with 2023-09-29T21:21:51,135 Apache Hadoop, Spark and Flink, Apache IoTDB can meet the requirements of massive data storage, 2023-09-29T21:21:51,136 high-speed data ingestion and complex data analysis in the IoT industrial fields. 2023-09-29T21:21:51,137 ## Python Native API 2023-09-29T21:21:51,138 ### Requirements 2023-09-29T21:21:51,140 You have to install thrift (>=0.13) before using the package. 2023-09-29T21:21:51,142 ### How to use (Example) 2023-09-29T21:21:51,143 First, download the latest package: `pip3 install apache-iotdb` 2023-09-29T21:21:51,145 *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!* 2023-09-29T21:21:51,146 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) 2023-09-29T21:21:51,147 An example of aligned timeseries: [Aligned Timeseries Session Example](https://github.com/apache/iotdb/blob/master/client-py/SessionAlignedTimeseriesExample.py) 2023-09-29T21:21:51,148 (you need to add `import iotdb` in the head of the file) 2023-09-29T21:21:51,149 Or: 2023-09-29T21:21:51,150 ```python 2023-09-29T21:21:51,151 from iotdb.Session import Session 2023-09-29T21:21:51,152 ip = "127.0.0.1" 2023-09-29T21:21:51,152 port_ = "6667" 2023-09-29T21:21:51,153 username_ = "root" 2023-09-29T21:21:51,153 password_ = "root" 2023-09-29T21:21:51,154 session = Session(ip, port_, username_, password_) 2023-09-29T21:21:51,155 session.open(False) 2023-09-29T21:21:51,155 zone = session.get_time_zone() 2023-09-29T21:21:51,156 session.close() 2023-09-29T21:21:51,156 ``` 2023-09-29T21:21:51,158 ### Initialization 2023-09-29T21:21:51,159 * Initialize a Session 2023-09-29T21:21:51,160 ```python 2023-09-29T21:21:51,161 session = Session(ip, port_, username_, password_, fetch_size=1024, zone_id="UTC+8") 2023-09-29T21:21:51,161 ``` 2023-09-29T21:21:51,163 * Open a session, with a parameter to specify whether to enable RPC compression 2023-09-29T21:21:51,164 ```python 2023-09-29T21:21:51,164 session.open(enable_rpc_compression=False) 2023-09-29T21:21:51,164 ``` 2023-09-29T21:21:51,165 Notice: this RPC compression status of client must comply with that of IoTDB server 2023-09-29T21:21:51,166 * Close a Session 2023-09-29T21:21:51,167 ```python 2023-09-29T21:21:51,167 session.close() 2023-09-29T21:21:51,168 ``` 2023-09-29T21:21:51,169 ### Data Definition Interface (DDL Interface) 2023-09-29T21:21:51,169 #### DATABASE Management 2023-09-29T21:21:51,170 * CREATE DATABASE 2023-09-29T21:21:51,171 ```python 2023-09-29T21:21:51,171 session.set_storage_group(group_name) 2023-09-29T21:21:51,172 ``` 2023-09-29T21:21:51,173 * Delete one or several databases 2023-09-29T21:21:51,173 ```python 2023-09-29T21:21:51,174 session.delete_storage_group(group_name) 2023-09-29T21:21:51,174 session.delete_storage_groups(group_name_lst) 2023-09-29T21:21:51,175 ``` 2023-09-29T21:21:51,175 #### Timeseries Management 2023-09-29T21:21:51,176 * Create one or multiple timeseries 2023-09-29T21:21:51,177 ```python 2023-09-29T21:21:51,178 session.create_time_series(ts_path, data_type, encoding, compressor, 2023-09-29T21:21:51,178 props=None, tags=None, attributes=None, alias=None) 2023-09-29T21:21:51,179 session.create_multi_time_series( 2023-09-29T21:21:51,180 ts_path_lst, data_type_lst, encoding_lst, compressor_lst, 2023-09-29T21:21:51,180 props_lst=None, tags_lst=None, attributes_lst=None, alias_lst=None 2023-09-29T21:21:51,180 ) 2023-09-29T21:21:51,181 ``` 2023-09-29T21:21:51,182 * Create aligned timeseries 2023-09-29T21:21:51,183 ```python 2023-09-29T21:21:51,183 session.create_aligned_time_series( 2023-09-29T21:21:51,184 device_id, measurements_lst, data_type_lst, encoding_lst, compressor_lst 2023-09-29T21:21:51,184 ) 2023-09-29T21:21:51,185 ``` 2023-09-29T21:21:51,186 Attention: Alias of measurements are **not supported** currently. 2023-09-29T21:21:51,187 * Delete one or several timeseries 2023-09-29T21:21:51,188 ```python 2023-09-29T21:21:51,189 session.delete_time_series(paths_list) 2023-09-29T21:21:51,189 ``` 2023-09-29T21:21:51,191 * Check whether the specific timeseries exists 2023-09-29T21:21:51,192 ```python 2023-09-29T21:21:51,193 session.check_time_series_exists(path) 2023-09-29T21:21:51,193 ``` 2023-09-29T21:21:51,194 ### Data Manipulation Interface (DML Interface) 2023-09-29T21:21:51,196 #### Insert 2023-09-29T21:21:51,197 It is recommended to use insertTablet to help improve write efficiency. 2023-09-29T21:21:51,198 * Insert a Tablet,which is multiple rows of a device, each row has the same measurements 2023-09-29T21:21:51,198 * **Better Write Performance** 2023-09-29T21:21:51,199 * **Support null values**: fill the null value with any value, and then mark the null value via BitMap (from v0.13) 2023-09-29T21:21:51,201 We have two implementations of Tablet in Python API. 2023-09-29T21:21:51,202 * Normal Tablet 2023-09-29T21:21:51,203 ```python 2023-09-29T21:21:51,204 values_ = [ 2023-09-29T21:21:51,204 [False, 10, 11, 1.1, 10011.1, "test01"], 2023-09-29T21:21:51,205 [True, 100, 11111, 1.25, 101.0, "test02"], 2023-09-29T21:21:51,205 [False, 100, 1, 188.1, 688.25, "test03"], 2023-09-29T21:21:51,206 [True, 0, 0, 0, 6.25, "test04"], 2023-09-29T21:21:51,206 ] 2023-09-29T21:21:51,207 timestamps_ = [1, 2, 3, 4] 2023-09-29T21:21:51,207 tablet_ = Tablet( 2023-09-29T21:21:51,208 device_id, measurements_, data_types_, values_, timestamps_ 2023-09-29T21:21:51,208 ) 2023-09-29T21:21:51,209 session.insert_tablet(tablet_) 2023-09-29T21:21:51,210 values_ = [ 2023-09-29T21:21:51,211 [None, 10, 11, 1.1, 10011.1, "test01"], 2023-09-29T21:21:51,212 [True, None, 11111, 1.25, 101.0, "test02"], 2023-09-29T21:21:51,212 [False, 100, None, 188.1, 688.25, "test03"], 2023-09-29T21:21:51,213 [True, 0, 0, 0, None, None], 2023-09-29T21:21:51,214 ] 2023-09-29T21:21:51,214 timestamps_ = [16, 17, 18, 19] 2023-09-29T21:21:51,215 tablet_ = Tablet( 2023-09-29T21:21:51,215 device_id, measurements_, data_types_, values_, timestamps_ 2023-09-29T21:21:51,216 ) 2023-09-29T21:21:51,216 session.insert_tablet(tablet_) 2023-09-29T21:21:51,217 ``` 2023-09-29T21:21:51,217 * Numpy Tablet 2023-09-29T21:21:51,218 Comparing with Tablet, Numpy Tablet is using [numpy.ndarray](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html) to record data. 2023-09-29T21:21:51,218 With less memory footprint and time cost of serialization, the insert performance will be better. 2023-09-29T21:21:51,219 **Notice** 2023-09-29T21:21:51,220 1. time and value columns in Tablet are ndarray. 2023-09-29T21:21:51,220 2. recommended to use the specific dtypes to each ndarray, see the example below 2023-09-29T21:21:51,220 (if not, the default dtypes are also ok). 2023-09-29T21:21:51,221 ```python 2023-09-29T21:21:51,222 import numpy as np 2023-09-29T21:21:51,222 data_types_ = [ 2023-09-29T21:21:51,222 TSDataType.BOOLEAN, 2023-09-29T21:21:51,223 TSDataType.INT32, 2023-09-29T21:21:51,223 TSDataType.INT64, 2023-09-29T21:21:51,224 TSDataType.FLOAT, 2023-09-29T21:21:51,224 TSDataType.DOUBLE, 2023-09-29T21:21:51,225 TSDataType.TEXT, 2023-09-29T21:21:51,225 ] 2023-09-29T21:21:51,226 np_values_ = [ 2023-09-29T21:21:51,226 np.array([False, True, False, True], TSDataType.BOOLEAN.np_dtype()), 2023-09-29T21:21:51,226 np.array([10, 100, 100, 0], TSDataType.INT32.np_dtype()), 2023-09-29T21:21:51,227 np.array([11, 11111, 1, 0], TSDataType.INT64.np_dtype()), 2023-09-29T21:21:51,227 np.array([1.1, 1.25, 188.1, 0], TSDataType.FLOAT.np_dtype()), 2023-09-29T21:21:51,228 np.array([10011.1, 101.0, 688.25, 6.25], TSDataType.DOUBLE.np_dtype()), 2023-09-29T21:21:51,229 np.array(["test01", "test02", "test03", "test04"], TSDataType.TEXT.np_dtype()), 2023-09-29T21:21:51,229 ] 2023-09-29T21:21:51,230 np_timestamps_ = np.array([1, 2, 3, 4], TSDataType.INT64.np_dtype()) 2023-09-29T21:21:51,230 np_tablet_ = NumpyTablet( 2023-09-29T21:21:51,231 device_id, measurements_, data_types_, np_values_, np_timestamps_ 2023-09-29T21:21:51,231 ) 2023-09-29T21:21:51,232 session.insert_tablet(np_tablet_) 2023-09-29T21:21:51,233 # insert one numpy tablet with none into the database. 2023-09-29T21:21:51,234 np_values_ = [ 2023-09-29T21:21:51,234 np.array([False, True, False, True], TSDataType.BOOLEAN.np_dtype()), 2023-09-29T21:21:51,235 np.array([10, 100, 100, 0], TSDataType.INT32.np_dtype()), 2023-09-29T21:21:51,235 np.array([11, 11111, 1, 0], TSDataType.INT64.np_dtype()), 2023-09-29T21:21:51,236 np.array([1.1, 1.25, 188.1, 0], TSDataType.FLOAT.np_dtype()), 2023-09-29T21:21:51,236 np.array([10011.1, 101.0, 688.25, 6.25], TSDataType.DOUBLE.np_dtype()), 2023-09-29T21:21:51,237 np.array(["test01", "test02", "test03", "test04"], TSDataType.TEXT.np_dtype()), 2023-09-29T21:21:51,237 ] 2023-09-29T21:21:51,238 np_timestamps_ = np.array([98, 99, 100, 101], TSDataType.INT64.np_dtype()) 2023-09-29T21:21:51,239 np_bitmaps_ = [] 2023-09-29T21:21:51,239 for i in range(len(measurements_)): 2023-09-29T21:21:51,240 np_bitmaps_.append(BitMap(len(np_timestamps_))) 2023-09-29T21:21:51,240 np_bitmaps_[0].mark(0) 2023-09-29T21:21:51,241 np_bitmaps_[1].mark(1) 2023-09-29T21:21:51,241 np_bitmaps_[2].mark(2) 2023-09-29T21:21:51,242 np_bitmaps_[4].mark(3) 2023-09-29T21:21:51,242 np_bitmaps_[5].mark(3) 2023-09-29T21:21:51,243 np_tablet_with_none = NumpyTablet( 2023-09-29T21:21:51,243 device_id, measurements_, data_types_, np_values_, np_timestamps_, np_bitmaps_ 2023-09-29T21:21:51,244 ) 2023-09-29T21:21:51,244 session.insert_tablet(np_tablet_with_none) 2023-09-29T21:21:51,245 ``` 2023-09-29T21:21:51,246 * Insert multiple Tablets 2023-09-29T21:21:51,247 ```python 2023-09-29T21:21:51,248 session.insert_tablets(tablet_lst) 2023-09-29T21:21:51,249 ``` 2023-09-29T21:21:51,250 * Insert a Record 2023-09-29T21:21:51,251 ```python 2023-09-29T21:21:51,251 session.insert_record(device_id, timestamp, measurements_, data_types_, values_) 2023-09-29T21:21:51,252 ``` 2023-09-29T21:21:51,253 * Insert multiple Records 2023-09-29T21:21:51,253 ```python 2023-09-29T21:21:51,254 session.insert_records( 2023-09-29T21:21:51,254 device_ids_, time_list_, measurements_list_, data_type_list_, values_list_ 2023-09-29T21:21:51,255 ) 2023-09-29T21:21:51,255 ``` 2023-09-29T21:21:51,256 * Insert multiple Records that belong to the same device. 2023-09-29T21:21:51,257 With type info the server has no need to do type inference, which leads a better performance 2023-09-29T21:21:51,258 ```python 2023-09-29T21:21:51,259 session.insert_records_of_one_device(device_id, time_list, measurements_list, data_types_list, values_list) 2023-09-29T21:21:51,259 ``` 2023-09-29T21:21:51,260 #### Insert with type inference 2023-09-29T21:21:51,261 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. 2023-09-29T21:21:51,262 * Insert a Record, which contains multiple measurement value of a device at a timestamp 2023-09-29T21:21:51,263 ```python 2023-09-29T21:21:51,264 session.insert_str_record(device_id, timestamp, measurements, string_values) 2023-09-29T21:21:51,264 ``` 2023-09-29T21:21:51,265 #### Insert of Aligned Timeseries 2023-09-29T21:21:51,266 The Insert of aligned timeseries uses interfaces like insert_aligned_XXX, and others are similar to the above interfaces: 2023-09-29T21:21:51,267 * insert_aligned_record 2023-09-29T21:21:51,268 * insert_aligned_records 2023-09-29T21:21:51,268 * insert_aligned_records_of_one_device 2023-09-29T21:21:51,269 * insert_aligned_tablet 2023-09-29T21:21:51,269 * insert_aligned_tablets 2023-09-29T21:21:51,271 ### IoTDB-SQL Interface 2023-09-29T21:21:51,272 * Execute query statement 2023-09-29T21:21:51,274 ```python 2023-09-29T21:21:51,274 session.execute_query_statement(sql) 2023-09-29T21:21:51,275 ``` 2023-09-29T21:21:51,276 * Execute non query statement 2023-09-29T21:21:51,277 ```python 2023-09-29T21:21:51,278 session.execute_non_query_statement(sql) 2023-09-29T21:21:51,278 ``` 2023-09-29T21:21:51,279 * Execute statement 2023-09-29T21:21:51,281 ```python 2023-09-29T21:21:51,281 session.execute_statement(sql) 2023-09-29T21:21:51,282 ``` 2023-09-29T21:21:51,283 ### Schema Template 2023-09-29T21:21:51,284 #### Create Schema Template 2023-09-29T21:21:51,284 The step for creating a metadata template is as follows 2023-09-29T21:21:51,285 1. Create the template class 2023-09-29T21:21:51,285 2. Adding child Node,InternalNode and MeasurementNode can be chose 2023-09-29T21:21:51,286 3. Execute create schema template function 2023-09-29T21:21:51,287 ```python 2023-09-29T21:21:51,287 template = Template(name=template_name, share_time=True) 2023-09-29T21:21:51,289 i_node_gps = InternalNode(name="GPS", share_time=False) 2023-09-29T21:21:51,289 i_node_v = InternalNode(name="vehicle", share_time=True) 2023-09-29T21:21:51,290 m_node_x = MeasurementNode("x", TSDataType.FLOAT, TSEncoding.RLE, Compressor.SNAPPY) 2023-09-29T21:21:51,291 i_node_gps.add_child(m_node_x) 2023-09-29T21:21:51,292 i_node_v.add_child(m_node_x) 2023-09-29T21:21:51,293 template.add_template(i_node_gps) 2023-09-29T21:21:51,294 template.add_template(i_node_v) 2023-09-29T21:21:51,295 template.add_template(m_node_x) 2023-09-29T21:21:51,296 session.create_schema_template(template) 2023-09-29T21:21:51,297 ``` 2023-09-29T21:21:51,298 #### Modify Schema Template nodes 2023-09-29T21:21:51,298 Modify nodes in a template, the template must be already created. These are functions that add or delete some measurement nodes. 2023-09-29T21:21:51,299 * add node in template 2023-09-29T21:21:51,300 ```python 2023-09-29T21:21:51,300 session.add_measurements_in_template(template_name, measurements_path, data_types, encodings, compressors, is_aligned) 2023-09-29T21:21:51,301 ``` 2023-09-29T21:21:51,301 * delete node in template 2023-09-29T21:21:51,302 ```python 2023-09-29T21:21:51,303 session.delete_node_in_template(template_name, path) 2023-09-29T21:21:51,303 ``` 2023-09-29T21:21:51,304 #### Set Schema Template 2023-09-29T21:21:51,304 ```python 2023-09-29T21:21:51,305 session.set_schema_template(template_name, prefix_path) 2023-09-29T21:21:51,305 ``` 2023-09-29T21:21:51,306 #### Uset Schema Template 2023-09-29T21:21:51,307 ```python 2023-09-29T21:21:51,307 session.unset_schema_template(template_name, prefix_path) 2023-09-29T21:21:51,307 ``` 2023-09-29T21:21:51,308 #### Show Schema Template 2023-09-29T21:21:51,309 * Show all schema templates 2023-09-29T21:21:51,309 ```python 2023-09-29T21:21:51,310 session.show_all_templates() 2023-09-29T21:21:51,310 ``` 2023-09-29T21:21:51,311 * Count all nodes in templates 2023-09-29T21:21:51,311 ```python 2023-09-29T21:21:51,312 session.count_measurements_in_template(template_name) 2023-09-29T21:21:51,312 ``` 2023-09-29T21:21:51,313 * Judge whether the path is measurement or not in templates, This measurement must be in the template 2023-09-29T21:21:51,314 ```python 2023-09-29T21:21:51,314 session.count_measurements_in_template(template_name, path) 2023-09-29T21:21:51,315 ``` 2023-09-29T21:21:51,316 * Judge whether the path is exist or not in templates, This path may not belong to the template 2023-09-29T21:21:51,316 ```python 2023-09-29T21:21:51,317 session.is_path_exist_in_template(template_name, path) 2023-09-29T21:21:51,317 ``` 2023-09-29T21:21:51,318 * Show nodes under in schema template 2023-09-29T21:21:51,319 ```python 2023-09-29T21:21:51,320 session.show_measurements_in_template(template_name) 2023-09-29T21:21:51,320 ``` 2023-09-29T21:21:51,321 * Show the path prefix where a schema template is set 2023-09-29T21:21:51,322 ```python 2023-09-29T21:21:51,323 session.show_paths_template_set_on(template_name) 2023-09-29T21:21:51,323 ``` 2023-09-29T21:21:51,325 * Show the path prefix where a schema template is used (i.e. the time series has been created) 2023-09-29T21:21:51,325 ```python 2023-09-29T21:21:51,326 session.show_paths_template_using_on(template_name) 2023-09-29T21:21:51,327 ``` 2023-09-29T21:21:51,328 #### Drop Schema Template 2023-09-29T21:21:51,328 Delete an existing metadata template,dropping an already set template is not supported 2023-09-29T21:21:51,329 ```python 2023-09-29T21:21:51,329 session.drop_schema_template("template_python") 2023-09-29T21:21:51,330 ``` 2023-09-29T21:21:51,332 ### Pandas Support 2023-09-29T21:21:51,333 To easily transform a query result to a [Pandas Dataframe](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html) 2023-09-29T21:21:51,333 the SessionDataSet has a method `.todf()` which consumes the dataset and transforms it to a pandas dataframe. 2023-09-29T21:21:51,334 Example: 2023-09-29T21:21:51,335 ```python 2023-09-29T21:21:51,336 from iotdb.Session import Session 2023-09-29T21:21:51,337 ip = "127.0.0.1" 2023-09-29T21:21:51,338 port_ = "6667" 2023-09-29T21:21:51,338 username_ = "root" 2023-09-29T21:21:51,339 password_ = "root" 2023-09-29T21:21:51,339 session = Session(ip, port_, username_, password_) 2023-09-29T21:21:51,340 session.open(False) 2023-09-29T21:21:51,341 result = session.execute_query_statement("SELECT * FROM root.*") 2023-09-29T21:21:51,342 # Transform to Pandas Dataset 2023-09-29T21:21:51,343 df = result.todf() 2023-09-29T21:21:51,344 session.close() 2023-09-29T21:21:51,345 # Now you can work with the dataframe 2023-09-29T21:21:51,345 df = ... 2023-09-29T21:21:51,346 ``` 2023-09-29T21:21:51,347 ### IoTDB Testcontainer 2023-09-29T21:21:51,348 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. 2023-09-29T21:21:51,349 To start (and stop) an IoTDB Database in a Docker container simply do: 2023-09-29T21:21:51,349 ```python 2023-09-29T21:21:51,350 class MyTestCase(unittest.TestCase): 2023-09-29T21:21:51,351 def test_something(self): 2023-09-29T21:21:51,351 with IoTDBContainer() as c: 2023-09-29T21:21:51,351 session = Session("localhost", c.get_exposed_port(6667), "root", "root") 2023-09-29T21:21:51,352 session.open(False) 2023-09-29T21:21:51,352 result = session.execute_query_statement("SHOW TIMESERIES") 2023-09-29T21:21:51,353 print(result) 2023-09-29T21:21:51,353 session.close() 2023-09-29T21:21:51,354 ``` 2023-09-29T21:21:51,355 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. 2023-09-29T21:21:51,356 ### IoTDB DBAPI 2023-09-29T21:21:51,357 IoTDB DBAPI implements the Python DB API 2.0 specification (https://peps.python.org/pep-0249/), which defines a common 2023-09-29T21:21:51,357 interface for accessing databases in Python. 2023-09-29T21:21:51,358 #### Examples 2023-09-29T21:21:51,359 + Initialization 2023-09-29T21:21:51,360 The initialized parameters are consistent with the session part (except for the sqlalchemy_mode). 2023-09-29T21:21:51,360 ```python 2023-09-29T21:21:51,361 from iotdb.dbapi import connect 2023-09-29T21:21:51,362 ip = "127.0.0.1" 2023-09-29T21:21:51,362 port_ = "6667" 2023-09-29T21:21:51,363 username_ = "root" 2023-09-29T21:21:51,363 password_ = "root" 2023-09-29T21:21:51,364 conn = connect(ip, port_, username_, password_,fetch_size=1024,zone_id="UTC+8",sqlalchemy_mode=False) 2023-09-29T21:21:51,364 cursor = conn.cursor() 2023-09-29T21:21:51,365 ``` 2023-09-29T21:21:51,365 + simple SQL statement execution 2023-09-29T21:21:51,366 ```python 2023-09-29T21:21:51,366 cursor.execute("SELECT * FROM root.*") 2023-09-29T21:21:51,367 for row in cursor.fetchall(): 2023-09-29T21:21:51,367 print(row) 2023-09-29T21:21:51,368 ``` 2023-09-29T21:21:51,369 + execute SQL with parameter 2023-09-29T21:21:51,370 IoTDB DBAPI supports pyformat style parameters 2023-09-29T21:21:51,370 ```python 2023-09-29T21:21:51,371 cursor.execute("SELECT * FROM root.* WHERE time < %(time)s",{"time":"2017-11-01T00:08:00.000"}) 2023-09-29T21:21:51,371 for row in cursor.fetchall(): 2023-09-29T21:21:51,372 print(row) 2023-09-29T21:21:51,374 ``` 2023-09-29T21:21:51,375 + execute SQL with parameter sequences 2023-09-29T21:21:51,376 ```python 2023-09-29T21:21:51,376 seq_of_parameters = [ 2023-09-29T21:21:51,377 {"timestamp": 1, "temperature": 1}, 2023-09-29T21:21:51,377 {"timestamp": 2, "temperature": 2}, 2023-09-29T21:21:51,378 {"timestamp": 3, "temperature": 3}, 2023-09-29T21:21:51,378 {"timestamp": 4, "temperature": 4}, 2023-09-29T21:21:51,379 {"timestamp": 5, "temperature": 5}, 2023-09-29T21:21:51,380 ] 2023-09-29T21:21:51,380 sql = "insert into root.cursor(timestamp,temperature) values(%(timestamp)s,%(temperature)s)" 2023-09-29T21:21:51,381 cursor.executemany(sql,seq_of_parameters) 2023-09-29T21:21:51,382 ``` 2023-09-29T21:21:51,384 + close the connection and cursor 2023-09-29T21:21:51,384 ```python 2023-09-29T21:21:51,385 cursor.close() 2023-09-29T21:21:51,386 conn.close() 2023-09-29T21:21:51,387 ``` 2023-09-29T21:21:51,389 ### IoTDB SQLAlchemy Dialect (Experimental) 2023-09-29T21:21:51,390 The SQLAlchemy dialect of IoTDB is written to adapt to Apache Superset. 2023-09-29T21:21:51,391 This part is still being improved. 2023-09-29T21:21:51,392 Please do not use it in the production environment! 2023-09-29T21:21:51,392 #### Mapping of the metadata 2023-09-29T21:21:51,394 The data model used by SQLAlchemy is a relational data model, which describes the relationships between different entities through tables. 2023-09-29T21:21:51,394 While the data model of IoTDB is a hierarchical data model, which organizes the data through a tree structure. 2023-09-29T21:21:51,395 In order to adapt IoTDB to the dialect of SQLAlchemy, the original data model in IoTDB needs to be reorganized. 2023-09-29T21:21:51,395 Converting the data model of IoTDB into the data model of SQLAlchemy. 2023-09-29T21:21:51,397 The metadata in the IoTDB are: 2023-09-29T21:21:51,398 1. Database 2023-09-29T21:21:51,399 2. Path 2023-09-29T21:21:51,400 3. Entity 2023-09-29T21:21:51,400 4. Measurement 2023-09-29T21:21:51,402 The metadata in the SQLAlchemy are: 2023-09-29T21:21:51,402 1. Schema 2023-09-29T21:21:51,403 2. Table 2023-09-29T21:21:51,404 3. Column 2023-09-29T21:21:51,405 The mapping relationship between them is: 2023-09-29T21:21:51,407 | The metadata in the SQLAlchemy | The metadata in the IoTDB | 2023-09-29T21:21:51,407 | -------------------- | ---------------------------------------------- | 2023-09-29T21:21:51,408 | Schema | Database | 2023-09-29T21:21:51,409 | Table | Path ( from database to entity ) + Entity | 2023-09-29T21:21:51,409 | Column | Measurement | 2023-09-29T21:21:51,411 The following figure shows the relationship between the two more intuitively: 2023-09-29T21:21:51,413 ![sqlalchemy-to-iotdb](https://github.com/apache/iotdb-bin-resources/blob/main/docs/UserGuide/API/IoTDB-SQLAlchemy/sqlalchemy-to-iotdb.png?raw=true) 2023-09-29T21:21:51,414 #### Data type mapping 2023-09-29T21:21:51,415 | data type in IoTDB | data type in SQLAlchemy | 2023-09-29T21:21:51,416 |--------------------|-------------------------| 2023-09-29T21:21:51,417 | BOOLEAN | Boolean | 2023-09-29T21:21:51,418 | INT32 | Integer | 2023-09-29T21:21:51,419 | INT64 | BigInteger | 2023-09-29T21:21:51,420 | FLOAT | Float | 2023-09-29T21:21:51,420 | DOUBLE | Float | 2023-09-29T21:21:51,421 | TEXT | Text | 2023-09-29T21:21:51,422 | LONG | BigInteger | 2023-09-29T21:21:51,423 #### Example 2023-09-29T21:21:51,425 + execute statement 2023-09-29T21:21:51,426 ```python 2023-09-29T21:21:51,427 from sqlalchemy import create_engine 2023-09-29T21:21:51,429 engine = create_engine("iotdb://root:root@127.0.0.1:6667") 2023-09-29T21:21:51,429 connect = engine.connect() 2023-09-29T21:21:51,430 result = connect.execute("SELECT ** FROM root") 2023-09-29T21:21:51,431 for row in result.fetchall(): 2023-09-29T21:21:51,432 print(row) 2023-09-29T21:21:51,432 ``` 2023-09-29T21:21:51,434 + ORM (now only simple queries are supported) 2023-09-29T21:21:51,435 ```python 2023-09-29T21:21:51,436 from sqlalchemy import create_engine, Column, Float, BigInteger, MetaData 2023-09-29T21:21:51,437 from sqlalchemy.ext.declarative import declarative_base 2023-09-29T21:21:51,437 from sqlalchemy.orm import sessionmaker 2023-09-29T21:21:51,439 metadata = MetaData( 2023-09-29T21:21:51,440 schema='root.factory' 2023-09-29T21:21:51,440 ) 2023-09-29T21:21:51,441 Base = declarative_base(metadata=metadata) 2023-09-29T21:21:51,444 class Device(Base): 2023-09-29T21:21:51,445 __tablename__ = "room2.device1" 2023-09-29T21:21:51,446 Time = Column(BigInteger, primary_key=True) 2023-09-29T21:21:51,447 temperature = Column(Float) 2023-09-29T21:21:51,448 status = Column(Float) 2023-09-29T21:21:51,450 engine = create_engine("iotdb://root:root@127.0.0.1:6667") 2023-09-29T21:21:51,452 DbSession = sessionmaker(bind=engine) 2023-09-29T21:21:51,453 session = DbSession() 2023-09-29T21:21:51,455 res = session.query(Device.status).filter(Device.temperature > 1) 2023-09-29T21:21:51,456 for row in res: 2023-09-29T21:21:51,457 print(row) 2023-09-29T21:21:51,458 ``` 2023-09-29T21:21:51,460 ## Developers 2023-09-29T21:21:51,461 ### Introduction 2023-09-29T21:21:51,463 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. 2023-09-29T21:21:51,466 ### Prerequisites 2023-09-29T21:21:51,467 Python3.7 or later is preferred. 2023-09-29T21:21:51,469 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. 2023-09-29T21:21:51,470 ``` 2023-09-29T21:21:51,470 http://thrift.apache.org/docs/install/ 2023-09-29T21:21:51,471 ``` 2023-09-29T21:21:51,472 Before starting you need to install `requirements_dev.txt` in your python environment, e.g. by calling 2023-09-29T21:21:51,473 ```shell 2023-09-29T21:21:51,473 pip install -r requirements_dev.txt 2023-09-29T21:21:51,474 ``` 2023-09-29T21:21:51,476 ### Compile the thrift library and Debug 2023-09-29T21:21:51,477 In the root of IoTDB's source code folder, run `mvn clean generate-sources -pl client-py -am`. 2023-09-29T21:21:51,478 This will automatically delete and repopulate the folder `iotdb/thrift` with the generated thrift files. 2023-09-29T21:21:51,479 This folder is ignored from git and should **never be pushed to git!** 2023-09-29T21:21:51,480 **Notice** Do not upload `iotdb/thrift` to the git repo. 2023-09-29T21:21:51,483 ### Session Client & Example 2023-09-29T21:21:51,484 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. 2023-09-29T21:21:51,487 Or, another simple example: 2023-09-29T21:21:51,488 ```python 2023-09-29T21:21:51,489 from iotdb.Session import Session 2023-09-29T21:21:51,491 ip = "127.0.0.1" 2023-09-29T21:21:51,491 port_ = "6667" 2023-09-29T21:21:51,492 username_ = "root" 2023-09-29T21:21:51,493 password_ = "root" 2023-09-29T21:21:51,493 session = Session(ip, port_, username_, password_) 2023-09-29T21:21:51,494 session.open(False) 2023-09-29T21:21:51,495 zone = session.get_time_zone() 2023-09-29T21:21:51,496 session.close() 2023-09-29T21:21:51,496 ``` 2023-09-29T21:21:51,498 ### Tests 2023-09-29T21:21:51,500 Please add your custom tests in `tests` folder. 2023-09-29T21:21:51,501 To run all defined tests just type `pytest .` in the root folder. 2023-09-29T21:21:51,502 **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). 2023-09-29T21:21:51,503 ### Futher Tools 2023-09-29T21:21:51,504 [black](https://pypi.org/project/black/) and [flake8](https://pypi.org/project/flake8/) are installed for autoformatting and linting. 2023-09-29T21:21:51,505 Both can be run by `black .` or `flake8 .` respectively. 2023-09-29T21:21:51,507 ## Releasing 2023-09-29T21:21:51,508 To do a release just ensure that you have the right set of generated thrift files. 2023-09-29T21:21:51,508 Then run linting and auto-formatting. 2023-09-29T21:21:51,509 Then, ensure that all tests work (via `pytest .`). 2023-09-29T21:21:51,509 Then you are good to go to do a release! 2023-09-29T21:21:51,511 ### Preparing your environment 2023-09-29T21:21:51,512 First, install all necessary dev dependencies via `pip install -r requirements_dev.txt`. 2023-09-29T21:21:51,515 ### Doing the Release 2023-09-29T21:21:51,516 There is a convenient script `release.sh` to do all steps for a release. 2023-09-29T21:21:51,516 Namely, these are 2023-09-29T21:21:51,518 * Remove all transient directories from last release (if exists) 2023-09-29T21:21:51,518 * (Re-)generate all generated sources via mvn 2023-09-29T21:21:51,518 * Run Linting (flake8) 2023-09-29T21:21:51,519 * Run Tests via pytest 2023-09-29T21:21:51,519 * Build 2023-09-29T21:21:51,519 * Release to pypi 2023-09-29T21:21:51,520 /tmp/pip-build-env-_gufnjd1/overlay/local/lib/python3.11/dist-packages/setuptools/_distutils/dist.py:265: UserWarning: Unknown distribution option: 'website' 2023-09-29T21:21:51,521 warnings.warn(msg) 2023-09-29T21:21:51,521 running dist_info 2023-09-29T21:21:51,522 creating /tmp/pip-modern-metadata-aqd3v9yj/apache_iotdb.egg-info 2023-09-29T21:21:51,522 writing /tmp/pip-modern-metadata-aqd3v9yj/apache_iotdb.egg-info/PKG-INFO 2023-09-29T21:21:51,522 writing dependency_links to /tmp/pip-modern-metadata-aqd3v9yj/apache_iotdb.egg-info/dependency_links.txt 2023-09-29T21:21:51,523 writing entry points to /tmp/pip-modern-metadata-aqd3v9yj/apache_iotdb.egg-info/entry_points.txt 2023-09-29T21:21:51,523 writing requirements to /tmp/pip-modern-metadata-aqd3v9yj/apache_iotdb.egg-info/requires.txt 2023-09-29T21:21:51,523 writing top-level names to /tmp/pip-modern-metadata-aqd3v9yj/apache_iotdb.egg-info/top_level.txt 2023-09-29T21:21:51,524 writing manifest file '/tmp/pip-modern-metadata-aqd3v9yj/apache_iotdb.egg-info/SOURCES.txt' 2023-09-29T21:21:51,524 reading manifest file '/tmp/pip-modern-metadata-aqd3v9yj/apache_iotdb.egg-info/SOURCES.txt' 2023-09-29T21:21:51,524 writing manifest file '/tmp/pip-modern-metadata-aqd3v9yj/apache_iotdb.egg-info/SOURCES.txt' 2023-09-29T21:21:51,525 creating '/tmp/pip-modern-metadata-aqd3v9yj/apache_iotdb-1.2.1.dist-info' 2023-09-29T21:21:51,525 Preparing metadata (pyproject.toml): finished with status 'done' 2023-09-29T21:21:51,531 Source in /tmp/pip-wheel-m8bh8obi/apache-iotdb_2212dc0ea0bb49029524d0ee8e3c089a has version 1.2.1, which satisfies requirement apache-iotdb==1.2.1 from https://files.pythonhosted.org/packages/86/cd/f88e673287faf21660046a1ec14dc917a5e598f2145ea2f1da0767dae759/apache-iotdb-1.2.1.tar.gz 2023-09-29T21:21:51,532 Removed apache-iotdb==1.2.1 from https://files.pythonhosted.org/packages/86/cd/f88e673287faf21660046a1ec14dc917a5e598f2145ea2f1da0767dae759/apache-iotdb-1.2.1.tar.gz from build tracker '/tmp/pip-build-tracker-3je7a8fk' 2023-09-29T21:21:51,540 Created temporary directory: /tmp/pip-unpack-bb7_osmu 2023-09-29T21:21:51,541 Created temporary directory: /tmp/pip-unpack-uq2oz9q4 2023-09-29T21:21:51,553 Building wheels for collected packages: apache-iotdb 2023-09-29T21:21:51,558 Created temporary directory: /tmp/pip-wheel-wby14tsg 2023-09-29T21:21:51,558 Destination directory: /tmp/pip-wheel-wby14tsg 2023-09-29T21:21:51,561 Building wheel for apache-iotdb (pyproject.toml): started 2023-09-29T21:21:51,562 Running command Building wheel for apache-iotdb (pyproject.toml) 2023-09-29T21:21:52,010 2023-09-29T21:21:52,021 # Apache IoTDB 2023-09-29T21:21:52,022 [![Python Client](https://github.com/apache/iotdb/actions/workflows/client-python.yml/badge.svg?branch=master)](https://github.com/apache/iotdb/actions/workflows/client-python.yml) 2023-09-29T21:21:52,022 [![GitHub release](https://img.shields.io/github/release/apache/iotdb.svg)](https://github.com/apache/iotdb/releases) 2023-09-29T21:21:52,022 [![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html) 2023-09-29T21:21:52,023 ![](https://github-size-badge.herokuapp.com/apache/iotdb.svg) 2023-09-29T21:21:52,023 ![](https://img.shields.io/github/downloads/apache/iotdb/total.svg) 2023-09-29T21:21:52,024 ![](https://img.shields.io/badge/platform-win%20%7C%20macos%20%7C%20linux-yellow.svg) 2023-09-29T21:21:52,024 [![IoTDB Website](https://img.shields.io/website-up-down-green-red/https/shields.io.svg?label=iotdb-website)](https://iotdb.apache.org/) 2023-09-29T21:21:52,025 Apache IoTDB (Database for Internet of Things) is an IoT native database with high performance for 2023-09-29T21:21:52,026 data management and analysis, deployable on the edge and the cloud. Due to its light-weight 2023-09-29T21:21:52,026 architecture, high performance and rich feature set together with its deep integration with 2023-09-29T21:21:52,027 Apache Hadoop, Spark and Flink, Apache IoTDB can meet the requirements of massive data storage, 2023-09-29T21:21:52,027 high-speed data ingestion and complex data analysis in the IoT industrial fields. 2023-09-29T21:21:52,030 ## Python Native API 2023-09-29T21:21:52,031 ### Requirements 2023-09-29T21:21:52,032 You have to install thrift (>=0.13) before using the package. 2023-09-29T21:21:52,034 ### How to use (Example) 2023-09-29T21:21:52,035 First, download the latest package: `pip3 install apache-iotdb` 2023-09-29T21:21:52,036 *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!* 2023-09-29T21:21:52,037 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) 2023-09-29T21:21:52,039 An example of aligned timeseries: [Aligned Timeseries Session Example](https://github.com/apache/iotdb/blob/master/client-py/SessionAlignedTimeseriesExample.py) 2023-09-29T21:21:52,040 (you need to add `import iotdb` in the head of the file) 2023-09-29T21:21:52,041 Or: 2023-09-29T21:21:52,043 ```python 2023-09-29T21:21:52,043 from iotdb.Session import Session 2023-09-29T21:21:52,044 ip = "127.0.0.1" 2023-09-29T21:21:52,045 port_ = "6667" 2023-09-29T21:21:52,046 username_ = "root" 2023-09-29T21:21:52,046 password_ = "root" 2023-09-29T21:21:52,047 session = Session(ip, port_, username_, password_) 2023-09-29T21:21:52,047 session.open(False) 2023-09-29T21:21:52,048 zone = session.get_time_zone() 2023-09-29T21:21:52,048 session.close() 2023-09-29T21:21:52,049 ``` 2023-09-29T21:21:52,050 ### Initialization 2023-09-29T21:21:52,051 * Initialize a Session 2023-09-29T21:21:52,052 ```python 2023-09-29T21:21:52,053 session = Session(ip, port_, username_, password_, fetch_size=1024, zone_id="UTC+8") 2023-09-29T21:21:52,054 ``` 2023-09-29T21:21:52,055 * Open a session, with a parameter to specify whether to enable RPC compression 2023-09-29T21:21:52,056 ```python 2023-09-29T21:21:52,056 session.open(enable_rpc_compression=False) 2023-09-29T21:21:52,057 ``` 2023-09-29T21:21:52,058 Notice: this RPC compression status of client must comply with that of IoTDB server 2023-09-29T21:21:52,060 * Close a Session 2023-09-29T21:21:52,061 ```python 2023-09-29T21:21:52,061 session.close() 2023-09-29T21:21:52,062 ``` 2023-09-29T21:21:52,064 ### Data Definition Interface (DDL Interface) 2023-09-29T21:21:52,065 #### DATABASE Management 2023-09-29T21:21:52,066 * CREATE DATABASE 2023-09-29T21:21:52,067 ```python 2023-09-29T21:21:52,067 session.set_storage_group(group_name) 2023-09-29T21:21:52,067 ``` 2023-09-29T21:21:52,068 * Delete one or several databases 2023-09-29T21:21:52,069 ```python 2023-09-29T21:21:52,070 session.delete_storage_group(group_name) 2023-09-29T21:21:52,070 session.delete_storage_groups(group_name_lst) 2023-09-29T21:21:52,070 ``` 2023-09-29T21:21:52,071 #### Timeseries Management 2023-09-29T21:21:52,072 * Create one or multiple timeseries 2023-09-29T21:21:52,073 ```python 2023-09-29T21:21:52,073 session.create_time_series(ts_path, data_type, encoding, compressor, 2023-09-29T21:21:52,074 props=None, tags=None, attributes=None, alias=None) 2023-09-29T21:21:52,074 session.create_multi_time_series( 2023-09-29T21:21:52,075 ts_path_lst, data_type_lst, encoding_lst, compressor_lst, 2023-09-29T21:21:52,075 props_lst=None, tags_lst=None, attributes_lst=None, alias_lst=None 2023-09-29T21:21:52,076 ) 2023-09-29T21:21:52,076 ``` 2023-09-29T21:21:52,077 * Create aligned timeseries 2023-09-29T21:21:52,078 ```python 2023-09-29T21:21:52,078 session.create_aligned_time_series( 2023-09-29T21:21:52,079 device_id, measurements_lst, data_type_lst, encoding_lst, compressor_lst 2023-09-29T21:21:52,079 ) 2023-09-29T21:21:52,080 ``` 2023-09-29T21:21:52,081 Attention: Alias of measurements are **not supported** currently. 2023-09-29T21:21:52,082 * Delete one or several timeseries 2023-09-29T21:21:52,083 ```python 2023-09-29T21:21:52,083 session.delete_time_series(paths_list) 2023-09-29T21:21:52,084 ``` 2023-09-29T21:21:52,085 * Check whether the specific timeseries exists 2023-09-29T21:21:52,086 ```python 2023-09-29T21:21:52,086 session.check_time_series_exists(path) 2023-09-29T21:21:52,087 ``` 2023-09-29T21:21:52,088 ### Data Manipulation Interface (DML Interface) 2023-09-29T21:21:52,089 #### Insert 2023-09-29T21:21:52,091 It is recommended to use insertTablet to help improve write efficiency. 2023-09-29T21:21:52,092 * Insert a Tablet,which is multiple rows of a device, each row has the same measurements 2023-09-29T21:21:52,092 * **Better Write Performance** 2023-09-29T21:21:52,093 * **Support null values**: fill the null value with any value, and then mark the null value via BitMap (from v0.13) 2023-09-29T21:21:52,095 We have two implementations of Tablet in Python API. 2023-09-29T21:21:52,096 * Normal Tablet 2023-09-29T21:21:52,097 ```python 2023-09-29T21:21:52,097 values_ = [ 2023-09-29T21:21:52,098 [False, 10, 11, 1.1, 10011.1, "test01"], 2023-09-29T21:21:52,099 [True, 100, 11111, 1.25, 101.0, "test02"], 2023-09-29T21:21:52,099 [False, 100, 1, 188.1, 688.25, "test03"], 2023-09-29T21:21:52,100 [True, 0, 0, 0, 6.25, "test04"], 2023-09-29T21:21:52,100 ] 2023-09-29T21:21:52,101 timestamps_ = [1, 2, 3, 4] 2023-09-29T21:21:52,101 tablet_ = Tablet( 2023-09-29T21:21:52,102 device_id, measurements_, data_types_, values_, timestamps_ 2023-09-29T21:21:52,102 ) 2023-09-29T21:21:52,103 session.insert_tablet(tablet_) 2023-09-29T21:21:52,104 values_ = [ 2023-09-29T21:21:52,104 [None, 10, 11, 1.1, 10011.1, "test01"], 2023-09-29T21:21:52,105 [True, None, 11111, 1.25, 101.0, "test02"], 2023-09-29T21:21:52,106 [False, 100, None, 188.1, 688.25, "test03"], 2023-09-29T21:21:52,106 [True, 0, 0, 0, None, None], 2023-09-29T21:21:52,107 ] 2023-09-29T21:21:52,107 timestamps_ = [16, 17, 18, 19] 2023-09-29T21:21:52,108 tablet_ = Tablet( 2023-09-29T21:21:52,108 device_id, measurements_, data_types_, values_, timestamps_ 2023-09-29T21:21:52,109 ) 2023-09-29T21:21:52,110 session.insert_tablet(tablet_) 2023-09-29T21:21:52,110 ``` 2023-09-29T21:21:52,111 * Numpy Tablet 2023-09-29T21:21:52,112 Comparing with Tablet, Numpy Tablet is using [numpy.ndarray](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html) to record data. 2023-09-29T21:21:52,113 With less memory footprint and time cost of serialization, the insert performance will be better. 2023-09-29T21:21:52,114 **Notice** 2023-09-29T21:21:52,115 1. time and value columns in Tablet are ndarray. 2023-09-29T21:21:52,115 2. recommended to use the specific dtypes to each ndarray, see the example below 2023-09-29T21:21:52,115 (if not, the default dtypes are also ok). 2023-09-29T21:21:52,116 ```python 2023-09-29T21:21:52,117 import numpy as np 2023-09-29T21:21:52,117 data_types_ = [ 2023-09-29T21:21:52,118 TSDataType.BOOLEAN, 2023-09-29T21:21:52,118 TSDataType.INT32, 2023-09-29T21:21:52,119 TSDataType.INT64, 2023-09-29T21:21:52,119 TSDataType.FLOAT, 2023-09-29T21:21:52,119 TSDataType.DOUBLE, 2023-09-29T21:21:52,120 TSDataType.TEXT, 2023-09-29T21:21:52,120 ] 2023-09-29T21:21:52,121 np_values_ = [ 2023-09-29T21:21:52,121 np.array([False, True, False, True], TSDataType.BOOLEAN.np_dtype()), 2023-09-29T21:21:52,122 np.array([10, 100, 100, 0], TSDataType.INT32.np_dtype()), 2023-09-29T21:21:52,122 np.array([11, 11111, 1, 0], TSDataType.INT64.np_dtype()), 2023-09-29T21:21:52,123 np.array([1.1, 1.25, 188.1, 0], TSDataType.FLOAT.np_dtype()), 2023-09-29T21:21:52,123 np.array([10011.1, 101.0, 688.25, 6.25], TSDataType.DOUBLE.np_dtype()), 2023-09-29T21:21:52,124 np.array(["test01", "test02", "test03", "test04"], TSDataType.TEXT.np_dtype()), 2023-09-29T21:21:52,124 ] 2023-09-29T21:21:52,125 np_timestamps_ = np.array([1, 2, 3, 4], TSDataType.INT64.np_dtype()) 2023-09-29T21:21:52,125 np_tablet_ = NumpyTablet( 2023-09-29T21:21:52,125 device_id, measurements_, data_types_, np_values_, np_timestamps_ 2023-09-29T21:21:52,126 ) 2023-09-29T21:21:52,126 session.insert_tablet(np_tablet_) 2023-09-29T21:21:52,128 # insert one numpy tablet with none into the database. 2023-09-29T21:21:52,128 np_values_ = [ 2023-09-29T21:21:52,129 np.array([False, True, False, True], TSDataType.BOOLEAN.np_dtype()), 2023-09-29T21:21:52,129 np.array([10, 100, 100, 0], TSDataType.INT32.np_dtype()), 2023-09-29T21:21:52,130 np.array([11, 11111, 1, 0], TSDataType.INT64.np_dtype()), 2023-09-29T21:21:52,130 np.array([1.1, 1.25, 188.1, 0], TSDataType.FLOAT.np_dtype()), 2023-09-29T21:21:52,131 np.array([10011.1, 101.0, 688.25, 6.25], TSDataType.DOUBLE.np_dtype()), 2023-09-29T21:21:52,132 np.array(["test01", "test02", "test03", "test04"], TSDataType.TEXT.np_dtype()), 2023-09-29T21:21:52,132 ] 2023-09-29T21:21:52,133 np_timestamps_ = np.array([98, 99, 100, 101], TSDataType.INT64.np_dtype()) 2023-09-29T21:21:52,133 np_bitmaps_ = [] 2023-09-29T21:21:52,134 for i in range(len(measurements_)): 2023-09-29T21:21:52,135 np_bitmaps_.append(BitMap(len(np_timestamps_))) 2023-09-29T21:21:52,135 np_bitmaps_[0].mark(0) 2023-09-29T21:21:52,136 np_bitmaps_[1].mark(1) 2023-09-29T21:21:52,136 np_bitmaps_[2].mark(2) 2023-09-29T21:21:52,137 np_bitmaps_[4].mark(3) 2023-09-29T21:21:52,137 np_bitmaps_[5].mark(3) 2023-09-29T21:21:52,138 np_tablet_with_none = NumpyTablet( 2023-09-29T21:21:52,138 device_id, measurements_, data_types_, np_values_, np_timestamps_, np_bitmaps_ 2023-09-29T21:21:52,139 ) 2023-09-29T21:21:52,139 session.insert_tablet(np_tablet_with_none) 2023-09-29T21:21:52,140 ``` 2023-09-29T21:21:52,141 * Insert multiple Tablets 2023-09-29T21:21:52,142 ```python 2023-09-29T21:21:52,143 session.insert_tablets(tablet_lst) 2023-09-29T21:21:52,143 ``` 2023-09-29T21:21:52,145 * Insert a Record 2023-09-29T21:21:52,146 ```python 2023-09-29T21:21:52,147 session.insert_record(device_id, timestamp, measurements_, data_types_, values_) 2023-09-29T21:21:52,147 ``` 2023-09-29T21:21:52,149 * Insert multiple Records 2023-09-29T21:21:52,151 ```python 2023-09-29T21:21:52,152 session.insert_records( 2023-09-29T21:21:52,153 device_ids_, time_list_, measurements_list_, data_type_list_, values_list_ 2023-09-29T21:21:52,153 ) 2023-09-29T21:21:52,154 ``` 2023-09-29T21:21:52,155 * Insert multiple Records that belong to the same device. 2023-09-29T21:21:52,155 With type info the server has no need to do type inference, which leads a better performance 2023-09-29T21:21:52,157 ```python 2023-09-29T21:21:52,157 session.insert_records_of_one_device(device_id, time_list, measurements_list, data_types_list, values_list) 2023-09-29T21:21:52,157 ``` 2023-09-29T21:21:52,158 #### Insert with type inference 2023-09-29T21:21:52,159 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. 2023-09-29T21:21:52,160 * Insert a Record, which contains multiple measurement value of a device at a timestamp 2023-09-29T21:21:52,161 ```python 2023-09-29T21:21:52,161 session.insert_str_record(device_id, timestamp, measurements, string_values) 2023-09-29T21:21:52,162 ``` 2023-09-29T21:21:52,163 #### Insert of Aligned Timeseries 2023-09-29T21:21:52,163 The Insert of aligned timeseries uses interfaces like insert_aligned_XXX, and others are similar to the above interfaces: 2023-09-29T21:21:52,164 * insert_aligned_record 2023-09-29T21:21:52,165 * insert_aligned_records 2023-09-29T21:21:52,165 * insert_aligned_records_of_one_device 2023-09-29T21:21:52,166 * insert_aligned_tablet 2023-09-29T21:21:52,166 * insert_aligned_tablets 2023-09-29T21:21:52,167 ### IoTDB-SQL Interface 2023-09-29T21:21:52,168 * Execute query statement 2023-09-29T21:21:52,169 ```python 2023-09-29T21:21:52,170 session.execute_query_statement(sql) 2023-09-29T21:21:52,170 ``` 2023-09-29T21:21:52,172 * Execute non query statement 2023-09-29T21:21:52,173 ```python 2023-09-29T21:21:52,174 session.execute_non_query_statement(sql) 2023-09-29T21:21:52,174 ``` 2023-09-29T21:21:52,175 * Execute statement 2023-09-29T21:21:52,176 ```python 2023-09-29T21:21:52,177 session.execute_statement(sql) 2023-09-29T21:21:52,178 ``` 2023-09-29T21:21:52,179 ### Schema Template 2023-09-29T21:21:52,180 #### Create Schema Template 2023-09-29T21:21:52,180 The step for creating a metadata template is as follows 2023-09-29T21:21:52,181 1. Create the template class 2023-09-29T21:21:52,181 2. Adding child Node,InternalNode and MeasurementNode can be chose 2023-09-29T21:21:52,182 3. Execute create schema template function 2023-09-29T21:21:52,183 ```python 2023-09-29T21:21:52,184 template = Template(name=template_name, share_time=True) 2023-09-29T21:21:52,185 i_node_gps = InternalNode(name="GPS", share_time=False) 2023-09-29T21:21:52,186 i_node_v = InternalNode(name="vehicle", share_time=True) 2023-09-29T21:21:52,186 m_node_x = MeasurementNode("x", TSDataType.FLOAT, TSEncoding.RLE, Compressor.SNAPPY) 2023-09-29T21:21:52,187 i_node_gps.add_child(m_node_x) 2023-09-29T21:21:52,188 i_node_v.add_child(m_node_x) 2023-09-29T21:21:52,189 template.add_template(i_node_gps) 2023-09-29T21:21:52,190 template.add_template(i_node_v) 2023-09-29T21:21:52,190 template.add_template(m_node_x) 2023-09-29T21:21:52,191 session.create_schema_template(template) 2023-09-29T21:21:52,192 ``` 2023-09-29T21:21:52,192 #### Modify Schema Template nodes 2023-09-29T21:21:52,193 Modify nodes in a template, the template must be already created. These are functions that add or delete some measurement nodes. 2023-09-29T21:21:52,194 * add node in template 2023-09-29T21:21:52,194 ```python 2023-09-29T21:21:52,195 session.add_measurements_in_template(template_name, measurements_path, data_types, encodings, compressors, is_aligned) 2023-09-29T21:21:52,195 ``` 2023-09-29T21:21:52,196 * delete node in template 2023-09-29T21:21:52,197 ```python 2023-09-29T21:21:52,198 session.delete_node_in_template(template_name, path) 2023-09-29T21:21:52,198 ``` 2023-09-29T21:21:52,200 #### Set Schema Template 2023-09-29T21:21:52,200 ```python 2023-09-29T21:21:52,200 session.set_schema_template(template_name, prefix_path) 2023-09-29T21:21:52,201 ``` 2023-09-29T21:21:52,202 #### Uset Schema Template 2023-09-29T21:21:52,202 ```python 2023-09-29T21:21:52,203 session.unset_schema_template(template_name, prefix_path) 2023-09-29T21:21:52,203 ``` 2023-09-29T21:21:52,204 #### Show Schema Template 2023-09-29T21:21:52,204 * Show all schema templates 2023-09-29T21:21:52,205 ```python 2023-09-29T21:21:52,205 session.show_all_templates() 2023-09-29T21:21:52,206 ``` 2023-09-29T21:21:52,206 * Count all nodes in templates 2023-09-29T21:21:52,207 ```python 2023-09-29T21:21:52,207 session.count_measurements_in_template(template_name) 2023-09-29T21:21:52,207 ``` 2023-09-29T21:21:52,208 * Judge whether the path is measurement or not in templates, This measurement must be in the template 2023-09-29T21:21:52,209 ```python 2023-09-29T21:21:52,209 session.count_measurements_in_template(template_name, path) 2023-09-29T21:21:52,210 ``` 2023-09-29T21:21:52,211 * Judge whether the path is exist or not in templates, This path may not belong to the template 2023-09-29T21:21:52,211 ```python 2023-09-29T21:21:52,212 session.is_path_exist_in_template(template_name, path) 2023-09-29T21:21:52,212 ``` 2023-09-29T21:21:52,213 * Show nodes under in schema template 2023-09-29T21:21:52,213 ```python 2023-09-29T21:21:52,214 session.show_measurements_in_template(template_name) 2023-09-29T21:21:52,214 ``` 2023-09-29T21:21:52,215 * Show the path prefix where a schema template is set 2023-09-29T21:21:52,216 ```python 2023-09-29T21:21:52,216 session.show_paths_template_set_on(template_name) 2023-09-29T21:21:52,217 ``` 2023-09-29T21:21:52,218 * Show the path prefix where a schema template is used (i.e. the time series has been created) 2023-09-29T21:21:52,218 ```python 2023-09-29T21:21:52,219 session.show_paths_template_using_on(template_name) 2023-09-29T21:21:52,219 ``` 2023-09-29T21:21:52,220 #### Drop Schema Template 2023-09-29T21:21:52,221 Delete an existing metadata template,dropping an already set template is not supported 2023-09-29T21:21:52,221 ```python 2023-09-29T21:21:52,221 session.drop_schema_template("template_python") 2023-09-29T21:21:52,222 ``` 2023-09-29T21:21:52,224 ### Pandas Support 2023-09-29T21:21:52,225 To easily transform a query result to a [Pandas Dataframe](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html) 2023-09-29T21:21:52,226 the SessionDataSet has a method `.todf()` which consumes the dataset and transforms it to a pandas dataframe. 2023-09-29T21:21:52,227 Example: 2023-09-29T21:21:52,228 ```python 2023-09-29T21:21:52,228 from iotdb.Session import Session 2023-09-29T21:21:52,229 ip = "127.0.0.1" 2023-09-29T21:21:52,229 port_ = "6667" 2023-09-29T21:21:52,230 username_ = "root" 2023-09-29T21:21:52,231 password_ = "root" 2023-09-29T21:21:52,231 session = Session(ip, port_, username_, password_) 2023-09-29T21:21:52,232 session.open(False) 2023-09-29T21:21:52,232 result = session.execute_query_statement("SELECT * FROM root.*") 2023-09-29T21:21:52,233 # Transform to Pandas Dataset 2023-09-29T21:21:52,234 df = result.todf() 2023-09-29T21:21:52,235 session.close() 2023-09-29T21:21:52,235 # Now you can work with the dataframe 2023-09-29T21:21:52,236 df = ... 2023-09-29T21:21:52,237 ``` 2023-09-29T21:21:52,238 ### IoTDB Testcontainer 2023-09-29T21:21:52,239 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. 2023-09-29T21:21:52,240 To start (and stop) an IoTDB Database in a Docker container simply do: 2023-09-29T21:21:52,241 ```python 2023-09-29T21:21:52,241 class MyTestCase(unittest.TestCase): 2023-09-29T21:21:52,242 def test_something(self): 2023-09-29T21:21:52,243 with IoTDBContainer() as c: 2023-09-29T21:21:52,244 session = Session("localhost", c.get_exposed_port(6667), "root", "root") 2023-09-29T21:21:52,244 session.open(False) 2023-09-29T21:21:52,244 result = session.execute_query_statement("SHOW TIMESERIES") 2023-09-29T21:21:52,245 print(result) 2023-09-29T21:21:52,245 session.close() 2023-09-29T21:21:52,246 ``` 2023-09-29T21:21:52,246 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. 2023-09-29T21:21:52,248 ### IoTDB DBAPI 2023-09-29T21:21:52,248 IoTDB DBAPI implements the Python DB API 2.0 specification (https://peps.python.org/pep-0249/), which defines a common 2023-09-29T21:21:52,249 interface for accessing databases in Python. 2023-09-29T21:21:52,250 #### Examples 2023-09-29T21:21:52,250 + Initialization 2023-09-29T21:21:52,251 The initialized parameters are consistent with the session part (except for the sqlalchemy_mode). 2023-09-29T21:21:52,251 ```python 2023-09-29T21:21:52,252 from iotdb.dbapi import connect 2023-09-29T21:21:52,253 ip = "127.0.0.1" 2023-09-29T21:21:52,253 port_ = "6667" 2023-09-29T21:21:52,254 username_ = "root" 2023-09-29T21:21:52,254 password_ = "root" 2023-09-29T21:21:52,255 conn = connect(ip, port_, username_, password_,fetch_size=1024,zone_id="UTC+8",sqlalchemy_mode=False) 2023-09-29T21:21:52,255 cursor = conn.cursor() 2023-09-29T21:21:52,255 ``` 2023-09-29T21:21:52,256 + simple SQL statement execution 2023-09-29T21:21:52,256 ```python 2023-09-29T21:21:52,257 cursor.execute("SELECT * FROM root.*") 2023-09-29T21:21:52,257 for row in cursor.fetchall(): 2023-09-29T21:21:52,258 print(row) 2023-09-29T21:21:52,258 ``` 2023-09-29T21:21:52,259 + execute SQL with parameter 2023-09-29T21:21:52,260 IoTDB DBAPI supports pyformat style parameters 2023-09-29T21:21:52,261 ```python 2023-09-29T21:21:52,261 cursor.execute("SELECT * FROM root.* WHERE time < %(time)s",{"time":"2017-11-01T00:08:00.000"}) 2023-09-29T21:21:52,262 for row in cursor.fetchall(): 2023-09-29T21:21:52,262 print(row) 2023-09-29T21:21:52,263 ``` 2023-09-29T21:21:52,264 + execute SQL with parameter sequences 2023-09-29T21:21:52,264 ```python 2023-09-29T21:21:52,265 seq_of_parameters = [ 2023-09-29T21:21:52,265 {"timestamp": 1, "temperature": 1}, 2023-09-29T21:21:52,266 {"timestamp": 2, "temperature": 2}, 2023-09-29T21:21:52,266 {"timestamp": 3, "temperature": 3}, 2023-09-29T21:21:52,266 {"timestamp": 4, "temperature": 4}, 2023-09-29T21:21:52,267 {"timestamp": 5, "temperature": 5}, 2023-09-29T21:21:52,267 ] 2023-09-29T21:21:52,268 sql = "insert into root.cursor(timestamp,temperature) values(%(timestamp)s,%(temperature)s)" 2023-09-29T21:21:52,268 cursor.executemany(sql,seq_of_parameters) 2023-09-29T21:21:52,269 ``` 2023-09-29T21:21:52,270 + close the connection and cursor 2023-09-29T21:21:52,270 ```python 2023-09-29T21:21:52,271 cursor.close() 2023-09-29T21:21:52,271 conn.close() 2023-09-29T21:21:52,272 ``` 2023-09-29T21:21:52,273 ### IoTDB SQLAlchemy Dialect (Experimental) 2023-09-29T21:21:52,273 The SQLAlchemy dialect of IoTDB is written to adapt to Apache Superset. 2023-09-29T21:21:52,274 This part is still being improved. 2023-09-29T21:21:52,274 Please do not use it in the production environment! 2023-09-29T21:21:52,275 #### Mapping of the metadata 2023-09-29T21:21:52,275 The data model used by SQLAlchemy is a relational data model, which describes the relationships between different entities through tables. 2023-09-29T21:21:52,276 While the data model of IoTDB is a hierarchical data model, which organizes the data through a tree structure. 2023-09-29T21:21:52,276 In order to adapt IoTDB to the dialect of SQLAlchemy, the original data model in IoTDB needs to be reorganized. 2023-09-29T21:21:52,277 Converting the data model of IoTDB into the data model of SQLAlchemy. 2023-09-29T21:21:52,278 The metadata in the IoTDB are: 2023-09-29T21:21:52,279 1. Database 2023-09-29T21:21:52,279 2. Path 2023-09-29T21:21:52,279 3. Entity 2023-09-29T21:21:52,280 4. Measurement 2023-09-29T21:21:52,281 The metadata in the SQLAlchemy are: 2023-09-29T21:21:52,281 1. Schema 2023-09-29T21:21:52,281 2. Table 2023-09-29T21:21:52,282 3. Column 2023-09-29T21:21:52,283 The mapping relationship between them is: 2023-09-29T21:21:52,283 | The metadata in the SQLAlchemy | The metadata in the IoTDB | 2023-09-29T21:21:52,284 | -------------------- | ---------------------------------------------- | 2023-09-29T21:21:52,284 | Schema | Database | 2023-09-29T21:21:52,285 | Table | Path ( from database to entity ) + Entity | 2023-09-29T21:21:52,285 | Column | Measurement | 2023-09-29T21:21:52,286 The following figure shows the relationship between the two more intuitively: 2023-09-29T21:21:52,287 ![sqlalchemy-to-iotdb](https://github.com/apache/iotdb-bin-resources/blob/main/docs/UserGuide/API/IoTDB-SQLAlchemy/sqlalchemy-to-iotdb.png?raw=true) 2023-09-29T21:21:52,288 #### Data type mapping 2023-09-29T21:21:52,288 | data type in IoTDB | data type in SQLAlchemy | 2023-09-29T21:21:52,289 |--------------------|-------------------------| 2023-09-29T21:21:52,289 | BOOLEAN | Boolean | 2023-09-29T21:21:52,289 | INT32 | Integer | 2023-09-29T21:21:52,290 | INT64 | BigInteger | 2023-09-29T21:21:52,290 | FLOAT | Float | 2023-09-29T21:21:52,291 | DOUBLE | Float | 2023-09-29T21:21:52,291 | TEXT | Text | 2023-09-29T21:21:52,292 | LONG | BigInteger | 2023-09-29T21:21:52,292 #### Example 2023-09-29T21:21:52,293 + execute statement 2023-09-29T21:21:52,294 ```python 2023-09-29T21:21:52,295 from sqlalchemy import create_engine 2023-09-29T21:21:52,296 engine = create_engine("iotdb://root:root@127.0.0.1:6667") 2023-09-29T21:21:52,296 connect = engine.connect() 2023-09-29T21:21:52,297 result = connect.execute("SELECT ** FROM root") 2023-09-29T21:21:52,297 for row in result.fetchall(): 2023-09-29T21:21:52,298 print(row) 2023-09-29T21:21:52,298 ``` 2023-09-29T21:21:52,299 + ORM (now only simple queries are supported) 2023-09-29T21:21:52,300 ```python 2023-09-29T21:21:52,301 from sqlalchemy import create_engine, Column, Float, BigInteger, MetaData 2023-09-29T21:21:52,301 from sqlalchemy.ext.declarative import declarative_base 2023-09-29T21:21:52,302 from sqlalchemy.orm import sessionmaker 2023-09-29T21:21:52,303 metadata = MetaData( 2023-09-29T21:21:52,303 schema='root.factory' 2023-09-29T21:21:52,304 ) 2023-09-29T21:21:52,304 Base = declarative_base(metadata=metadata) 2023-09-29T21:21:52,306 class Device(Base): 2023-09-29T21:21:52,306 __tablename__ = "room2.device1" 2023-09-29T21:21:52,307 Time = Column(BigInteger, primary_key=True) 2023-09-29T21:21:52,307 temperature = Column(Float) 2023-09-29T21:21:52,308 status = Column(Float) 2023-09-29T21:21:52,309 engine = create_engine("iotdb://root:root@127.0.0.1:6667") 2023-09-29T21:21:52,310 DbSession = sessionmaker(bind=engine) 2023-09-29T21:21:52,311 session = DbSession() 2023-09-29T21:21:52,312 res = session.query(Device.status).filter(Device.temperature > 1) 2023-09-29T21:21:52,313 for row in res: 2023-09-29T21:21:52,314 print(row) 2023-09-29T21:21:52,314 ``` 2023-09-29T21:21:52,315 ## Developers 2023-09-29T21:21:52,316 ### Introduction 2023-09-29T21:21:52,318 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. 2023-09-29T21:21:52,320 ### Prerequisites 2023-09-29T21:21:52,321 Python3.7 or later is preferred. 2023-09-29T21:21:52,321 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. 2023-09-29T21:21:52,322 ``` 2023-09-29T21:21:52,322 http://thrift.apache.org/docs/install/ 2023-09-29T21:21:52,323 ``` 2023-09-29T21:21:52,324 Before starting you need to install `requirements_dev.txt` in your python environment, e.g. by calling 2023-09-29T21:21:52,324 ```shell 2023-09-29T21:21:52,324 pip install -r requirements_dev.txt 2023-09-29T21:21:52,325 ``` 2023-09-29T21:21:52,326 ### Compile the thrift library and Debug 2023-09-29T21:21:52,327 In the root of IoTDB's source code folder, run `mvn clean generate-sources -pl client-py -am`. 2023-09-29T21:21:52,328 This will automatically delete and repopulate the folder `iotdb/thrift` with the generated thrift files. 2023-09-29T21:21:52,329 This folder is ignored from git and should **never be pushed to git!** 2023-09-29T21:21:52,329 **Notice** Do not upload `iotdb/thrift` to the git repo. 2023-09-29T21:21:52,332 ### Session Client & Example 2023-09-29T21:21:52,332 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. 2023-09-29T21:21:52,334 Or, another simple example: 2023-09-29T21:21:52,335 ```python 2023-09-29T21:21:52,335 from iotdb.Session import Session 2023-09-29T21:21:52,336 ip = "127.0.0.1" 2023-09-29T21:21:52,336 port_ = "6667" 2023-09-29T21:21:52,337 username_ = "root" 2023-09-29T21:21:52,337 password_ = "root" 2023-09-29T21:21:52,338 session = Session(ip, port_, username_, password_) 2023-09-29T21:21:52,338 session.open(False) 2023-09-29T21:21:52,339 zone = session.get_time_zone() 2023-09-29T21:21:52,339 session.close() 2023-09-29T21:21:52,339 ``` 2023-09-29T21:21:52,341 ### Tests 2023-09-29T21:21:52,342 Please add your custom tests in `tests` folder. 2023-09-29T21:21:52,343 To run all defined tests just type `pytest .` in the root folder. 2023-09-29T21:21:52,344 **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). 2023-09-29T21:21:52,346 ### Futher Tools 2023-09-29T21:21:52,347 [black](https://pypi.org/project/black/) and [flake8](https://pypi.org/project/flake8/) are installed for autoformatting and linting. 2023-09-29T21:21:52,348 Both can be run by `black .` or `flake8 .` respectively. 2023-09-29T21:21:52,350 ## Releasing 2023-09-29T21:21:52,351 To do a release just ensure that you have the right set of generated thrift files. 2023-09-29T21:21:52,351 Then run linting and auto-formatting. 2023-09-29T21:21:52,352 Then, ensure that all tests work (via `pytest .`). 2023-09-29T21:21:52,352 Then you are good to go to do a release! 2023-09-29T21:21:52,354 ### Preparing your environment 2023-09-29T21:21:52,355 First, install all necessary dev dependencies via `pip install -r requirements_dev.txt`. 2023-09-29T21:21:52,360 ### Doing the Release 2023-09-29T21:21:52,361 There is a convenient script `release.sh` to do all steps for a release. 2023-09-29T21:21:52,362 Namely, these are 2023-09-29T21:21:52,363 * Remove all transient directories from last release (if exists) 2023-09-29T21:21:52,363 * (Re-)generate all generated sources via mvn 2023-09-29T21:21:52,364 * Run Linting (flake8) 2023-09-29T21:21:52,365 * Run Tests via pytest 2023-09-29T21:21:52,365 * Build 2023-09-29T21:21:52,366 * Release to pypi 2023-09-29T21:21:52,369 /tmp/pip-build-env-_gufnjd1/overlay/local/lib/python3.11/dist-packages/setuptools/_distutils/dist.py:265: UserWarning: Unknown distribution option: 'website' 2023-09-29T21:21:52,370 warnings.warn(msg) 2023-09-29T21:21:52,371 running bdist_wheel 2023-09-29T21:21:52,372 running build 2023-09-29T21:21:52,372 running build_py 2023-09-29T21:21:52,372 creating build 2023-09-29T21:21:52,373 creating build/lib 2023-09-29T21:21:52,373 creating build/lib/iotdb 2023-09-29T21:21:52,373 copying iotdb/SessionPool.py -> build/lib/iotdb 2023-09-29T21:21:52,374 copying iotdb/Session.py -> build/lib/iotdb 2023-09-29T21:21:52,374 copying iotdb/__init__.py -> build/lib/iotdb 2023-09-29T21:21:52,375 copying iotdb/IoTDBContainer.py -> build/lib/iotdb 2023-09-29T21:21:52,375 creating build/lib/tests 2023-09-29T21:21:52,375 copying tests/test_one_device.py -> build/lib/tests 2023-09-29T21:21:52,376 copying tests/test_tablet.py -> build/lib/tests 2023-09-29T21:21:52,377 copying tests/test_todf.py -> build/lib/tests 2023-09-29T21:21:52,378 copying tests/__init__.py -> build/lib/tests 2023-09-29T21:21:52,378 copying tests/test_template.py -> build/lib/tests 2023-09-29T21:21:52,378 copying tests/test_aligned_timeseries.py -> build/lib/tests 2023-09-29T21:21:52,379 copying tests/test_delete_data.py -> build/lib/tests 2023-09-29T21:21:52,379 copying tests/tablet_performance_comparison.py -> build/lib/tests 2023-09-29T21:21:52,380 copying tests/test_session.py -> build/lib/tests 2023-09-29T21:21:52,380 copying tests/test_dataframe.py -> build/lib/tests 2023-09-29T21:21:52,381 copying tests/test_session_pool.py -> build/lib/tests 2023-09-29T21:21:52,382 copying tests/test_numpy_tablet.py -> build/lib/tests 2023-09-29T21:21:52,382 creating build/lib/iotdb/dbapi 2023-09-29T21:21:52,382 copying iotdb/dbapi/Cursor.py -> build/lib/iotdb/dbapi 2023-09-29T21:21:52,383 copying iotdb/dbapi/Connection.py -> build/lib/iotdb/dbapi 2023-09-29T21:21:52,383 copying iotdb/dbapi/Exceptions.py -> build/lib/iotdb/dbapi 2023-09-29T21:21:52,384 copying iotdb/dbapi/__init__.py -> build/lib/iotdb/dbapi 2023-09-29T21:21:52,384 creating build/lib/iotdb/tsfile 2023-09-29T21:21:52,385 copying iotdb/tsfile/__init__.py -> build/lib/iotdb/tsfile 2023-09-29T21:21:52,385 creating build/lib/iotdb/utils 2023-09-29T21:21:52,386 copying iotdb/utils/Tablet.py -> build/lib/iotdb/utils 2023-09-29T21:21:52,387 copying iotdb/utils/IoTDBConstants.py -> build/lib/iotdb/utils 2023-09-29T21:21:52,387 copying iotdb/utils/Field.py -> build/lib/iotdb/utils 2023-09-29T21:21:52,388 copying iotdb/utils/NumpyTablet.py -> build/lib/iotdb/utils 2023-09-29T21:21:52,388 copying iotdb/utils/RowRecord.py -> build/lib/iotdb/utils 2023-09-29T21:21:52,389 copying iotdb/utils/__init__.py -> build/lib/iotdb/utils 2023-09-29T21:21:52,390 copying iotdb/utils/IoTDBConnectionException.py -> build/lib/iotdb/utils 2023-09-29T21:21:52,390 copying iotdb/utils/BitMap.py -> build/lib/iotdb/utils 2023-09-29T21:21:52,391 copying iotdb/utils/IoTDBRpcDataSet.py -> build/lib/iotdb/utils 2023-09-29T21:21:52,392 copying iotdb/utils/SessionDataSet.py -> build/lib/iotdb/utils 2023-09-29T21:21:52,392 creating build/lib/iotdb/template 2023-09-29T21:21:52,393 copying iotdb/template/TemplateQueryType.py -> build/lib/iotdb/template 2023-09-29T21:21:52,393 copying iotdb/template/Template.py -> build/lib/iotdb/template 2023-09-29T21:21:52,394 copying iotdb/template/__init__.py -> build/lib/iotdb/template 2023-09-29T21:21:52,395 copying iotdb/template/InternalNode.py -> build/lib/iotdb/template 2023-09-29T21:21:52,395 copying iotdb/template/MeasurementNode.py -> build/lib/iotdb/template 2023-09-29T21:21:52,396 copying iotdb/template/TemplateNode.py -> build/lib/iotdb/template 2023-09-29T21:21:52,396 creating build/lib/iotdb/sqlalchemy 2023-09-29T21:21:52,397 copying iotdb/sqlalchemy/IoTDBDialect.py -> build/lib/iotdb/sqlalchemy 2023-09-29T21:21:52,398 copying iotdb/sqlalchemy/IoTDBTypeCompiler.py -> build/lib/iotdb/sqlalchemy 2023-09-29T21:21:52,398 copying iotdb/sqlalchemy/__init__.py -> build/lib/iotdb/sqlalchemy 2023-09-29T21:21:52,399 copying iotdb/sqlalchemy/IoTDBSQLCompiler.py -> build/lib/iotdb/sqlalchemy 2023-09-29T21:21:52,399 copying iotdb/sqlalchemy/IoTDBIdentifierPreparer.py -> build/lib/iotdb/sqlalchemy 2023-09-29T21:21:52,400 creating build/lib/iotdb/thrift 2023-09-29T21:21:52,400 copying iotdb/thrift/__init__.py -> build/lib/iotdb/thrift 2023-09-29T21:21:52,401 creating build/lib/iotdb/dbapi/tests 2023-09-29T21:21:52,401 copying iotdb/dbapi/tests/__init__.py -> build/lib/iotdb/dbapi/tests 2023-09-29T21:21:52,402 copying iotdb/dbapi/tests/test_cursor.py -> build/lib/iotdb/dbapi/tests 2023-09-29T21:21:52,402 copying iotdb/dbapi/tests/test_connection.py -> build/lib/iotdb/dbapi/tests 2023-09-29T21:21:52,402 creating build/lib/iotdb/tsfile/utils 2023-09-29T21:21:52,403 copying iotdb/tsfile/utils/__init__.py -> build/lib/iotdb/tsfile/utils 2023-09-29T21:21:52,403 copying iotdb/tsfile/utils/ReadWriteIOUtils.py -> build/lib/iotdb/tsfile/utils 2023-09-29T21:21:52,403 copying iotdb/tsfile/utils/Pair.py -> build/lib/iotdb/tsfile/utils 2023-09-29T21:21:52,404 creating build/lib/iotdb/tsfile/common 2023-09-29T21:21:52,404 copying iotdb/tsfile/common/__init__.py -> build/lib/iotdb/tsfile/common 2023-09-29T21:21:52,405 creating build/lib/iotdb/tsfile/common/constant 2023-09-29T21:21:52,405 copying iotdb/tsfile/common/constant/__init__.py -> build/lib/iotdb/tsfile/common/constant 2023-09-29T21:21:52,405 copying iotdb/tsfile/common/constant/TsFileConstant.py -> build/lib/iotdb/tsfile/common/constant 2023-09-29T21:21:52,406 creating build/lib/iotdb/sqlalchemy/tests 2023-09-29T21:21:52,406 copying iotdb/sqlalchemy/tests/__init__.py -> build/lib/iotdb/sqlalchemy/tests 2023-09-29T21:21:52,407 copying iotdb/sqlalchemy/tests/test_dialect.py -> build/lib/iotdb/sqlalchemy/tests 2023-09-29T21:21:52,407 creating build/lib/iotdb/thrift/rpc 2023-09-29T21:21:52,407 copying iotdb/thrift/rpc/__init__.py -> build/lib/iotdb/thrift/rpc 2023-09-29T21:21:52,408 copying iotdb/thrift/rpc/IClientRPCService.py -> build/lib/iotdb/thrift/rpc 2023-09-29T21:21:52,409 copying iotdb/thrift/rpc/constants.py -> build/lib/iotdb/thrift/rpc 2023-09-29T21:21:52,409 copying iotdb/thrift/rpc/ttypes.py -> build/lib/iotdb/thrift/rpc 2023-09-29T21:21:52,410 creating build/lib/iotdb/thrift/common 2023-09-29T21:21:52,410 copying iotdb/thrift/common/__init__.py -> build/lib/iotdb/thrift/common 2023-09-29T21:21:52,411 copying iotdb/thrift/common/constants.py -> build/lib/iotdb/thrift/common 2023-09-29T21:21:52,412 copying iotdb/thrift/common/ttypes.py -> build/lib/iotdb/thrift/common 2023-09-29T21:21:52,412 installing to build/bdist.linux-armv7l/wheel 2023-09-29T21:21:52,413 running install 2023-09-29T21:21:52,425 running install_lib 2023-09-29T21:21:52,432 creating build/bdist.linux-armv7l 2023-09-29T21:21:52,433 creating build/bdist.linux-armv7l/wheel 2023-09-29T21:21:52,434 creating build/bdist.linux-armv7l/wheel/iotdb 2023-09-29T21:21:52,435 copying build/lib/iotdb/SessionPool.py -> build/bdist.linux-armv7l/wheel/iotdb 2023-09-29T21:21:52,438 creating build/bdist.linux-armv7l/wheel/iotdb/dbapi 2023-09-29T21:21:52,439 copying build/lib/iotdb/dbapi/Cursor.py -> build/bdist.linux-armv7l/wheel/iotdb/dbapi 2023-09-29T21:21:52,441 creating build/bdist.linux-armv7l/wheel/iotdb/dbapi/tests 2023-09-29T21:21:52,442 copying build/lib/iotdb/dbapi/tests/__init__.py -> build/bdist.linux-armv7l/wheel/iotdb/dbapi/tests 2023-09-29T21:21:52,444 copying build/lib/iotdb/dbapi/tests/test_cursor.py -> build/bdist.linux-armv7l/wheel/iotdb/dbapi/tests 2023-09-29T21:21:52,446 copying build/lib/iotdb/dbapi/tests/test_connection.py -> build/bdist.linux-armv7l/wheel/iotdb/dbapi/tests 2023-09-29T21:21:52,448 copying build/lib/iotdb/dbapi/Connection.py -> build/bdist.linux-armv7l/wheel/iotdb/dbapi 2023-09-29T21:21:52,450 copying build/lib/iotdb/dbapi/Exceptions.py -> build/bdist.linux-armv7l/wheel/iotdb/dbapi 2023-09-29T21:21:52,452 copying build/lib/iotdb/dbapi/__init__.py -> build/bdist.linux-armv7l/wheel/iotdb/dbapi 2023-09-29T21:21:52,454 creating build/bdist.linux-armv7l/wheel/iotdb/tsfile 2023-09-29T21:21:52,455 copying build/lib/iotdb/tsfile/__init__.py -> build/bdist.linux-armv7l/wheel/iotdb/tsfile 2023-09-29T21:21:52,457 creating build/bdist.linux-armv7l/wheel/iotdb/tsfile/utils 2023-09-29T21:21:52,458 copying build/lib/iotdb/tsfile/utils/__init__.py -> build/bdist.linux-armv7l/wheel/iotdb/tsfile/utils 2023-09-29T21:21:52,460 copying build/lib/iotdb/tsfile/utils/ReadWriteIOUtils.py -> build/bdist.linux-armv7l/wheel/iotdb/tsfile/utils 2023-09-29T21:21:52,461 copying build/lib/iotdb/tsfile/utils/Pair.py -> build/bdist.linux-armv7l/wheel/iotdb/tsfile/utils 2023-09-29T21:21:52,463 creating build/bdist.linux-armv7l/wheel/iotdb/tsfile/common 2023-09-29T21:21:52,464 copying build/lib/iotdb/tsfile/common/__init__.py -> build/bdist.linux-armv7l/wheel/iotdb/tsfile/common 2023-09-29T21:21:52,467 creating build/bdist.linux-armv7l/wheel/iotdb/tsfile/common/constant 2023-09-29T21:21:52,467 copying build/lib/iotdb/tsfile/common/constant/__init__.py -> build/bdist.linux-armv7l/wheel/iotdb/tsfile/common/constant 2023-09-29T21:21:52,469 copying build/lib/iotdb/tsfile/common/constant/TsFileConstant.py -> build/bdist.linux-armv7l/wheel/iotdb/tsfile/common/constant 2023-09-29T21:21:52,471 copying build/lib/iotdb/Session.py -> build/bdist.linux-armv7l/wheel/iotdb 2023-09-29T21:21:52,474 copying build/lib/iotdb/__init__.py -> build/bdist.linux-armv7l/wheel/iotdb 2023-09-29T21:21:52,476 creating build/bdist.linux-armv7l/wheel/iotdb/utils 2023-09-29T21:21:52,477 copying build/lib/iotdb/utils/Tablet.py -> build/bdist.linux-armv7l/wheel/iotdb/utils 2023-09-29T21:21:52,479 copying build/lib/iotdb/utils/IoTDBConstants.py -> build/bdist.linux-armv7l/wheel/iotdb/utils 2023-09-29T21:21:52,481 copying build/lib/iotdb/utils/Field.py -> build/bdist.linux-armv7l/wheel/iotdb/utils 2023-09-29T21:21:52,483 copying build/lib/iotdb/utils/NumpyTablet.py -> build/bdist.linux-armv7l/wheel/iotdb/utils 2023-09-29T21:21:52,486 copying build/lib/iotdb/utils/RowRecord.py -> build/bdist.linux-armv7l/wheel/iotdb/utils 2023-09-29T21:21:52,488 copying build/lib/iotdb/utils/__init__.py -> build/bdist.linux-armv7l/wheel/iotdb/utils 2023-09-29T21:21:52,489 copying build/lib/iotdb/utils/IoTDBConnectionException.py -> build/bdist.linux-armv7l/wheel/iotdb/utils 2023-09-29T21:21:52,491 copying build/lib/iotdb/utils/BitMap.py -> build/bdist.linux-armv7l/wheel/iotdb/utils 2023-09-29T21:21:52,493 copying build/lib/iotdb/utils/IoTDBRpcDataSet.py -> build/bdist.linux-armv7l/wheel/iotdb/utils 2023-09-29T21:21:52,495 copying build/lib/iotdb/utils/SessionDataSet.py -> build/bdist.linux-armv7l/wheel/iotdb/utils 2023-09-29T21:21:52,497 copying build/lib/iotdb/IoTDBContainer.py -> build/bdist.linux-armv7l/wheel/iotdb 2023-09-29T21:21:52,499 creating build/bdist.linux-armv7l/wheel/iotdb/template 2023-09-29T21:21:52,500 copying build/lib/iotdb/template/TemplateQueryType.py -> build/bdist.linux-armv7l/wheel/iotdb/template 2023-09-29T21:21:52,502 copying build/lib/iotdb/template/Template.py -> build/bdist.linux-armv7l/wheel/iotdb/template 2023-09-29T21:21:52,504 copying build/lib/iotdb/template/__init__.py -> build/bdist.linux-armv7l/wheel/iotdb/template 2023-09-29T21:21:52,506 copying build/lib/iotdb/template/InternalNode.py -> build/bdist.linux-armv7l/wheel/iotdb/template 2023-09-29T21:21:52,507 copying build/lib/iotdb/template/MeasurementNode.py -> build/bdist.linux-armv7l/wheel/iotdb/template 2023-09-29T21:21:52,509 copying build/lib/iotdb/template/TemplateNode.py -> build/bdist.linux-armv7l/wheel/iotdb/template 2023-09-29T21:21:52,512 creating build/bdist.linux-armv7l/wheel/iotdb/sqlalchemy 2023-09-29T21:21:52,513 copying build/lib/iotdb/sqlalchemy/IoTDBDialect.py -> build/bdist.linux-armv7l/wheel/iotdb/sqlalchemy 2023-09-29T21:21:52,515 copying build/lib/iotdb/sqlalchemy/IoTDBTypeCompiler.py -> build/bdist.linux-armv7l/wheel/iotdb/sqlalchemy 2023-09-29T21:21:52,517 creating build/bdist.linux-armv7l/wheel/iotdb/sqlalchemy/tests 2023-09-29T21:21:52,518 copying build/lib/iotdb/sqlalchemy/tests/__init__.py -> build/bdist.linux-armv7l/wheel/iotdb/sqlalchemy/tests 2023-09-29T21:21:52,520 copying build/lib/iotdb/sqlalchemy/tests/test_dialect.py -> build/bdist.linux-armv7l/wheel/iotdb/sqlalchemy/tests 2023-09-29T21:21:52,522 copying build/lib/iotdb/sqlalchemy/__init__.py -> build/bdist.linux-armv7l/wheel/iotdb/sqlalchemy 2023-09-29T21:21:52,523 copying build/lib/iotdb/sqlalchemy/IoTDBSQLCompiler.py -> build/bdist.linux-armv7l/wheel/iotdb/sqlalchemy 2023-09-29T21:21:52,525 copying build/lib/iotdb/sqlalchemy/IoTDBIdentifierPreparer.py -> build/bdist.linux-armv7l/wheel/iotdb/sqlalchemy 2023-09-29T21:21:52,528 creating build/bdist.linux-armv7l/wheel/iotdb/thrift 2023-09-29T21:21:52,529 creating build/bdist.linux-armv7l/wheel/iotdb/thrift/rpc 2023-09-29T21:21:52,530 copying build/lib/iotdb/thrift/rpc/__init__.py -> build/bdist.linux-armv7l/wheel/iotdb/thrift/rpc 2023-09-29T21:21:52,532 copying build/lib/iotdb/thrift/rpc/IClientRPCService.py -> build/bdist.linux-armv7l/wheel/iotdb/thrift/rpc 2023-09-29T21:21:52,540 copying build/lib/iotdb/thrift/rpc/constants.py -> build/bdist.linux-armv7l/wheel/iotdb/thrift/rpc 2023-09-29T21:21:52,542 copying build/lib/iotdb/thrift/rpc/ttypes.py -> build/bdist.linux-armv7l/wheel/iotdb/thrift/rpc 2023-09-29T21:21:52,549 copying build/lib/iotdb/thrift/__init__.py -> build/bdist.linux-armv7l/wheel/iotdb/thrift 2023-09-29T21:21:52,551 creating build/bdist.linux-armv7l/wheel/iotdb/thrift/common 2023-09-29T21:21:52,552 copying build/lib/iotdb/thrift/common/__init__.py -> build/bdist.linux-armv7l/wheel/iotdb/thrift/common 2023-09-29T21:21:52,554 copying build/lib/iotdb/thrift/common/constants.py -> build/bdist.linux-armv7l/wheel/iotdb/thrift/common 2023-09-29T21:21:52,556 copying build/lib/iotdb/thrift/common/ttypes.py -> build/bdist.linux-armv7l/wheel/iotdb/thrift/common 2023-09-29T21:21:52,560 creating build/bdist.linux-armv7l/wheel/tests 2023-09-29T21:21:52,561 copying build/lib/tests/test_one_device.py -> build/bdist.linux-armv7l/wheel/tests 2023-09-29T21:21:52,563 copying build/lib/tests/test_tablet.py -> build/bdist.linux-armv7l/wheel/tests 2023-09-29T21:21:52,566 copying build/lib/tests/test_todf.py -> build/bdist.linux-armv7l/wheel/tests 2023-09-29T21:21:52,568 copying build/lib/tests/__init__.py -> build/bdist.linux-armv7l/wheel/tests 2023-09-29T21:21:52,570 copying build/lib/tests/test_template.py -> build/bdist.linux-armv7l/wheel/tests 2023-09-29T21:21:52,572 copying build/lib/tests/test_aligned_timeseries.py -> build/bdist.linux-armv7l/wheel/tests 2023-09-29T21:21:52,574 copying build/lib/tests/test_delete_data.py -> build/bdist.linux-armv7l/wheel/tests 2023-09-29T21:21:52,577 copying build/lib/tests/tablet_performance_comparison.py -> build/bdist.linux-armv7l/wheel/tests 2023-09-29T21:21:52,579 copying build/lib/tests/test_session.py -> build/bdist.linux-armv7l/wheel/tests 2023-09-29T21:21:52,582 copying build/lib/tests/test_dataframe.py -> build/bdist.linux-armv7l/wheel/tests 2023-09-29T21:21:52,584 copying build/lib/tests/test_session_pool.py -> build/bdist.linux-armv7l/wheel/tests 2023-09-29T21:21:52,586 copying build/lib/tests/test_numpy_tablet.py -> build/bdist.linux-armv7l/wheel/tests 2023-09-29T21:21:52,588 running install_egg_info 2023-09-29T21:21:52,599 running egg_info 2023-09-29T21:21:52,604 writing apache_iotdb.egg-info/PKG-INFO 2023-09-29T21:21:52,608 writing dependency_links to apache_iotdb.egg-info/dependency_links.txt 2023-09-29T21:21:52,609 writing entry points to apache_iotdb.egg-info/entry_points.txt 2023-09-29T21:21:52,611 writing requirements to apache_iotdb.egg-info/requires.txt 2023-09-29T21:21:52,612 writing top-level names to apache_iotdb.egg-info/top_level.txt 2023-09-29T21:21:52,626 reading manifest file 'apache_iotdb.egg-info/SOURCES.txt' 2023-09-29T21:21:52,634 writing manifest file 'apache_iotdb.egg-info/SOURCES.txt' 2023-09-29T21:21:52,636 Copying apache_iotdb.egg-info to build/bdist.linux-armv7l/wheel/apache_iotdb-1.2.1-py3.11.egg-info 2023-09-29T21:21:52,648 running install_scripts 2023-09-29T21:21:52,666 creating build/bdist.linux-armv7l/wheel/apache_iotdb-1.2.1.dist-info/WHEEL 2023-09-29T21:21:52,669 creating '/tmp/pip-wheel-wby14tsg/.tmp-ikhyfygn/apache_iotdb-1.2.1-py3-none-any.whl' and adding 'build/bdist.linux-armv7l/wheel' to it 2023-09-29T21:21:52,672 adding 'iotdb/IoTDBContainer.py' 2023-09-29T21:21:52,680 adding 'iotdb/Session.py' 2023-09-29T21:21:52,682 adding 'iotdb/SessionPool.py' 2023-09-29T21:21:52,684 adding 'iotdb/__init__.py' 2023-09-29T21:21:52,687 adding 'iotdb/dbapi/Connection.py' 2023-09-29T21:21:52,689 adding 'iotdb/dbapi/Cursor.py' 2023-09-29T21:21:52,691 adding 'iotdb/dbapi/Exceptions.py' 2023-09-29T21:21:52,693 adding 'iotdb/dbapi/__init__.py' 2023-09-29T21:21:52,695 adding 'iotdb/dbapi/tests/__init__.py' 2023-09-29T21:21:52,696 adding 'iotdb/dbapi/tests/test_connection.py' 2023-09-29T21:21:52,698 adding 'iotdb/dbapi/tests/test_cursor.py' 2023-09-29T21:21:52,701 adding 'iotdb/sqlalchemy/IoTDBDialect.py' 2023-09-29T21:21:52,702 adding 'iotdb/sqlalchemy/IoTDBIdentifierPreparer.py' 2023-09-29T21:21:52,705 adding 'iotdb/sqlalchemy/IoTDBSQLCompiler.py' 2023-09-29T21:21:52,707 adding 'iotdb/sqlalchemy/IoTDBTypeCompiler.py' 2023-09-29T21:21:52,708 adding 'iotdb/sqlalchemy/__init__.py' 2023-09-29T21:21:52,710 adding 'iotdb/sqlalchemy/tests/__init__.py' 2023-09-29T21:21:52,712 adding 'iotdb/sqlalchemy/tests/test_dialect.py' 2023-09-29T21:21:52,714 adding 'iotdb/template/InternalNode.py' 2023-09-29T21:21:52,716 adding 'iotdb/template/MeasurementNode.py' 2023-09-29T21:21:52,717 adding 'iotdb/template/Template.py' 2023-09-29T21:21:52,719 adding 'iotdb/template/TemplateNode.py' 2023-09-29T21:21:52,720 adding 'iotdb/template/TemplateQueryType.py' 2023-09-29T21:21:52,722 adding 'iotdb/template/__init__.py' 2023-09-29T21:21:52,723 adding 'iotdb/thrift/__init__.py' 2023-09-29T21:21:52,725 adding 'iotdb/thrift/common/__init__.py' 2023-09-29T21:21:52,726 adding 'iotdb/thrift/common/constants.py' 2023-09-29T21:21:52,731 adding 'iotdb/thrift/common/ttypes.py' 2023-09-29T21:21:52,745 adding 'iotdb/thrift/rpc/IClientRPCService.py' 2023-09-29T21:21:52,749 adding 'iotdb/thrift/rpc/__init__.py' 2023-09-29T21:21:52,751 adding 'iotdb/thrift/rpc/constants.py' 2023-09-29T21:21:52,764 adding 'iotdb/thrift/rpc/ttypes.py' 2023-09-29T21:21:52,768 adding 'iotdb/tsfile/__init__.py' 2023-09-29T21:21:52,769 adding 'iotdb/tsfile/common/__init__.py' 2023-09-29T21:21:52,771 adding 'iotdb/tsfile/common/constant/TsFileConstant.py' 2023-09-29T21:21:52,772 adding 'iotdb/tsfile/common/constant/__init__.py' 2023-09-29T21:21:52,774 adding 'iotdb/tsfile/utils/Pair.py' 2023-09-29T21:21:52,775 adding 'iotdb/tsfile/utils/ReadWriteIOUtils.py' 2023-09-29T21:21:52,776 adding 'iotdb/tsfile/utils/__init__.py' 2023-09-29T21:21:52,778 adding 'iotdb/utils/BitMap.py' 2023-09-29T21:21:52,780 adding 'iotdb/utils/Field.py' 2023-09-29T21:21:52,781 adding 'iotdb/utils/IoTDBConnectionException.py' 2023-09-29T21:21:52,782 adding 'iotdb/utils/IoTDBConstants.py' 2023-09-29T21:21:52,784 adding 'iotdb/utils/IoTDBRpcDataSet.py' 2023-09-29T21:21:52,786 adding 'iotdb/utils/NumpyTablet.py' 2023-09-29T21:21:52,787 adding 'iotdb/utils/RowRecord.py' 2023-09-29T21:21:52,789 adding 'iotdb/utils/SessionDataSet.py' 2023-09-29T21:21:52,790 adding 'iotdb/utils/Tablet.py' 2023-09-29T21:21:52,792 adding 'iotdb/utils/__init__.py' 2023-09-29T21:21:52,794 adding 'tests/__init__.py' 2023-09-29T21:21:52,796 adding 'tests/tablet_performance_comparison.py' 2023-09-29T21:21:52,797 adding 'tests/test_aligned_timeseries.py' 2023-09-29T21:21:52,799 adding 'tests/test_dataframe.py' 2023-09-29T21:21:52,800 adding 'tests/test_delete_data.py' 2023-09-29T21:21:52,802 adding 'tests/test_numpy_tablet.py' 2023-09-29T21:21:52,803 adding 'tests/test_one_device.py' 2023-09-29T21:21:52,805 adding 'tests/test_session.py' 2023-09-29T21:21:52,806 adding 'tests/test_session_pool.py' 2023-09-29T21:21:52,808 adding 'tests/test_tablet.py' 2023-09-29T21:21:52,809 adding 'tests/test_template.py' 2023-09-29T21:21:52,810 adding 'tests/test_todf.py' 2023-09-29T21:21:52,813 adding 'apache_iotdb-1.2.1.dist-info/METADATA' 2023-09-29T21:21:52,814 adding 'apache_iotdb-1.2.1.dist-info/WHEEL' 2023-09-29T21:21:52,815 adding 'apache_iotdb-1.2.1.dist-info/entry_points.txt' 2023-09-29T21:21:52,816 adding 'apache_iotdb-1.2.1.dist-info/top_level.txt' 2023-09-29T21:21:52,817 adding 'apache_iotdb-1.2.1.dist-info/RECORD' 2023-09-29T21:21:52,821 removing build/bdist.linux-armv7l/wheel 2023-09-29T21:21:52,930 Building wheel for apache-iotdb (pyproject.toml): finished with status 'done' 2023-09-29T21:21:52,937 Created wheel for apache-iotdb: filename=apache_iotdb-1.2.1-py3-none-any.whl size=127496 sha256=23c4b520884e408c124527f709ba7d5c14e606dec0ea24e8a8ff33d2098c849a 2023-09-29T21:21:52,939 Stored in directory: /tmp/pip-ephem-wheel-cache-zmt4q7vq/wheels/59/ca/8c/cfde113552ef664886e48cf9d5c35381a964fec4044b486357 2023-09-29T21:21:52,954 Successfully built apache-iotdb 2023-09-29T21:21:52,961 Removed build tracker: '/tmp/pip-build-tracker-3je7a8fk'