2023-07-28T10:58:00,085 Created temporary directory: /tmp/pip-build-tracker-xkvwt5eb 2023-07-28T10:58:00,088 Initialized build tracking at /tmp/pip-build-tracker-xkvwt5eb 2023-07-28T10:58:00,089 Created build tracker: /tmp/pip-build-tracker-xkvwt5eb 2023-07-28T10:58:00,089 Entered build tracker: /tmp/pip-build-tracker-xkvwt5eb 2023-07-28T10:58:00,091 Created temporary directory: /tmp/pip-wheel-a5k7t_ek 2023-07-28T10:58:00,099 Created temporary directory: /tmp/pip-ephem-wheel-cache-5fv45ezk 2023-07-28T10:58:00,154 Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple 2023-07-28T10:58:00,162 2 location(s) to search for versions of apache-iotdb: 2023-07-28T10:58:00,162 * https://pypi.org/simple/apache-iotdb/ 2023-07-28T10:58:00,162 * https://www.piwheels.org/simple/apache-iotdb/ 2023-07-28T10:58:00,163 Fetching project page and analyzing links: https://pypi.org/simple/apache-iotdb/ 2023-07-28T10:58:00,164 Getting page https://pypi.org/simple/apache-iotdb/ 2023-07-28T10:58:00,169 Found index url https://pypi.org/simple/ 2023-07-28T10:58:00,355 Fetched page https://pypi.org/simple/apache-iotdb/ as application/vnd.pypi.simple.v1+json 2023-07-28T10:58:00,384 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-07-28T10:58:00,385 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-07-28T10:58:00,387 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-07-28T10:58:00,387 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-07-28T10:58:00,389 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-07-28T10:58:00,389 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-07-28T10:58:00,391 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-07-28T10:58:00,391 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-07-28T10:58:00,393 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-07-28T10:58:00,393 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-07-28T10:58:00,395 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-07-28T10:58:00,395 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-07-28T10:58:00,397 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-07-28T10:58:00,397 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-07-28T10:58:00,399 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-07-28T10:58:00,399 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-07-28T10:58:00,401 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-07-28T10:58:00,401 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-07-28T10:58:00,403 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-07-28T10:58:00,403 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-07-28T10:58:00,405 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-07-28T10:58:00,405 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-07-28T10:58:00,407 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-07-28T10:58:00,407 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-07-28T10:58:00,408 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-07-28T10:58:00,409 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-07-28T10:58:00,410 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-07-28T10:58:00,411 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-07-28T10:58:00,412 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-07-28T10:58:00,413 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-07-28T10:58:00,414 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-07-28T10:58:00,415 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-07-28T10:58:00,416 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-07-28T10:58:00,417 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-07-28T10:58:00,418 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-07-28T10:58:00,419 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-07-28T10:58:00,420 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-07-28T10:58:00,421 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-07-28T10:58:00,422 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-07-28T10:58:00,423 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-07-28T10:58:00,424 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-07-28T10:58:00,425 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-07-28T10:58:00,426 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-07-28T10:58:00,427 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-07-28T10:58:00,428 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-07-28T10:58:00,429 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-07-28T10:58:00,430 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-07-28T10:58:00,431 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-07-28T10:58:00,432 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-07-28T10:58:00,433 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-07-28T10:58:00,434 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-07-28T10:58:00,435 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-07-28T10:58:00,436 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-07-28T10:58:00,437 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-07-28T10:58:00,438 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-07-28T10:58:00,439 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-07-28T10:58:00,440 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-07-28T10:58:00,441 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-07-28T10:58:00,442 Fetching project page and analyzing links: https://www.piwheels.org/simple/apache-iotdb/ 2023-07-28T10:58:00,442 Getting page https://www.piwheels.org/simple/apache-iotdb/ 2023-07-28T10:58:00,445 Found index url https://www.piwheels.org/simple/ 2023-07-28T10:58:00,654 Fetched page https://www.piwheels.org/simple/apache-iotdb/ as text/html 2023-07-28T10:58:00,677 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-07-28T10:58:00,677 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-07-28T10:58:00,678 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-07-28T10:58:00,678 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-07-28T10:58:00,679 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-07-28T10:58:00,680 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-07-28T10:58:00,680 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-07-28T10:58:00,681 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-07-28T10:58:00,681 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-07-28T10:58:00,682 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-07-28T10:58:00,682 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-07-28T10:58:00,683 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-07-28T10:58:00,683 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-07-28T10:58:00,684 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-07-28T10:58:00,684 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-07-28T10:58:00,685 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-07-28T10:58:00,685 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-07-28T10:58:00,686 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-07-28T10:58:00,686 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-07-28T10:58:00,687 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-07-28T10:58:00,687 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-07-28T10:58:00,688 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-07-28T10:58:00,688 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-07-28T10:58:00,689 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-07-28T10:58:00,690 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-07-28T10:58:00,690 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-07-28T10:58:00,691 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-07-28T10:58:00,691 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-07-28T10:58:00,692 Skipping link: not a file: https://www.piwheels.org/simple/apache-iotdb/ 2023-07-28T10:58:00,692 Skipping link: not a file: https://pypi.org/simple/apache-iotdb/ 2023-07-28T10:58:00,738 Given no hashes to check 1 links for project 'apache-iotdb': discarding no candidates 2023-07-28T10:58:00,770 Collecting apache-iotdb==1.1.2 2023-07-28T10:58:00,774 Created temporary directory: /tmp/pip-unpack-2lxkcwsm 2023-07-28T10:58:00,957 Downloading apache-iotdb-1.1.2.tar.gz (116 kB) 2023-07-28T10:58:01,490 Added apache-iotdb==1.1.2 from https://files.pythonhosted.org/packages/51/36/6e73e46e1d6b2d2272a5a1b369da16dd36a3120aa883ea86d2a9a85ce105/apache-iotdb-1.1.2.tar.gz to build tracker '/tmp/pip-build-tracker-xkvwt5eb' 2023-07-28T10:58:01,500 Created temporary directory: /tmp/pip-build-env-1hef8z5g 2023-07-28T10:58:01,520 Installing build dependencies: started 2023-07-28T10:58:01,522 Running command pip subprocess to install build dependencies 2023-07-28T10:58:04,259 Using pip 23.1.2 from /home/piwheels/.local/lib/python3.7/site-packages/pip (python 3.7) 2023-07-28T10:58:05,033 Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple 2023-07-28T10:58:09,139 Collecting setuptools>=40.8.0 2023-07-28T10:58:09,332 Using cached https://www.piwheels.org/simple/setuptools/setuptools-68.0.0-py3-none-any.whl (804 kB) 2023-07-28T10:58:09,981 Collecting wheel 2023-07-28T10:58:10,020 Using cached https://www.piwheels.org/simple/wheel/wheel-0.41.0-py3-none-any.whl (64 kB) 2023-07-28T10:58:15,071 Installing collected packages: wheel, setuptools 2023-07-28T10:58:15,533 Creating /tmp/pip-build-env-1hef8z5g/overlay/bin 2023-07-28T10:58:15,537 changing mode of /tmp/pip-build-env-1hef8z5g/overlay/bin/wheel to 755 2023-07-28T10:58:19,788 Successfully installed setuptools-68.0.0 wheel-0.41.0 2023-07-28T10:58:19,821 [notice] A new release of pip is available: 23.1.2 -> 23.2 2023-07-28T10:58:19,822 [notice] To update, run: python3 -m pip install --upgrade pip 2023-07-28T10:58:20,255 Installing build dependencies: finished with status 'done' 2023-07-28T10:58:20,266 Getting requirements to build wheel: started 2023-07-28T10:58:20,268 Running command Getting requirements to build wheel 2023-07-28T10:58:21,430 2023-07-28T10:58:21,437 # Apache IoTDB 2023-07-28T10:58:21,438 [![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-07-28T10:58:21,438 [![GitHub release](https://img.shields.io/github/release/apache/iotdb.svg)](https://github.com/apache/iotdb/releases) 2023-07-28T10:58:21,439 [![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html) 2023-07-28T10:58:21,439 ![](https://github-size-badge.herokuapp.com/apache/iotdb.svg) 2023-07-28T10:58:21,439 ![](https://img.shields.io/github/downloads/apache/iotdb/total.svg) 2023-07-28T10:58:21,440 ![](https://img.shields.io/badge/platform-win%20%7C%20macos%20%7C%20linux-yellow.svg) 2023-07-28T10:58:21,440 [![IoTDB Website](https://img.shields.io/website-up-down-green-red/https/shields.io.svg?label=iotdb-website)](https://iotdb.apache.org/) 2023-07-28T10:58:21,441 Apache IoTDB (Database for Internet of Things) is an IoT native database with high performance for 2023-07-28T10:58:21,441 data management and analysis, deployable on the edge and the cloud. Due to its light-weight 2023-07-28T10:58:21,441 architecture, high performance and rich feature set together with its deep integration with 2023-07-28T10:58:21,442 Apache Hadoop, Spark and Flink, Apache IoTDB can meet the requirements of massive data storage, 2023-07-28T10:58:21,442 high-speed data ingestion and complex data analysis in the IoT industrial fields. 2023-07-28T10:58:21,443 ## Python Native API 2023-07-28T10:58:21,443 ### Requirements 2023-07-28T10:58:21,444 You have to install thrift (>=0.13) before using the package. 2023-07-28T10:58:21,445 ### How to use (Example) 2023-07-28T10:58:21,446 First, download the latest package: `pip3 install apache-iotdb` 2023-07-28T10:58:21,447 *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-07-28T10:58:21,447 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-07-28T10:58:21,448 An example of aligned timeseries: [Aligned Timeseries Session Example](https://github.com/apache/iotdb/blob/master/client-py/SessionAlignedTimeseriesExample.py) 2023-07-28T10:58:21,448 (you need to add `import iotdb` in the head of the file) 2023-07-28T10:58:21,449 Or: 2023-07-28T10:58:21,450 ```python 2023-07-28T10:58:21,450 from iotdb.Session import Session 2023-07-28T10:58:21,451 ip = "127.0.0.1" 2023-07-28T10:58:21,451 port_ = "6667" 2023-07-28T10:58:21,451 username_ = "root" 2023-07-28T10:58:21,452 password_ = "root" 2023-07-28T10:58:21,452 session = Session(ip, port_, username_, password_) 2023-07-28T10:58:21,452 session.open(False) 2023-07-28T10:58:21,453 zone = session.get_time_zone() 2023-07-28T10:58:21,453 session.close() 2023-07-28T10:58:21,453 ``` 2023-07-28T10:58:21,454 ### Initialization 2023-07-28T10:58:21,454 * Initialize a Session 2023-07-28T10:58:21,455 ```python 2023-07-28T10:58:21,455 session = Session(ip, port_, username_, password_, fetch_size=1024, zone_id="UTC+8") 2023-07-28T10:58:21,456 ``` 2023-07-28T10:58:21,457 * Open a session, with a parameter to specify whether to enable RPC compression 2023-07-28T10:58:21,457 ```python 2023-07-28T10:58:21,458 session.open(enable_rpc_compression=False) 2023-07-28T10:58:21,458 ``` 2023-07-28T10:58:21,458 Notice: this RPC compression status of client must comply with that of IoTDB server 2023-07-28T10:58:21,459 * Close a Session 2023-07-28T10:58:21,460 ```python 2023-07-28T10:58:21,460 session.close() 2023-07-28T10:58:21,460 ``` 2023-07-28T10:58:21,461 ### Data Definition Interface (DDL Interface) 2023-07-28T10:58:21,462 #### DATABASE Management 2023-07-28T10:58:21,462 * CREATE DATABASE 2023-07-28T10:58:21,463 ```python 2023-07-28T10:58:21,463 session.set_storage_group(group_name) 2023-07-28T10:58:21,464 ``` 2023-07-28T10:58:21,464 * Delete one or several databases 2023-07-28T10:58:21,465 ```python 2023-07-28T10:58:21,465 session.delete_storage_group(group_name) 2023-07-28T10:58:21,466 session.delete_storage_groups(group_name_lst) 2023-07-28T10:58:21,466 ``` 2023-07-28T10:58:21,466 #### Timeseries Management 2023-07-28T10:58:21,467 * Create one or multiple timeseries 2023-07-28T10:58:21,468 ```python 2023-07-28T10:58:21,468 session.create_time_series(ts_path, data_type, encoding, compressor, 2023-07-28T10:58:21,468 props=None, tags=None, attributes=None, alias=None) 2023-07-28T10:58:21,469 session.create_multi_time_series( 2023-07-28T10:58:21,469 ts_path_lst, data_type_lst, encoding_lst, compressor_lst, 2023-07-28T10:58:21,469 props_lst=None, tags_lst=None, attributes_lst=None, alias_lst=None 2023-07-28T10:58:21,470 ) 2023-07-28T10:58:21,470 ``` 2023-07-28T10:58:21,471 * Create aligned timeseries 2023-07-28T10:58:21,471 ```python 2023-07-28T10:58:21,472 session.create_aligned_time_series( 2023-07-28T10:58:21,472 device_id, measurements_lst, data_type_lst, encoding_lst, compressor_lst 2023-07-28T10:58:21,472 ) 2023-07-28T10:58:21,472 ``` 2023-07-28T10:58:21,473 Attention: Alias of measurements are **not supported** currently. 2023-07-28T10:58:21,474 * Delete one or several timeseries 2023-07-28T10:58:21,474 ```python 2023-07-28T10:58:21,475 session.delete_time_series(paths_list) 2023-07-28T10:58:21,475 ``` 2023-07-28T10:58:21,476 * Check whether the specific timeseries exists 2023-07-28T10:58:21,476 ```python 2023-07-28T10:58:21,477 session.check_time_series_exists(path) 2023-07-28T10:58:21,477 ``` 2023-07-28T10:58:21,478 ### Data Manipulation Interface (DML Interface) 2023-07-28T10:58:21,478 #### Insert 2023-07-28T10:58:21,479 It is recommended to use insertTablet to help improve write efficiency. 2023-07-28T10:58:21,479 * Insert a Tablet,which is multiple rows of a device, each row has the same measurements 2023-07-28T10:58:21,480 * **Better Write Performance** 2023-07-28T10:58:21,480 * **Support null values**: fill the null value with any value, and then mark the null value via BitMap (from v0.13) 2023-07-28T10:58:21,481 We have two implementations of Tablet in Python API. 2023-07-28T10:58:21,482 * Normal Tablet 2023-07-28T10:58:21,482 ```python 2023-07-28T10:58:21,482 values_ = [ 2023-07-28T10:58:21,483 [False, 10, 11, 1.1, 10011.1, "test01"], 2023-07-28T10:58:21,483 [True, 100, 11111, 1.25, 101.0, "test02"], 2023-07-28T10:58:21,483 [False, 100, 1, 188.1, 688.25, "test03"], 2023-07-28T10:58:21,484 [True, 0, 0, 0, 6.25, "test04"], 2023-07-28T10:58:21,484 ] 2023-07-28T10:58:21,484 timestamps_ = [1, 2, 3, 4] 2023-07-28T10:58:21,484 tablet_ = Tablet( 2023-07-28T10:58:21,485 device_id, measurements_, data_types_, values_, timestamps_ 2023-07-28T10:58:21,485 ) 2023-07-28T10:58:21,485 session.insert_tablet(tablet_) 2023-07-28T10:58:21,486 values_ = [ 2023-07-28T10:58:21,486 [None, 10, 11, 1.1, 10011.1, "test01"], 2023-07-28T10:58:21,487 [True, None, 11111, 1.25, 101.0, "test02"], 2023-07-28T10:58:21,487 [False, 100, None, 188.1, 688.25, "test03"], 2023-07-28T10:58:21,487 [True, 0, 0, 0, None, None], 2023-07-28T10:58:21,488 ] 2023-07-28T10:58:21,488 timestamps_ = [16, 17, 18, 19] 2023-07-28T10:58:21,488 tablet_ = Tablet( 2023-07-28T10:58:21,489 device_id, measurements_, data_types_, values_, timestamps_ 2023-07-28T10:58:21,489 ) 2023-07-28T10:58:21,489 session.insert_tablet(tablet_) 2023-07-28T10:58:21,490 ``` 2023-07-28T10:58:21,490 * Numpy Tablet 2023-07-28T10:58:21,490 Comparing with Tablet, Numpy Tablet is using [numpy.ndarray](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html) to record data. 2023-07-28T10:58:21,491 With less memory footprint and time cost of serialization, the insert performance will be better. 2023-07-28T10:58:21,491 **Notice** 2023-07-28T10:58:21,492 1. time and value columns in Tablet are ndarray. 2023-07-28T10:58:21,492 2. recommended to use the specific dtypes to each ndarray, see the example below 2023-07-28T10:58:21,492 (if not, the default dtypes are also ok). 2023-07-28T10:58:21,493 ```python 2023-07-28T10:58:21,493 import numpy as np 2023-07-28T10:58:21,493 data_types_ = [ 2023-07-28T10:58:21,494 TSDataType.BOOLEAN, 2023-07-28T10:58:21,494 TSDataType.INT32, 2023-07-28T10:58:21,494 TSDataType.INT64, 2023-07-28T10:58:21,495 TSDataType.FLOAT, 2023-07-28T10:58:21,495 TSDataType.DOUBLE, 2023-07-28T10:58:21,495 TSDataType.TEXT, 2023-07-28T10:58:21,496 ] 2023-07-28T10:58:21,496 np_values_ = [ 2023-07-28T10:58:21,496 np.array([False, True, False, True], TSDataType.BOOLEAN.np_dtype()), 2023-07-28T10:58:21,497 np.array([10, 100, 100, 0], TSDataType.INT32.np_dtype()), 2023-07-28T10:58:21,497 np.array([11, 11111, 1, 0], TSDataType.INT64.np_dtype()), 2023-07-28T10:58:21,497 np.array([1.1, 1.25, 188.1, 0], TSDataType.FLOAT.np_dtype()), 2023-07-28T10:58:21,498 np.array([10011.1, 101.0, 688.25, 6.25], TSDataType.DOUBLE.np_dtype()), 2023-07-28T10:58:21,498 np.array(["test01", "test02", "test03", "test04"], TSDataType.TEXT.np_dtype()), 2023-07-28T10:58:21,498 ] 2023-07-28T10:58:21,499 np_timestamps_ = np.array([1, 2, 3, 4], TSDataType.INT64.np_dtype()) 2023-07-28T10:58:21,499 np_tablet_ = NumpyTablet( 2023-07-28T10:58:21,499 device_id, measurements_, data_types_, np_values_, np_timestamps_ 2023-07-28T10:58:21,499 ) 2023-07-28T10:58:21,500 session.insert_tablet(np_tablet_) 2023-07-28T10:58:21,500 # insert one numpy tablet with none into the database. 2023-07-28T10:58:21,501 np_values_ = [ 2023-07-28T10:58:21,501 np.array([False, True, False, True], TSDataType.BOOLEAN.np_dtype()), 2023-07-28T10:58:21,501 np.array([10, 100, 100, 0], TSDataType.INT32.np_dtype()), 2023-07-28T10:58:21,501 np.array([11, 11111, 1, 0], TSDataType.INT64.np_dtype()), 2023-07-28T10:58:21,502 np.array([1.1, 1.25, 188.1, 0], TSDataType.FLOAT.np_dtype()), 2023-07-28T10:58:21,502 np.array([10011.1, 101.0, 688.25, 6.25], TSDataType.DOUBLE.np_dtype()), 2023-07-28T10:58:21,502 np.array(["test01", "test02", "test03", "test04"], TSDataType.TEXT.np_dtype()), 2023-07-28T10:58:21,503 ] 2023-07-28T10:58:21,503 np_timestamps_ = np.array([98, 99, 100, 101], TSDataType.INT64.np_dtype()) 2023-07-28T10:58:21,503 np_bitmaps_ = [] 2023-07-28T10:58:21,504 for i in range(len(measurements_)): 2023-07-28T10:58:21,504 np_bitmaps_.append(BitMap(len(np_timestamps_))) 2023-07-28T10:58:21,504 np_bitmaps_[0].mark(0) 2023-07-28T10:58:21,505 np_bitmaps_[1].mark(1) 2023-07-28T10:58:21,505 np_bitmaps_[2].mark(2) 2023-07-28T10:58:21,505 np_bitmaps_[4].mark(3) 2023-07-28T10:58:21,505 np_bitmaps_[5].mark(3) 2023-07-28T10:58:21,506 np_tablet_with_none = NumpyTablet( 2023-07-28T10:58:21,506 device_id, measurements_, data_types_, np_values_, np_timestamps_, np_bitmaps_ 2023-07-28T10:58:21,507 ) 2023-07-28T10:58:21,507 session.insert_tablet(np_tablet_with_none) 2023-07-28T10:58:21,507 ``` 2023-07-28T10:58:21,508 * Insert multiple Tablets 2023-07-28T10:58:21,508 ```python 2023-07-28T10:58:21,509 session.insert_tablets(tablet_lst) 2023-07-28T10:58:21,509 ``` 2023-07-28T10:58:21,510 * Insert a Record 2023-07-28T10:58:21,510 ```python 2023-07-28T10:58:21,510 session.insert_record(device_id, timestamp, measurements_, data_types_, values_) 2023-07-28T10:58:21,511 ``` 2023-07-28T10:58:21,511 * Insert multiple Records 2023-07-28T10:58:21,512 ```python 2023-07-28T10:58:21,512 session.insert_records( 2023-07-28T10:58:21,513 device_ids_, time_list_, measurements_list_, data_type_list_, values_list_ 2023-07-28T10:58:21,513 ) 2023-07-28T10:58:21,513 ``` 2023-07-28T10:58:21,514 * Insert multiple Records that belong to the same device. 2023-07-28T10:58:21,514 With type info the server has no need to do type inference, which leads a better performance 2023-07-28T10:58:21,515 ```python 2023-07-28T10:58:21,516 session.insert_records_of_one_device(device_id, time_list, measurements_list, data_types_list, values_list) 2023-07-28T10:58:21,516 ``` 2023-07-28T10:58:21,517 #### Insert with type inference 2023-07-28T10:58:21,517 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-07-28T10:58:21,518 * Insert a Record, which contains multiple measurement value of a device at a timestamp 2023-07-28T10:58:21,518 ```python 2023-07-28T10:58:21,519 session.insert_str_record(device_id, timestamp, measurements, string_values) 2023-07-28T10:58:21,519 ``` 2023-07-28T10:58:21,520 #### Insert of Aligned Timeseries 2023-07-28T10:58:21,520 The Insert of aligned timeseries uses interfaces like insert_aligned_XXX, and others are similar to the above interfaces: 2023-07-28T10:58:21,521 * insert_aligned_record 2023-07-28T10:58:21,521 * insert_aligned_records 2023-07-28T10:58:21,521 * insert_aligned_records_of_one_device 2023-07-28T10:58:21,522 * insert_aligned_tablet 2023-07-28T10:58:21,522 * insert_aligned_tablets 2023-07-28T10:58:21,523 ### IoTDB-SQL Interface 2023-07-28T10:58:21,523 * Execute query statement 2023-07-28T10:58:21,524 ```python 2023-07-28T10:58:21,524 session.execute_query_statement(sql) 2023-07-28T10:58:21,525 ``` 2023-07-28T10:58:21,525 * Execute non query statement 2023-07-28T10:58:21,526 ```python 2023-07-28T10:58:21,526 session.execute_non_query_statement(sql) 2023-07-28T10:58:21,527 ``` 2023-07-28T10:58:21,527 * Execute statement 2023-07-28T10:58:21,528 ```python 2023-07-28T10:58:21,528 session.execute_statement(sql) 2023-07-28T10:58:21,529 ``` 2023-07-28T10:58:21,529 ### Schema Template 2023-07-28T10:58:21,530 #### Create Schema Template 2023-07-28T10:58:21,530 The step for creating a metadata template is as follows 2023-07-28T10:58:21,530 1. Create the template class 2023-07-28T10:58:21,530 2. Adding child Node,InternalNode and MeasurementNode can be chose 2023-07-28T10:58:21,531 3. Execute create schema template function 2023-07-28T10:58:21,531 ```python 2023-07-28T10:58:21,532 template = Template(name=template_name, share_time=True) 2023-07-28T10:58:21,532 i_node_gps = InternalNode(name="GPS", share_time=False) 2023-07-28T10:58:21,533 i_node_v = InternalNode(name="vehicle", share_time=True) 2023-07-28T10:58:21,533 m_node_x = MeasurementNode("x", TSDataType.FLOAT, TSEncoding.RLE, Compressor.SNAPPY) 2023-07-28T10:58:21,533 i_node_gps.add_child(m_node_x) 2023-07-28T10:58:21,534 i_node_v.add_child(m_node_x) 2023-07-28T10:58:21,534 template.add_template(i_node_gps) 2023-07-28T10:58:21,535 template.add_template(i_node_v) 2023-07-28T10:58:21,535 template.add_template(m_node_x) 2023-07-28T10:58:21,536 session.create_schema_template(template) 2023-07-28T10:58:21,536 ``` 2023-07-28T10:58:21,536 #### Modify Schema Template nodes 2023-07-28T10:58:21,537 Modify nodes in a template, the template must be already created. These are functions that add or delete some measurement nodes. 2023-07-28T10:58:21,537 * add node in template 2023-07-28T10:58:21,537 ```python 2023-07-28T10:58:21,538 session.add_measurements_in_template(template_name, measurements_path, data_types, encodings, compressors, is_aligned) 2023-07-28T10:58:21,538 ``` 2023-07-28T10:58:21,539 * delete node in template 2023-07-28T10:58:21,539 ```python 2023-07-28T10:58:21,539 session.delete_node_in_template(template_name, path) 2023-07-28T10:58:21,540 ``` 2023-07-28T10:58:21,540 #### Set Schema Template 2023-07-28T10:58:21,540 ```python 2023-07-28T10:58:21,541 session.set_schema_template(template_name, prefix_path) 2023-07-28T10:58:21,541 ``` 2023-07-28T10:58:21,542 #### Uset Schema Template 2023-07-28T10:58:21,542 ```python 2023-07-28T10:58:21,542 session.unset_schema_template(template_name, prefix_path) 2023-07-28T10:58:21,543 ``` 2023-07-28T10:58:21,544 #### Show Schema Template 2023-07-28T10:58:21,544 * Show all schema templates 2023-07-28T10:58:21,544 ```python 2023-07-28T10:58:21,545 session.show_all_templates() 2023-07-28T10:58:21,545 ``` 2023-07-28T10:58:21,546 * Count all nodes in templates 2023-07-28T10:58:21,546 ```python 2023-07-28T10:58:21,546 session.count_measurements_in_template(template_name) 2023-07-28T10:58:21,547 ``` 2023-07-28T10:58:21,547 * Judge whether the path is measurement or not in templates, This measurement must be in the template 2023-07-28T10:58:21,547 ```python 2023-07-28T10:58:21,548 session.count_measurements_in_template(template_name, path) 2023-07-28T10:58:21,548 ``` 2023-07-28T10:58:21,549 * Judge whether the path is exist or not in templates, This path may not belong to the template 2023-07-28T10:58:21,549 ```python 2023-07-28T10:58:21,549 session.is_path_exist_in_template(template_name, path) 2023-07-28T10:58:21,550 ``` 2023-07-28T10:58:21,550 * Show nodes under in schema template 2023-07-28T10:58:21,550 ```python 2023-07-28T10:58:21,551 session.show_measurements_in_template(template_name) 2023-07-28T10:58:21,551 ``` 2023-07-28T10:58:21,552 * Show the path prefix where a schema template is set 2023-07-28T10:58:21,552 ```python 2023-07-28T10:58:21,552 session.show_paths_template_set_on(template_name) 2023-07-28T10:58:21,552 ``` 2023-07-28T10:58:21,553 * Show the path prefix where a schema template is used (i.e. the time series has been created) 2023-07-28T10:58:21,553 ```python 2023-07-28T10:58:21,554 session.show_paths_template_using_on(template_name) 2023-07-28T10:58:21,554 ``` 2023-07-28T10:58:21,554 #### Drop Schema Template 2023-07-28T10:58:21,555 Delete an existing metadata template,dropping an already set template is not supported 2023-07-28T10:58:21,555 ```python 2023-07-28T10:58:21,555 session.drop_schema_template("template_python") 2023-07-28T10:58:21,556 ``` 2023-07-28T10:58:21,557 ### Pandas Support 2023-07-28T10:58:21,557 To easily transform a query result to a [Pandas Dataframe](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html) 2023-07-28T10:58:21,558 the SessionDataSet has a method `.todf()` which consumes the dataset and transforms it to a pandas dataframe. 2023-07-28T10:58:21,558 Example: 2023-07-28T10:58:21,559 ```python 2023-07-28T10:58:21,559 from iotdb.Session import Session 2023-07-28T10:58:21,560 ip = "127.0.0.1" 2023-07-28T10:58:21,560 port_ = "6667" 2023-07-28T10:58:21,560 username_ = "root" 2023-07-28T10:58:21,560 password_ = "root" 2023-07-28T10:58:21,561 session = Session(ip, port_, username_, password_) 2023-07-28T10:58:21,561 session.open(False) 2023-07-28T10:58:21,561 result = session.execute_query_statement("SELECT * FROM root.*") 2023-07-28T10:58:21,562 # Transform to Pandas Dataset 2023-07-28T10:58:21,562 df = result.todf() 2023-07-28T10:58:21,563 session.close() 2023-07-28T10:58:21,563 # Now you can work with the dataframe 2023-07-28T10:58:21,564 df = ... 2023-07-28T10:58:21,564 ``` 2023-07-28T10:58:21,565 ### IoTDB Testcontainer 2023-07-28T10:58:21,566 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-07-28T10:58:21,566 To start (and stop) an IoTDB Database in a Docker container simply do: 2023-07-28T10:58:21,566 ```python 2023-07-28T10:58:21,567 class MyTestCase(unittest.TestCase): 2023-07-28T10:58:21,567 def test_something(self): 2023-07-28T10:58:21,568 with IoTDBContainer() as c: 2023-07-28T10:58:21,568 session = Session("localhost", c.get_exposed_port(6667), "root", "root") 2023-07-28T10:58:21,568 session.open(False) 2023-07-28T10:58:21,568 result = session.execute_query_statement("SHOW TIMESERIES") 2023-07-28T10:58:21,569 print(result) 2023-07-28T10:58:21,569 session.close() 2023-07-28T10:58:21,569 ``` 2023-07-28T10:58:21,570 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-07-28T10:58:21,571 ### IoTDB DBAPI 2023-07-28T10:58:21,571 IoTDB DBAPI implements the Python DB API 2.0 specification (https://peps.python.org/pep-0249/), which defines a common 2023-07-28T10:58:21,572 interface for accessing databases in Python. 2023-07-28T10:58:21,572 #### Examples 2023-07-28T10:58:21,573 + Initialization 2023-07-28T10:58:21,573 The initialized parameters are consistent with the session part (except for the sqlalchemy_mode). 2023-07-28T10:58:21,573 ```python 2023-07-28T10:58:21,574 from iotdb.dbapi import connect 2023-07-28T10:58:21,574 ip = "127.0.0.1" 2023-07-28T10:58:21,575 port_ = "6667" 2023-07-28T10:58:21,575 username_ = "root" 2023-07-28T10:58:21,575 password_ = "root" 2023-07-28T10:58:21,576 conn = connect(ip, port_, username_, password_,fetch_size=1024,zone_id="UTC+8",sqlalchemy_mode=False) 2023-07-28T10:58:21,576 cursor = conn.cursor() 2023-07-28T10:58:21,576 ``` 2023-07-28T10:58:21,577 + simple SQL statement execution 2023-07-28T10:58:21,577 ```python 2023-07-28T10:58:21,577 cursor.execute("SELECT * FROM root.*") 2023-07-28T10:58:21,578 for row in cursor.fetchall(): 2023-07-28T10:58:21,578 print(row) 2023-07-28T10:58:21,578 ``` 2023-07-28T10:58:21,579 + execute SQL with parameter 2023-07-28T10:58:21,579 IoTDB DBAPI supports pyformat style parameters 2023-07-28T10:58:21,580 ```python 2023-07-28T10:58:21,580 cursor.execute("SELECT * FROM root.* WHERE time < %(time)s",{"time":"2017-11-01T00:08:00.000"}) 2023-07-28T10:58:21,580 for row in cursor.fetchall(): 2023-07-28T10:58:21,580 print(row) 2023-07-28T10:58:21,581 ``` 2023-07-28T10:58:21,581 + execute SQL with parameter sequences 2023-07-28T10:58:21,582 ```python 2023-07-28T10:58:21,582 seq_of_parameters = [ 2023-07-28T10:58:21,582 {"timestamp": 1, "temperature": 1}, 2023-07-28T10:58:21,583 {"timestamp": 2, "temperature": 2}, 2023-07-28T10:58:21,583 {"timestamp": 3, "temperature": 3}, 2023-07-28T10:58:21,583 {"timestamp": 4, "temperature": 4}, 2023-07-28T10:58:21,583 {"timestamp": 5, "temperature": 5}, 2023-07-28T10:58:21,584 ] 2023-07-28T10:58:21,584 sql = "insert into root.cursor(timestamp,temperature) values(%(timestamp)s,%(temperature)s)" 2023-07-28T10:58:21,584 cursor.executemany(sql,seq_of_parameters) 2023-07-28T10:58:21,584 ``` 2023-07-28T10:58:21,585 + close the connection and cursor 2023-07-28T10:58:21,585 ```python 2023-07-28T10:58:21,586 cursor.close() 2023-07-28T10:58:21,586 conn.close() 2023-07-28T10:58:21,586 ``` 2023-07-28T10:58:21,587 ### IoTDB SQLAlchemy Dialect (Experimental) 2023-07-28T10:58:21,587 The SQLAlchemy dialect of IoTDB is written to adapt to Apache Superset. 2023-07-28T10:58:21,588 This part is still being improved. 2023-07-28T10:58:21,588 Please do not use it in the production environment! 2023-07-28T10:58:21,588 #### Mapping of the metadata 2023-07-28T10:58:21,589 The data model used by SQLAlchemy is a relational data model, which describes the relationships between different entities through tables. 2023-07-28T10:58:21,589 While the data model of IoTDB is a hierarchical data model, which organizes the data through a tree structure. 2023-07-28T10:58:21,589 In order to adapt IoTDB to the dialect of SQLAlchemy, the original data model in IoTDB needs to be reorganized. 2023-07-28T10:58:21,590 Converting the data model of IoTDB into the data model of SQLAlchemy. 2023-07-28T10:58:21,590 The metadata in the IoTDB are: 2023-07-28T10:58:21,591 1. Database 2023-07-28T10:58:21,591 2. Path 2023-07-28T10:58:21,591 3. Entity 2023-07-28T10:58:21,592 4. Measurement 2023-07-28T10:58:21,592 The metadata in the SQLAlchemy are: 2023-07-28T10:58:21,593 1. Schema 2023-07-28T10:58:21,593 2. Table 2023-07-28T10:58:21,593 3. Column 2023-07-28T10:58:21,594 The mapping relationship between them is: 2023-07-28T10:58:21,596 | The metadata in the SQLAlchemy | The metadata in the IoTDB | 2023-07-28T10:58:21,596 | -------------------- | ---------------------------------------------- | 2023-07-28T10:58:21,596 | Schema | Database | 2023-07-28T10:58:21,597 | Table | Path ( from database to entity ) + Entity | 2023-07-28T10:58:21,597 | Column | Measurement | 2023-07-28T10:58:21,598 The following figure shows the relationship between the two more intuitively: 2023-07-28T10:58:21,598 ![sqlalchemy-to-iotdb](https://github.com/apache/iotdb-bin-resources/blob/main/docs/UserGuide/API/IoTDB-SQLAlchemy/sqlalchemy-to-iotdb.png?raw=true) 2023-07-28T10:58:21,599 #### Data type mapping 2023-07-28T10:58:21,599 | data type in IoTDB | data type in SQLAlchemy | 2023-07-28T10:58:21,600 |--------------------|-------------------------| 2023-07-28T10:58:21,600 | BOOLEAN | Boolean | 2023-07-28T10:58:21,600 | INT32 | Integer | 2023-07-28T10:58:21,601 | INT64 | BigInteger | 2023-07-28T10:58:21,601 | FLOAT | Float | 2023-07-28T10:58:21,601 | DOUBLE | Float | 2023-07-28T10:58:21,602 | TEXT | Text | 2023-07-28T10:58:21,602 | LONG | BigInteger | 2023-07-28T10:58:21,602 #### Example 2023-07-28T10:58:21,603 + execute statement 2023-07-28T10:58:21,603 ```python 2023-07-28T10:58:21,604 from sqlalchemy import create_engine 2023-07-28T10:58:21,604 engine = create_engine("iotdb://root:root@127.0.0.1:6667") 2023-07-28T10:58:21,605 connect = engine.connect() 2023-07-28T10:58:21,605 result = connect.execute("SELECT ** FROM root") 2023-07-28T10:58:21,605 for row in result.fetchall(): 2023-07-28T10:58:21,606 print(row) 2023-07-28T10:58:21,606 ``` 2023-07-28T10:58:21,606 + ORM (now only simple queries are supported) 2023-07-28T10:58:21,607 ```python 2023-07-28T10:58:21,607 from sqlalchemy import create_engine, Column, Float, BigInteger, MetaData 2023-07-28T10:58:21,608 from sqlalchemy.ext.declarative import declarative_base 2023-07-28T10:58:21,608 from sqlalchemy.orm import sessionmaker 2023-07-28T10:58:21,608 metadata = MetaData( 2023-07-28T10:58:21,609 schema='root.factory' 2023-07-28T10:58:21,609 ) 2023-07-28T10:58:21,609 Base = declarative_base(metadata=metadata) 2023-07-28T10:58:21,610 class Device(Base): 2023-07-28T10:58:21,610 __tablename__ = "room2.device1" 2023-07-28T10:58:21,611 Time = Column(BigInteger, primary_key=True) 2023-07-28T10:58:21,611 temperature = Column(Float) 2023-07-28T10:58:21,611 status = Column(Float) 2023-07-28T10:58:21,612 engine = create_engine("iotdb://root:root@127.0.0.1:6667") 2023-07-28T10:58:21,613 DbSession = sessionmaker(bind=engine) 2023-07-28T10:58:21,613 session = DbSession() 2023-07-28T10:58:21,614 res = session.query(Device.status).filter(Device.temperature > 1) 2023-07-28T10:58:21,614 for row in res: 2023-07-28T10:58:21,614 print(row) 2023-07-28T10:58:21,615 ``` 2023-07-28T10:58:21,616 ## Developers 2023-07-28T10:58:21,616 ### Introduction 2023-07-28T10:58:21,617 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-07-28T10:58:21,618 ### Prerequisites 2023-07-28T10:58:21,619 Python3.7 or later is preferred. 2023-07-28T10:58:21,619 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-07-28T10:58:21,620 ``` 2023-07-28T10:58:21,620 http://thrift.apache.org/docs/install/ 2023-07-28T10:58:21,620 ``` 2023-07-28T10:58:21,621 Before starting you need to install `requirements_dev.txt` in your python environment, e.g. by calling 2023-07-28T10:58:21,621 ```shell 2023-07-28T10:58:21,622 pip install -r requirements_dev.txt 2023-07-28T10:58:21,622 ``` 2023-07-28T10:58:21,623 ### Compile the thrift library and Debug 2023-07-28T10:58:21,624 In the root of IoTDB's source code folder, run `mvn clean generate-sources -pl client-py -am`. 2023-07-28T10:58:21,624 This will automatically delete and repopulate the folder `iotdb/thrift` with the generated thrift files. 2023-07-28T10:58:21,625 This folder is ignored from git and should **never be pushed to git!** 2023-07-28T10:58:21,625 **Notice** Do not upload `iotdb/thrift` to the git repo. 2023-07-28T10:58:21,627 ### Session Client & Example 2023-07-28T10:58:21,627 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-07-28T10:58:21,628 Or, another simple example: 2023-07-28T10:58:21,629 ```python 2023-07-28T10:58:21,629 from iotdb.Session import Session 2023-07-28T10:58:21,630 ip = "127.0.0.1" 2023-07-28T10:58:21,630 port_ = "6667" 2023-07-28T10:58:21,631 username_ = "root" 2023-07-28T10:58:21,632 password_ = "root" 2023-07-28T10:58:21,632 session = Session(ip, port_, username_, password_) 2023-07-28T10:58:21,632 session.open(False) 2023-07-28T10:58:21,633 zone = session.get_time_zone() 2023-07-28T10:58:21,633 session.close() 2023-07-28T10:58:21,633 ``` 2023-07-28T10:58:21,634 ### Tests 2023-07-28T10:58:21,635 Please add your custom tests in `tests` folder. 2023-07-28T10:58:21,636 To run all defined tests just type `pytest .` in the root folder. 2023-07-28T10:58:21,636 **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-07-28T10:58:21,638 ### Futher Tools 2023-07-28T10:58:21,638 [black](https://pypi.org/project/black/) and [flake8](https://pypi.org/project/flake8/) are installed for autoformatting and linting. 2023-07-28T10:58:21,639 Both can be run by `black .` or `flake8 .` respectively. 2023-07-28T10:58:21,640 ## Releasing 2023-07-28T10:58:21,640 To do a release just ensure that you have the right set of generated thrift files. 2023-07-28T10:58:21,641 Then run linting and auto-formatting. 2023-07-28T10:58:21,641 Then, ensure that all tests work (via `pytest .`). 2023-07-28T10:58:21,641 Then you are good to go to do a release! 2023-07-28T10:58:21,643 ### Preparing your environment 2023-07-28T10:58:21,643 First, install all necessary dev dependencies via `pip install -r requirements_dev.txt`. 2023-07-28T10:58:21,644 ### Doing the Release 2023-07-28T10:58:21,645 There is a convenient script `release.sh` to do all steps for a release. 2023-07-28T10:58:21,645 Namely, these are 2023-07-28T10:58:21,646 * Remove all transient directories from last release (if exists) 2023-07-28T10:58:21,646 * (Re-)generate all generated sources via mvn 2023-07-28T10:58:21,647 * Run Linting (flake8) 2023-07-28T10:58:21,647 * Run Tests via pytest 2023-07-28T10:58:21,647 * Build 2023-07-28T10:58:21,647 * Release to pypi 2023-07-28T10:58:21,678 running egg_info 2023-07-28T10:58:21,689 writing apache_iotdb.egg-info/PKG-INFO 2023-07-28T10:58:21,695 writing dependency_links to apache_iotdb.egg-info/dependency_links.txt 2023-07-28T10:58:21,698 writing entry points to apache_iotdb.egg-info/entry_points.txt 2023-07-28T10:58:21,701 writing requirements to apache_iotdb.egg-info/requires.txt 2023-07-28T10:58:21,704 writing top-level names to apache_iotdb.egg-info/top_level.txt 2023-07-28T10:58:21,777 reading manifest file 'apache_iotdb.egg-info/SOURCES.txt' 2023-07-28T10:58:21,784 adding license file 'LICENSE' 2023-07-28T10:58:21,798 writing manifest file 'apache_iotdb.egg-info/SOURCES.txt' 2023-07-28T10:58:21,802 /tmp/pip-build-env-1hef8z5g/overlay/lib/python3.7/site-packages/setuptools/_distutils/dist.py:265: UserWarning: Unknown distribution option: 'website' 2023-07-28T10:58:21,802 warnings.warn(msg) 2023-07-28T10:58:21,914 Getting requirements to build wheel: finished with status 'done' 2023-07-28T10:58:21,935 Created temporary directory: /tmp/pip-modern-metadata-wv6awfhb 2023-07-28T10:58:21,941 Preparing metadata (pyproject.toml): started 2023-07-28T10:58:21,943 Running command Preparing metadata (pyproject.toml) 2023-07-28T10:58:23,042 2023-07-28T10:58:23,050 # Apache IoTDB 2023-07-28T10:58:23,051 [![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-07-28T10:58:23,051 [![GitHub release](https://img.shields.io/github/release/apache/iotdb.svg)](https://github.com/apache/iotdb/releases) 2023-07-28T10:58:23,052 [![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html) 2023-07-28T10:58:23,052 ![](https://github-size-badge.herokuapp.com/apache/iotdb.svg) 2023-07-28T10:58:23,052 ![](https://img.shields.io/github/downloads/apache/iotdb/total.svg) 2023-07-28T10:58:23,053 ![](https://img.shields.io/badge/platform-win%20%7C%20macos%20%7C%20linux-yellow.svg) 2023-07-28T10:58:23,053 [![IoTDB Website](https://img.shields.io/website-up-down-green-red/https/shields.io.svg?label=iotdb-website)](https://iotdb.apache.org/) 2023-07-28T10:58:23,054 Apache IoTDB (Database for Internet of Things) is an IoT native database with high performance for 2023-07-28T10:58:23,054 data management and analysis, deployable on the edge and the cloud. Due to its light-weight 2023-07-28T10:58:23,055 architecture, high performance and rich feature set together with its deep integration with 2023-07-28T10:58:23,055 Apache Hadoop, Spark and Flink, Apache IoTDB can meet the requirements of massive data storage, 2023-07-28T10:58:23,055 high-speed data ingestion and complex data analysis in the IoT industrial fields. 2023-07-28T10:58:23,056 ## Python Native API 2023-07-28T10:58:23,057 ### Requirements 2023-07-28T10:58:23,057 You have to install thrift (>=0.13) before using the package. 2023-07-28T10:58:23,059 ### How to use (Example) 2023-07-28T10:58:23,059 First, download the latest package: `pip3 install apache-iotdb` 2023-07-28T10:58:23,060 *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-07-28T10:58:23,060 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-07-28T10:58:23,061 An example of aligned timeseries: [Aligned Timeseries Session Example](https://github.com/apache/iotdb/blob/master/client-py/SessionAlignedTimeseriesExample.py) 2023-07-28T10:58:23,062 (you need to add `import iotdb` in the head of the file) 2023-07-28T10:58:23,062 Or: 2023-07-28T10:58:23,063 ```python 2023-07-28T10:58:23,063 from iotdb.Session import Session 2023-07-28T10:58:23,064 ip = "127.0.0.1" 2023-07-28T10:58:23,064 port_ = "6667" 2023-07-28T10:58:23,065 username_ = "root" 2023-07-28T10:58:23,065 password_ = "root" 2023-07-28T10:58:23,065 session = Session(ip, port_, username_, password_) 2023-07-28T10:58:23,066 session.open(False) 2023-07-28T10:58:23,066 zone = session.get_time_zone() 2023-07-28T10:58:23,066 session.close() 2023-07-28T10:58:23,067 ``` 2023-07-28T10:58:23,067 ### Initialization 2023-07-28T10:58:23,068 * Initialize a Session 2023-07-28T10:58:23,068 ```python 2023-07-28T10:58:23,069 session = Session(ip, port_, username_, password_, fetch_size=1024, zone_id="UTC+8") 2023-07-28T10:58:23,069 ``` 2023-07-28T10:58:23,070 * Open a session, with a parameter to specify whether to enable RPC compression 2023-07-28T10:58:23,070 ```python 2023-07-28T10:58:23,071 session.open(enable_rpc_compression=False) 2023-07-28T10:58:23,071 ``` 2023-07-28T10:58:23,071 Notice: this RPC compression status of client must comply with that of IoTDB server 2023-07-28T10:58:23,072 * Close a Session 2023-07-28T10:58:23,073 ```python 2023-07-28T10:58:23,073 session.close() 2023-07-28T10:58:23,073 ``` 2023-07-28T10:58:23,074 ### Data Definition Interface (DDL Interface) 2023-07-28T10:58:23,074 #### DATABASE Management 2023-07-28T10:58:23,075 * CREATE DATABASE 2023-07-28T10:58:23,076 ```python 2023-07-28T10:58:23,076 session.set_storage_group(group_name) 2023-07-28T10:58:23,076 ``` 2023-07-28T10:58:23,077 * Delete one or several databases 2023-07-28T10:58:23,077 ```python 2023-07-28T10:58:23,078 session.delete_storage_group(group_name) 2023-07-28T10:58:23,078 session.delete_storage_groups(group_name_lst) 2023-07-28T10:58:23,078 ``` 2023-07-28T10:58:23,079 #### Timeseries Management 2023-07-28T10:58:23,079 * Create one or multiple timeseries 2023-07-28T10:58:23,080 ```python 2023-07-28T10:58:23,080 session.create_time_series(ts_path, data_type, encoding, compressor, 2023-07-28T10:58:23,081 props=None, tags=None, attributes=None, alias=None) 2023-07-28T10:58:23,081 session.create_multi_time_series( 2023-07-28T10:58:23,082 ts_path_lst, data_type_lst, encoding_lst, compressor_lst, 2023-07-28T10:58:23,082 props_lst=None, tags_lst=None, attributes_lst=None, alias_lst=None 2023-07-28T10:58:23,082 ) 2023-07-28T10:58:23,083 ``` 2023-07-28T10:58:23,083 * Create aligned timeseries 2023-07-28T10:58:23,084 ```python 2023-07-28T10:58:23,084 session.create_aligned_time_series( 2023-07-28T10:58:23,084 device_id, measurements_lst, data_type_lst, encoding_lst, compressor_lst 2023-07-28T10:58:23,085 ) 2023-07-28T10:58:23,085 ``` 2023-07-28T10:58:23,086 Attention: Alias of measurements are **not supported** currently. 2023-07-28T10:58:23,086 * Delete one or several timeseries 2023-07-28T10:58:23,087 ```python 2023-07-28T10:58:23,087 session.delete_time_series(paths_list) 2023-07-28T10:58:23,087 ``` 2023-07-28T10:58:23,088 * Check whether the specific timeseries exists 2023-07-28T10:58:23,089 ```python 2023-07-28T10:58:23,089 session.check_time_series_exists(path) 2023-07-28T10:58:23,089 ``` 2023-07-28T10:58:23,090 ### Data Manipulation Interface (DML Interface) 2023-07-28T10:58:23,091 #### Insert 2023-07-28T10:58:23,091 It is recommended to use insertTablet to help improve write efficiency. 2023-07-28T10:58:23,092 * Insert a Tablet,which is multiple rows of a device, each row has the same measurements 2023-07-28T10:58:23,092 * **Better Write Performance** 2023-07-28T10:58:23,093 * **Support null values**: fill the null value with any value, and then mark the null value via BitMap (from v0.13) 2023-07-28T10:58:23,093 We have two implementations of Tablet in Python API. 2023-07-28T10:58:23,094 * Normal Tablet 2023-07-28T10:58:23,095 ```python 2023-07-28T10:58:23,095 values_ = [ 2023-07-28T10:58:23,095 [False, 10, 11, 1.1, 10011.1, "test01"], 2023-07-28T10:58:23,096 [True, 100, 11111, 1.25, 101.0, "test02"], 2023-07-28T10:58:23,096 [False, 100, 1, 188.1, 688.25, "test03"], 2023-07-28T10:58:23,096 [True, 0, 0, 0, 6.25, "test04"], 2023-07-28T10:58:23,096 ] 2023-07-28T10:58:23,097 timestamps_ = [1, 2, 3, 4] 2023-07-28T10:58:23,097 tablet_ = Tablet( 2023-07-28T10:58:23,097 device_id, measurements_, data_types_, values_, timestamps_ 2023-07-28T10:58:23,098 ) 2023-07-28T10:58:23,098 session.insert_tablet(tablet_) 2023-07-28T10:58:23,099 values_ = [ 2023-07-28T10:58:23,099 [None, 10, 11, 1.1, 10011.1, "test01"], 2023-07-28T10:58:23,099 [True, None, 11111, 1.25, 101.0, "test02"], 2023-07-28T10:58:23,100 [False, 100, None, 188.1, 688.25, "test03"], 2023-07-28T10:58:23,100 [True, 0, 0, 0, None, None], 2023-07-28T10:58:23,100 ] 2023-07-28T10:58:23,100 timestamps_ = [16, 17, 18, 19] 2023-07-28T10:58:23,101 tablet_ = Tablet( 2023-07-28T10:58:23,101 device_id, measurements_, data_types_, values_, timestamps_ 2023-07-28T10:58:23,101 ) 2023-07-28T10:58:23,102 session.insert_tablet(tablet_) 2023-07-28T10:58:23,102 ``` 2023-07-28T10:58:23,102 * Numpy Tablet 2023-07-28T10:58:23,103 Comparing with Tablet, Numpy Tablet is using [numpy.ndarray](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html) to record data. 2023-07-28T10:58:23,103 With less memory footprint and time cost of serialization, the insert performance will be better. 2023-07-28T10:58:23,104 **Notice** 2023-07-28T10:58:23,104 1. time and value columns in Tablet are ndarray. 2023-07-28T10:58:23,104 2. recommended to use the specific dtypes to each ndarray, see the example below 2023-07-28T10:58:23,105 (if not, the default dtypes are also ok). 2023-07-28T10:58:23,105 ```python 2023-07-28T10:58:23,106 import numpy as np 2023-07-28T10:58:23,106 data_types_ = [ 2023-07-28T10:58:23,106 TSDataType.BOOLEAN, 2023-07-28T10:58:23,107 TSDataType.INT32, 2023-07-28T10:58:23,107 TSDataType.INT64, 2023-07-28T10:58:23,107 TSDataType.FLOAT, 2023-07-28T10:58:23,108 TSDataType.DOUBLE, 2023-07-28T10:58:23,108 TSDataType.TEXT, 2023-07-28T10:58:23,108 ] 2023-07-28T10:58:23,108 np_values_ = [ 2023-07-28T10:58:23,109 np.array([False, True, False, True], TSDataType.BOOLEAN.np_dtype()), 2023-07-28T10:58:23,109 np.array([10, 100, 100, 0], TSDataType.INT32.np_dtype()), 2023-07-28T10:58:23,109 np.array([11, 11111, 1, 0], TSDataType.INT64.np_dtype()), 2023-07-28T10:58:23,110 np.array([1.1, 1.25, 188.1, 0], TSDataType.FLOAT.np_dtype()), 2023-07-28T10:58:23,110 np.array([10011.1, 101.0, 688.25, 6.25], TSDataType.DOUBLE.np_dtype()), 2023-07-28T10:58:23,110 np.array(["test01", "test02", "test03", "test04"], TSDataType.TEXT.np_dtype()), 2023-07-28T10:58:23,111 ] 2023-07-28T10:58:23,111 np_timestamps_ = np.array([1, 2, 3, 4], TSDataType.INT64.np_dtype()) 2023-07-28T10:58:23,111 np_tablet_ = NumpyTablet( 2023-07-28T10:58:23,111 device_id, measurements_, data_types_, np_values_, np_timestamps_ 2023-07-28T10:58:23,112 ) 2023-07-28T10:58:23,112 session.insert_tablet(np_tablet_) 2023-07-28T10:58:23,113 # insert one numpy tablet with none into the database. 2023-07-28T10:58:23,113 np_values_ = [ 2023-07-28T10:58:23,113 np.array([False, True, False, True], TSDataType.BOOLEAN.np_dtype()), 2023-07-28T10:58:23,113 np.array([10, 100, 100, 0], TSDataType.INT32.np_dtype()), 2023-07-28T10:58:23,114 np.array([11, 11111, 1, 0], TSDataType.INT64.np_dtype()), 2023-07-28T10:58:23,114 np.array([1.1, 1.25, 188.1, 0], TSDataType.FLOAT.np_dtype()), 2023-07-28T10:58:23,114 np.array([10011.1, 101.0, 688.25, 6.25], TSDataType.DOUBLE.np_dtype()), 2023-07-28T10:58:23,115 np.array(["test01", "test02", "test03", "test04"], TSDataType.TEXT.np_dtype()), 2023-07-28T10:58:23,115 ] 2023-07-28T10:58:23,115 np_timestamps_ = np.array([98, 99, 100, 101], TSDataType.INT64.np_dtype()) 2023-07-28T10:58:23,116 np_bitmaps_ = [] 2023-07-28T10:58:23,116 for i in range(len(measurements_)): 2023-07-28T10:58:23,116 np_bitmaps_.append(BitMap(len(np_timestamps_))) 2023-07-28T10:58:23,116 np_bitmaps_[0].mark(0) 2023-07-28T10:58:23,117 np_bitmaps_[1].mark(1) 2023-07-28T10:58:23,117 np_bitmaps_[2].mark(2) 2023-07-28T10:58:23,117 np_bitmaps_[4].mark(3) 2023-07-28T10:58:23,118 np_bitmaps_[5].mark(3) 2023-07-28T10:58:23,118 np_tablet_with_none = NumpyTablet( 2023-07-28T10:58:23,118 device_id, measurements_, data_types_, np_values_, np_timestamps_, np_bitmaps_ 2023-07-28T10:58:23,118 ) 2023-07-28T10:58:23,119 session.insert_tablet(np_tablet_with_none) 2023-07-28T10:58:23,119 ``` 2023-07-28T10:58:23,120 * Insert multiple Tablets 2023-07-28T10:58:23,120 ```python 2023-07-28T10:58:23,120 session.insert_tablets(tablet_lst) 2023-07-28T10:58:23,121 ``` 2023-07-28T10:58:23,121 * Insert a Record 2023-07-28T10:58:23,122 ```python 2023-07-28T10:58:23,122 session.insert_record(device_id, timestamp, measurements_, data_types_, values_) 2023-07-28T10:58:23,123 ``` 2023-07-28T10:58:23,123 * Insert multiple Records 2023-07-28T10:58:23,124 ```python 2023-07-28T10:58:23,124 session.insert_records( 2023-07-28T10:58:23,124 device_ids_, time_list_, measurements_list_, data_type_list_, values_list_ 2023-07-28T10:58:23,125 ) 2023-07-28T10:58:23,125 ``` 2023-07-28T10:58:23,126 * Insert multiple Records that belong to the same device. 2023-07-28T10:58:23,126 With type info the server has no need to do type inference, which leads a better performance 2023-07-28T10:58:23,127 ```python 2023-07-28T10:58:23,127 session.insert_records_of_one_device(device_id, time_list, measurements_list, data_types_list, values_list) 2023-07-28T10:58:23,128 ``` 2023-07-28T10:58:23,128 #### Insert with type inference 2023-07-28T10:58:23,129 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-07-28T10:58:23,130 * Insert a Record, which contains multiple measurement value of a device at a timestamp 2023-07-28T10:58:23,130 ```python 2023-07-28T10:58:23,130 session.insert_str_record(device_id, timestamp, measurements, string_values) 2023-07-28T10:58:23,131 ``` 2023-07-28T10:58:23,131 #### Insert of Aligned Timeseries 2023-07-28T10:58:23,132 The Insert of aligned timeseries uses interfaces like insert_aligned_XXX, and others are similar to the above interfaces: 2023-07-28T10:58:23,133 * insert_aligned_record 2023-07-28T10:58:23,133 * insert_aligned_records 2023-07-28T10:58:23,134 * insert_aligned_records_of_one_device 2023-07-28T10:58:23,134 * insert_aligned_tablet 2023-07-28T10:58:23,135 * insert_aligned_tablets 2023-07-28T10:58:23,136 ### IoTDB-SQL Interface 2023-07-28T10:58:23,136 * Execute query statement 2023-07-28T10:58:23,137 ```python 2023-07-28T10:58:23,137 session.execute_query_statement(sql) 2023-07-28T10:58:23,137 ``` 2023-07-28T10:58:23,138 * Execute non query statement 2023-07-28T10:58:23,139 ```python 2023-07-28T10:58:23,139 session.execute_non_query_statement(sql) 2023-07-28T10:58:23,139 ``` 2023-07-28T10:58:23,140 * Execute statement 2023-07-28T10:58:23,141 ```python 2023-07-28T10:58:23,141 session.execute_statement(sql) 2023-07-28T10:58:23,141 ``` 2023-07-28T10:58:23,142 ### Schema Template 2023-07-28T10:58:23,142 #### Create Schema Template 2023-07-28T10:58:23,142 The step for creating a metadata template is as follows 2023-07-28T10:58:23,143 1. Create the template class 2023-07-28T10:58:23,143 2. Adding child Node,InternalNode and MeasurementNode can be chose 2023-07-28T10:58:23,143 3. Execute create schema template function 2023-07-28T10:58:23,144 ```python 2023-07-28T10:58:23,144 template = Template(name=template_name, share_time=True) 2023-07-28T10:58:23,145 i_node_gps = InternalNode(name="GPS", share_time=False) 2023-07-28T10:58:23,145 i_node_v = InternalNode(name="vehicle", share_time=True) 2023-07-28T10:58:23,146 m_node_x = MeasurementNode("x", TSDataType.FLOAT, TSEncoding.RLE, Compressor.SNAPPY) 2023-07-28T10:58:23,146 i_node_gps.add_child(m_node_x) 2023-07-28T10:58:23,147 i_node_v.add_child(m_node_x) 2023-07-28T10:58:23,147 template.add_template(i_node_gps) 2023-07-28T10:58:23,148 template.add_template(i_node_v) 2023-07-28T10:58:23,148 template.add_template(m_node_x) 2023-07-28T10:58:23,149 session.create_schema_template(template) 2023-07-28T10:58:23,149 ``` 2023-07-28T10:58:23,150 #### Modify Schema Template nodes 2023-07-28T10:58:23,150 Modify nodes in a template, the template must be already created. These are functions that add or delete some measurement nodes. 2023-07-28T10:58:23,151 * add node in template 2023-07-28T10:58:23,151 ```python 2023-07-28T10:58:23,151 session.add_measurements_in_template(template_name, measurements_path, data_types, encodings, compressors, is_aligned) 2023-07-28T10:58:23,152 ``` 2023-07-28T10:58:23,152 * delete node in template 2023-07-28T10:58:23,153 ```python 2023-07-28T10:58:23,153 session.delete_node_in_template(template_name, path) 2023-07-28T10:58:23,153 ``` 2023-07-28T10:58:23,154 #### Set Schema Template 2023-07-28T10:58:23,154 ```python 2023-07-28T10:58:23,155 session.set_schema_template(template_name, prefix_path) 2023-07-28T10:58:23,155 ``` 2023-07-28T10:58:23,156 #### Uset Schema Template 2023-07-28T10:58:23,156 ```python 2023-07-28T10:58:23,156 session.unset_schema_template(template_name, prefix_path) 2023-07-28T10:58:23,156 ``` 2023-07-28T10:58:23,157 #### Show Schema Template 2023-07-28T10:58:23,157 * Show all schema templates 2023-07-28T10:58:23,158 ```python 2023-07-28T10:58:23,158 session.show_all_templates() 2023-07-28T10:58:23,158 ``` 2023-07-28T10:58:23,158 * Count all nodes in templates 2023-07-28T10:58:23,159 ```python 2023-07-28T10:58:23,159 session.count_measurements_in_template(template_name) 2023-07-28T10:58:23,159 ``` 2023-07-28T10:58:23,160 * Judge whether the path is measurement or not in templates, This measurement must be in the template 2023-07-28T10:58:23,160 ```python 2023-07-28T10:58:23,160 session.count_measurements_in_template(template_name, path) 2023-07-28T10:58:23,161 ``` 2023-07-28T10:58:23,161 * Judge whether the path is exist or not in templates, This path may not belong to the template 2023-07-28T10:58:23,162 ```python 2023-07-28T10:58:23,162 session.is_path_exist_in_template(template_name, path) 2023-07-28T10:58:23,162 ``` 2023-07-28T10:58:23,163 * Show nodes under in schema template 2023-07-28T10:58:23,163 ```python 2023-07-28T10:58:23,163 session.show_measurements_in_template(template_name) 2023-07-28T10:58:23,164 ``` 2023-07-28T10:58:23,164 * Show the path prefix where a schema template is set 2023-07-28T10:58:23,164 ```python 2023-07-28T10:58:23,165 session.show_paths_template_set_on(template_name) 2023-07-28T10:58:23,165 ``` 2023-07-28T10:58:23,166 * Show the path prefix where a schema template is used (i.e. the time series has been created) 2023-07-28T10:58:23,166 ```python 2023-07-28T10:58:23,166 session.show_paths_template_using_on(template_name) 2023-07-28T10:58:23,167 ``` 2023-07-28T10:58:23,167 #### Drop Schema Template 2023-07-28T10:58:23,167 Delete an existing metadata template,dropping an already set template is not supported 2023-07-28T10:58:23,168 ```python 2023-07-28T10:58:23,168 session.drop_schema_template("template_python") 2023-07-28T10:58:23,168 ``` 2023-07-28T10:58:23,169 ### Pandas Support 2023-07-28T10:58:23,170 To easily transform a query result to a [Pandas Dataframe](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html) 2023-07-28T10:58:23,170 the SessionDataSet has a method `.todf()` which consumes the dataset and transforms it to a pandas dataframe. 2023-07-28T10:58:23,171 Example: 2023-07-28T10:58:23,171 ```python 2023-07-28T10:58:23,172 from iotdb.Session import Session 2023-07-28T10:58:23,172 ip = "127.0.0.1" 2023-07-28T10:58:23,173 port_ = "6667" 2023-07-28T10:58:23,173 username_ = "root" 2023-07-28T10:58:23,173 password_ = "root" 2023-07-28T10:58:23,173 session = Session(ip, port_, username_, password_) 2023-07-28T10:58:23,174 session.open(False) 2023-07-28T10:58:23,174 result = session.execute_query_statement("SELECT * FROM root.*") 2023-07-28T10:58:23,175 # Transform to Pandas Dataset 2023-07-28T10:58:23,175 df = result.todf() 2023-07-28T10:58:23,176 session.close() 2023-07-28T10:58:23,176 # Now you can work with the dataframe 2023-07-28T10:58:23,176 df = ... 2023-07-28T10:58:23,177 ``` 2023-07-28T10:58:23,178 ### IoTDB Testcontainer 2023-07-28T10:58:23,178 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-07-28T10:58:23,179 To start (and stop) an IoTDB Database in a Docker container simply do: 2023-07-28T10:58:23,179 ```python 2023-07-28T10:58:23,179 class MyTestCase(unittest.TestCase): 2023-07-28T10:58:23,180 def test_something(self): 2023-07-28T10:58:23,180 with IoTDBContainer() as c: 2023-07-28T10:58:23,181 session = Session("localhost", c.get_exposed_port(6667), "root", "root") 2023-07-28T10:58:23,181 session.open(False) 2023-07-28T10:58:23,181 result = session.execute_query_statement("SHOW TIMESERIES") 2023-07-28T10:58:23,182 print(result) 2023-07-28T10:58:23,182 session.close() 2023-07-28T10:58:23,182 ``` 2023-07-28T10:58:23,183 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-07-28T10:58:23,184 ### IoTDB DBAPI 2023-07-28T10:58:23,184 IoTDB DBAPI implements the Python DB API 2.0 specification (https://peps.python.org/pep-0249/), which defines a common 2023-07-28T10:58:23,185 interface for accessing databases in Python. 2023-07-28T10:58:23,185 #### Examples 2023-07-28T10:58:23,186 + Initialization 2023-07-28T10:58:23,186 The initialized parameters are consistent with the session part (except for the sqlalchemy_mode). 2023-07-28T10:58:23,187 ```python 2023-07-28T10:58:23,187 from iotdb.dbapi import connect 2023-07-28T10:58:23,188 ip = "127.0.0.1" 2023-07-28T10:58:23,188 port_ = "6667" 2023-07-28T10:58:23,188 username_ = "root" 2023-07-28T10:58:23,188 password_ = "root" 2023-07-28T10:58:23,189 conn = connect(ip, port_, username_, password_,fetch_size=1024,zone_id="UTC+8",sqlalchemy_mode=False) 2023-07-28T10:58:23,189 cursor = conn.cursor() 2023-07-28T10:58:23,189 ``` 2023-07-28T10:58:23,190 + simple SQL statement execution 2023-07-28T10:58:23,190 ```python 2023-07-28T10:58:23,190 cursor.execute("SELECT * FROM root.*") 2023-07-28T10:58:23,191 for row in cursor.fetchall(): 2023-07-28T10:58:23,191 print(row) 2023-07-28T10:58:23,191 ``` 2023-07-28T10:58:23,192 + execute SQL with parameter 2023-07-28T10:58:23,193 IoTDB DBAPI supports pyformat style parameters 2023-07-28T10:58:23,193 ```python 2023-07-28T10:58:23,193 cursor.execute("SELECT * FROM root.* WHERE time < %(time)s",{"time":"2017-11-01T00:08:00.000"}) 2023-07-28T10:58:23,193 for row in cursor.fetchall(): 2023-07-28T10:58:23,194 print(row) 2023-07-28T10:58:23,194 ``` 2023-07-28T10:58:23,195 + execute SQL with parameter sequences 2023-07-28T10:58:23,195 ```python 2023-07-28T10:58:23,195 seq_of_parameters = [ 2023-07-28T10:58:23,195 {"timestamp": 1, "temperature": 1}, 2023-07-28T10:58:23,196 {"timestamp": 2, "temperature": 2}, 2023-07-28T10:58:23,196 {"timestamp": 3, "temperature": 3}, 2023-07-28T10:58:23,196 {"timestamp": 4, "temperature": 4}, 2023-07-28T10:58:23,197 {"timestamp": 5, "temperature": 5}, 2023-07-28T10:58:23,197 ] 2023-07-28T10:58:23,197 sql = "insert into root.cursor(timestamp,temperature) values(%(timestamp)s,%(temperature)s)" 2023-07-28T10:58:23,197 cursor.executemany(sql,seq_of_parameters) 2023-07-28T10:58:23,198 ``` 2023-07-28T10:58:23,198 + close the connection and cursor 2023-07-28T10:58:23,199 ```python 2023-07-28T10:58:23,199 cursor.close() 2023-07-28T10:58:23,199 conn.close() 2023-07-28T10:58:23,200 ``` 2023-07-28T10:58:23,200 ### IoTDB SQLAlchemy Dialect (Experimental) 2023-07-28T10:58:23,201 The SQLAlchemy dialect of IoTDB is written to adapt to Apache Superset. 2023-07-28T10:58:23,201 This part is still being improved. 2023-07-28T10:58:23,201 Please do not use it in the production environment! 2023-07-28T10:58:23,201 #### Mapping of the metadata 2023-07-28T10:58:23,202 The data model used by SQLAlchemy is a relational data model, which describes the relationships between different entities through tables. 2023-07-28T10:58:23,202 While the data model of IoTDB is a hierarchical data model, which organizes the data through a tree structure. 2023-07-28T10:58:23,202 In order to adapt IoTDB to the dialect of SQLAlchemy, the original data model in IoTDB needs to be reorganized. 2023-07-28T10:58:23,203 Converting the data model of IoTDB into the data model of SQLAlchemy. 2023-07-28T10:58:23,203 The metadata in the IoTDB are: 2023-07-28T10:58:23,204 1. Database 2023-07-28T10:58:23,204 2. Path 2023-07-28T10:58:23,205 3. Entity 2023-07-28T10:58:23,205 4. Measurement 2023-07-28T10:58:23,206 The metadata in the SQLAlchemy are: 2023-07-28T10:58:23,206 1. Schema 2023-07-28T10:58:23,206 2. Table 2023-07-28T10:58:23,207 3. Column 2023-07-28T10:58:23,207 The mapping relationship between them is: 2023-07-28T10:58:23,208 | The metadata in the SQLAlchemy | The metadata in the IoTDB | 2023-07-28T10:58:23,208 | -------------------- | ---------------------------------------------- | 2023-07-28T10:58:23,208 | Schema | Database | 2023-07-28T10:58:23,209 | Table | Path ( from database to entity ) + Entity | 2023-07-28T10:58:23,209 | Column | Measurement | 2023-07-28T10:58:23,210 The following figure shows the relationship between the two more intuitively: 2023-07-28T10:58:23,210 ![sqlalchemy-to-iotdb](https://github.com/apache/iotdb-bin-resources/blob/main/docs/UserGuide/API/IoTDB-SQLAlchemy/sqlalchemy-to-iotdb.png?raw=true) 2023-07-28T10:58:23,211 #### Data type mapping 2023-07-28T10:58:23,211 | data type in IoTDB | data type in SQLAlchemy | 2023-07-28T10:58:23,212 |--------------------|-------------------------| 2023-07-28T10:58:23,212 | BOOLEAN | Boolean | 2023-07-28T10:58:23,212 | INT32 | Integer | 2023-07-28T10:58:23,213 | INT64 | BigInteger | 2023-07-28T10:58:23,213 | FLOAT | Float | 2023-07-28T10:58:23,213 | DOUBLE | Float | 2023-07-28T10:58:23,213 | TEXT | Text | 2023-07-28T10:58:23,214 | LONG | BigInteger | 2023-07-28T10:58:23,214 #### Example 2023-07-28T10:58:23,215 + execute statement 2023-07-28T10:58:23,215 ```python 2023-07-28T10:58:23,216 from sqlalchemy import create_engine 2023-07-28T10:58:23,216 engine = create_engine("iotdb://root:root@127.0.0.1:6667") 2023-07-28T10:58:23,217 connect = engine.connect() 2023-07-28T10:58:23,217 result = connect.execute("SELECT ** FROM root") 2023-07-28T10:58:23,217 for row in result.fetchall(): 2023-07-28T10:58:23,218 print(row) 2023-07-28T10:58:23,218 ``` 2023-07-28T10:58:23,218 + ORM (now only simple queries are supported) 2023-07-28T10:58:23,219 ```python 2023-07-28T10:58:23,219 from sqlalchemy import create_engine, Column, Float, BigInteger, MetaData 2023-07-28T10:58:23,220 from sqlalchemy.ext.declarative import declarative_base 2023-07-28T10:58:23,220 from sqlalchemy.orm import sessionmaker 2023-07-28T10:58:23,221 metadata = MetaData( 2023-07-28T10:58:23,221 schema='root.factory' 2023-07-28T10:58:23,221 ) 2023-07-28T10:58:23,222 Base = declarative_base(metadata=metadata) 2023-07-28T10:58:23,223 class Device(Base): 2023-07-28T10:58:23,223 __tablename__ = "room2.device1" 2023-07-28T10:58:23,223 Time = Column(BigInteger, primary_key=True) 2023-07-28T10:58:23,223 temperature = Column(Float) 2023-07-28T10:58:23,224 status = Column(Float) 2023-07-28T10:58:23,225 engine = create_engine("iotdb://root:root@127.0.0.1:6667") 2023-07-28T10:58:23,225 DbSession = sessionmaker(bind=engine) 2023-07-28T10:58:23,226 session = DbSession() 2023-07-28T10:58:23,226 res = session.query(Device.status).filter(Device.temperature > 1) 2023-07-28T10:58:23,227 for row in res: 2023-07-28T10:58:23,227 print(row) 2023-07-28T10:58:23,228 ``` 2023-07-28T10:58:23,228 ## Developers 2023-07-28T10:58:23,229 ### Introduction 2023-07-28T10:58:23,230 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-07-28T10:58:23,231 ### Prerequisites 2023-07-28T10:58:23,232 Python3.7 or later is preferred. 2023-07-28T10:58:23,232 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-07-28T10:58:23,233 ``` 2023-07-28T10:58:23,233 http://thrift.apache.org/docs/install/ 2023-07-28T10:58:23,233 ``` 2023-07-28T10:58:23,234 Before starting you need to install `requirements_dev.txt` in your python environment, e.g. by calling 2023-07-28T10:58:23,234 ```shell 2023-07-28T10:58:23,235 pip install -r requirements_dev.txt 2023-07-28T10:58:23,235 ``` 2023-07-28T10:58:23,236 ### Compile the thrift library and Debug 2023-07-28T10:58:23,237 In the root of IoTDB's source code folder, run `mvn clean generate-sources -pl client-py -am`. 2023-07-28T10:58:23,238 This will automatically delete and repopulate the folder `iotdb/thrift` with the generated thrift files. 2023-07-28T10:58:23,238 This folder is ignored from git and should **never be pushed to git!** 2023-07-28T10:58:23,239 **Notice** Do not upload `iotdb/thrift` to the git repo. 2023-07-28T10:58:23,240 ### Session Client & Example 2023-07-28T10:58:23,241 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-07-28T10:58:23,242 Or, another simple example: 2023-07-28T10:58:23,242 ```python 2023-07-28T10:58:23,243 from iotdb.Session import Session 2023-07-28T10:58:23,243 ip = "127.0.0.1" 2023-07-28T10:58:23,244 port_ = "6667" 2023-07-28T10:58:23,244 username_ = "root" 2023-07-28T10:58:23,244 password_ = "root" 2023-07-28T10:58:23,245 session = Session(ip, port_, username_, password_) 2023-07-28T10:58:23,245 session.open(False) 2023-07-28T10:58:23,245 zone = session.get_time_zone() 2023-07-28T10:58:23,246 session.close() 2023-07-28T10:58:23,246 ``` 2023-07-28T10:58:23,247 ### Tests 2023-07-28T10:58:23,248 Please add your custom tests in `tests` folder. 2023-07-28T10:58:23,248 To run all defined tests just type `pytest .` in the root folder. 2023-07-28T10:58:23,249 **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-07-28T10:58:23,250 ### Futher Tools 2023-07-28T10:58:23,251 [black](https://pypi.org/project/black/) and [flake8](https://pypi.org/project/flake8/) are installed for autoformatting and linting. 2023-07-28T10:58:23,251 Both can be run by `black .` or `flake8 .` respectively. 2023-07-28T10:58:23,253 ## Releasing 2023-07-28T10:58:23,253 To do a release just ensure that you have the right set of generated thrift files. 2023-07-28T10:58:23,253 Then run linting and auto-formatting. 2023-07-28T10:58:23,254 Then, ensure that all tests work (via `pytest .`). 2023-07-28T10:58:23,254 Then you are good to go to do a release! 2023-07-28T10:58:23,255 ### Preparing your environment 2023-07-28T10:58:23,256 First, install all necessary dev dependencies via `pip install -r requirements_dev.txt`. 2023-07-28T10:58:23,257 ### Doing the Release 2023-07-28T10:58:23,258 There is a convenient script `release.sh` to do all steps for a release. 2023-07-28T10:58:23,258 Namely, these are 2023-07-28T10:58:23,259 * Remove all transient directories from last release (if exists) 2023-07-28T10:58:23,259 * (Re-)generate all generated sources via mvn 2023-07-28T10:58:23,259 * Run Linting (flake8) 2023-07-28T10:58:23,260 * Run Tests via pytest 2023-07-28T10:58:23,260 * Build 2023-07-28T10:58:23,260 * Release to pypi 2023-07-28T10:58:23,262 running dist_info 2023-07-28T10:58:23,262 creating /tmp/pip-modern-metadata-wv6awfhb/apache_iotdb.egg-info 2023-07-28T10:58:23,262 writing /tmp/pip-modern-metadata-wv6awfhb/apache_iotdb.egg-info/PKG-INFO 2023-07-28T10:58:23,264 writing dependency_links to /tmp/pip-modern-metadata-wv6awfhb/apache_iotdb.egg-info/dependency_links.txt 2023-07-28T10:58:23,268 writing entry points to /tmp/pip-modern-metadata-wv6awfhb/apache_iotdb.egg-info/entry_points.txt 2023-07-28T10:58:23,271 writing requirements to /tmp/pip-modern-metadata-wv6awfhb/apache_iotdb.egg-info/requires.txt 2023-07-28T10:58:23,274 writing top-level names to /tmp/pip-modern-metadata-wv6awfhb/apache_iotdb.egg-info/top_level.txt 2023-07-28T10:58:23,278 writing manifest file '/tmp/pip-modern-metadata-wv6awfhb/apache_iotdb.egg-info/SOURCES.txt' 2023-07-28T10:58:23,346 reading manifest file '/tmp/pip-modern-metadata-wv6awfhb/apache_iotdb.egg-info/SOURCES.txt' 2023-07-28T10:58:23,351 adding license file 'LICENSE' 2023-07-28T10:58:23,362 writing manifest file '/tmp/pip-modern-metadata-wv6awfhb/apache_iotdb.egg-info/SOURCES.txt' 2023-07-28T10:58:23,365 creating '/tmp/pip-modern-metadata-wv6awfhb/apache_iotdb-1.1.2.dist-info' 2023-07-28T10:58:23,583 /tmp/pip-build-env-1hef8z5g/overlay/lib/python3.7/site-packages/setuptools/_distutils/dist.py:265: UserWarning: Unknown distribution option: 'website' 2023-07-28T10:58:23,584 warnings.warn(msg) 2023-07-28T10:58:23,710 Preparing metadata (pyproject.toml): finished with status 'done' 2023-07-28T10:58:23,730 Source in /tmp/pip-wheel-a5k7t_ek/apache-iotdb_bdeab818e3cd4936a5bec3277dc47295 has version 1.1.2, which satisfies requirement apache-iotdb==1.1.2 from https://files.pythonhosted.org/packages/51/36/6e73e46e1d6b2d2272a5a1b369da16dd36a3120aa883ea86d2a9a85ce105/apache-iotdb-1.1.2.tar.gz 2023-07-28T10:58:23,732 Removed apache-iotdb==1.1.2 from https://files.pythonhosted.org/packages/51/36/6e73e46e1d6b2d2272a5a1b369da16dd36a3120aa883ea86d2a9a85ce105/apache-iotdb-1.1.2.tar.gz from build tracker '/tmp/pip-build-tracker-xkvwt5eb' 2023-07-28T10:58:23,752 Created temporary directory: /tmp/pip-unpack-ege88flu 2023-07-28T10:58:23,753 Building wheels for collected packages: apache-iotdb 2023-07-28T10:58:23,763 Created temporary directory: /tmp/pip-wheel-8ll9kzfd 2023-07-28T10:58:23,763 Destination directory: /tmp/pip-wheel-8ll9kzfd 2023-07-28T10:58:23,769 Building wheel for apache-iotdb (pyproject.toml): started 2023-07-28T10:58:23,771 Running command Building wheel for apache-iotdb (pyproject.toml) 2023-07-28T10:58:24,859 2023-07-28T10:58:24,867 # Apache IoTDB 2023-07-28T10:58:24,867 [![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-07-28T10:58:24,868 [![GitHub release](https://img.shields.io/github/release/apache/iotdb.svg)](https://github.com/apache/iotdb/releases) 2023-07-28T10:58:24,868 [![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html) 2023-07-28T10:58:24,869 ![](https://github-size-badge.herokuapp.com/apache/iotdb.svg) 2023-07-28T10:58:24,869 ![](https://img.shields.io/github/downloads/apache/iotdb/total.svg) 2023-07-28T10:58:24,869 ![](https://img.shields.io/badge/platform-win%20%7C%20macos%20%7C%20linux-yellow.svg) 2023-07-28T10:58:24,869 [![IoTDB Website](https://img.shields.io/website-up-down-green-red/https/shields.io.svg?label=iotdb-website)](https://iotdb.apache.org/) 2023-07-28T10:58:24,870 Apache IoTDB (Database for Internet of Things) is an IoT native database with high performance for 2023-07-28T10:58:24,871 data management and analysis, deployable on the edge and the cloud. Due to its light-weight 2023-07-28T10:58:24,871 architecture, high performance and rich feature set together with its deep integration with 2023-07-28T10:58:24,871 Apache Hadoop, Spark and Flink, Apache IoTDB can meet the requirements of massive data storage, 2023-07-28T10:58:24,872 high-speed data ingestion and complex data analysis in the IoT industrial fields. 2023-07-28T10:58:24,872 ## Python Native API 2023-07-28T10:58:24,873 ### Requirements 2023-07-28T10:58:24,874 You have to install thrift (>=0.13) before using the package. 2023-07-28T10:58:24,875 ### How to use (Example) 2023-07-28T10:58:24,876 First, download the latest package: `pip3 install apache-iotdb` 2023-07-28T10:58:24,876 *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-07-28T10:58:24,877 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-07-28T10:58:24,878 An example of aligned timeseries: [Aligned Timeseries Session Example](https://github.com/apache/iotdb/blob/master/client-py/SessionAlignedTimeseriesExample.py) 2023-07-28T10:58:24,878 (you need to add `import iotdb` in the head of the file) 2023-07-28T10:58:24,879 Or: 2023-07-28T10:58:24,880 ```python 2023-07-28T10:58:24,880 from iotdb.Session import Session 2023-07-28T10:58:24,881 ip = "127.0.0.1" 2023-07-28T10:58:24,881 port_ = "6667" 2023-07-28T10:58:24,881 username_ = "root" 2023-07-28T10:58:24,881 password_ = "root" 2023-07-28T10:58:24,882 session = Session(ip, port_, username_, password_) 2023-07-28T10:58:24,882 session.open(False) 2023-07-28T10:58:24,882 zone = session.get_time_zone() 2023-07-28T10:58:24,883 session.close() 2023-07-28T10:58:24,883 ``` 2023-07-28T10:58:24,884 ### Initialization 2023-07-28T10:58:24,884 * Initialize a Session 2023-07-28T10:58:24,885 ```python 2023-07-28T10:58:24,885 session = Session(ip, port_, username_, password_, fetch_size=1024, zone_id="UTC+8") 2023-07-28T10:58:24,886 ``` 2023-07-28T10:58:24,886 * Open a session, with a parameter to specify whether to enable RPC compression 2023-07-28T10:58:24,887 ```python 2023-07-28T10:58:24,887 session.open(enable_rpc_compression=False) 2023-07-28T10:58:24,887 ``` 2023-07-28T10:58:24,888 Notice: this RPC compression status of client must comply with that of IoTDB server 2023-07-28T10:58:24,889 * Close a Session 2023-07-28T10:58:24,889 ```python 2023-07-28T10:58:24,889 session.close() 2023-07-28T10:58:24,890 ``` 2023-07-28T10:58:24,890 ### Data Definition Interface (DDL Interface) 2023-07-28T10:58:24,891 #### DATABASE Management 2023-07-28T10:58:24,892 * CREATE DATABASE 2023-07-28T10:58:24,892 ```python 2023-07-28T10:58:24,892 session.set_storage_group(group_name) 2023-07-28T10:58:24,893 ``` 2023-07-28T10:58:24,893 * Delete one or several databases 2023-07-28T10:58:24,894 ```python 2023-07-28T10:58:24,894 session.delete_storage_group(group_name) 2023-07-28T10:58:24,895 session.delete_storage_groups(group_name_lst) 2023-07-28T10:58:24,895 ``` 2023-07-28T10:58:24,895 #### Timeseries Management 2023-07-28T10:58:24,896 * Create one or multiple timeseries 2023-07-28T10:58:24,897 ```python 2023-07-28T10:58:24,897 session.create_time_series(ts_path, data_type, encoding, compressor, 2023-07-28T10:58:24,897 props=None, tags=None, attributes=None, alias=None) 2023-07-28T10:58:24,898 session.create_multi_time_series( 2023-07-28T10:58:24,898 ts_path_lst, data_type_lst, encoding_lst, compressor_lst, 2023-07-28T10:58:24,899 props_lst=None, tags_lst=None, attributes_lst=None, alias_lst=None 2023-07-28T10:58:24,899 ) 2023-07-28T10:58:24,899 ``` 2023-07-28T10:58:24,900 * Create aligned timeseries 2023-07-28T10:58:24,900 ```python 2023-07-28T10:58:24,901 session.create_aligned_time_series( 2023-07-28T10:58:24,901 device_id, measurements_lst, data_type_lst, encoding_lst, compressor_lst 2023-07-28T10:58:24,901 ) 2023-07-28T10:58:24,901 ``` 2023-07-28T10:58:24,902 Attention: Alias of measurements are **not supported** currently. 2023-07-28T10:58:24,903 * Delete one or several timeseries 2023-07-28T10:58:24,903 ```python 2023-07-28T10:58:24,904 session.delete_time_series(paths_list) 2023-07-28T10:58:24,904 ``` 2023-07-28T10:58:24,905 * Check whether the specific timeseries exists 2023-07-28T10:58:24,905 ```python 2023-07-28T10:58:24,906 session.check_time_series_exists(path) 2023-07-28T10:58:24,906 ``` 2023-07-28T10:58:24,906 ### Data Manipulation Interface (DML Interface) 2023-07-28T10:58:24,907 #### Insert 2023-07-28T10:58:24,908 It is recommended to use insertTablet to help improve write efficiency. 2023-07-28T10:58:24,908 * Insert a Tablet,which is multiple rows of a device, each row has the same measurements 2023-07-28T10:58:24,909 * **Better Write Performance** 2023-07-28T10:58:24,909 * **Support null values**: fill the null value with any value, and then mark the null value via BitMap (from v0.13) 2023-07-28T10:58:24,910 We have two implementations of Tablet in Python API. 2023-07-28T10:58:24,911 * Normal Tablet 2023-07-28T10:58:24,911 ```python 2023-07-28T10:58:24,911 values_ = [ 2023-07-28T10:58:24,912 [False, 10, 11, 1.1, 10011.1, "test01"], 2023-07-28T10:58:24,912 [True, 100, 11111, 1.25, 101.0, "test02"], 2023-07-28T10:58:24,912 [False, 100, 1, 188.1, 688.25, "test03"], 2023-07-28T10:58:24,913 [True, 0, 0, 0, 6.25, "test04"], 2023-07-28T10:58:24,913 ] 2023-07-28T10:58:24,913 timestamps_ = [1, 2, 3, 4] 2023-07-28T10:58:24,914 tablet_ = Tablet( 2023-07-28T10:58:24,914 device_id, measurements_, data_types_, values_, timestamps_ 2023-07-28T10:58:24,914 ) 2023-07-28T10:58:24,914 session.insert_tablet(tablet_) 2023-07-28T10:58:24,915 values_ = [ 2023-07-28T10:58:24,915 [None, 10, 11, 1.1, 10011.1, "test01"], 2023-07-28T10:58:24,916 [True, None, 11111, 1.25, 101.0, "test02"], 2023-07-28T10:58:24,916 [False, 100, None, 188.1, 688.25, "test03"], 2023-07-28T10:58:24,916 [True, 0, 0, 0, None, None], 2023-07-28T10:58:24,917 ] 2023-07-28T10:58:24,917 timestamps_ = [16, 17, 18, 19] 2023-07-28T10:58:24,917 tablet_ = Tablet( 2023-07-28T10:58:24,917 device_id, measurements_, data_types_, values_, timestamps_ 2023-07-28T10:58:24,918 ) 2023-07-28T10:58:24,918 session.insert_tablet(tablet_) 2023-07-28T10:58:24,918 ``` 2023-07-28T10:58:24,919 * Numpy Tablet 2023-07-28T10:58:24,919 Comparing with Tablet, Numpy Tablet is using [numpy.ndarray](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html) to record data. 2023-07-28T10:58:24,919 With less memory footprint and time cost of serialization, the insert performance will be better. 2023-07-28T10:58:24,920 **Notice** 2023-07-28T10:58:24,920 1. time and value columns in Tablet are ndarray. 2023-07-28T10:58:24,921 2. recommended to use the specific dtypes to each ndarray, see the example below 2023-07-28T10:58:24,921 (if not, the default dtypes are also ok). 2023-07-28T10:58:24,921 ```python 2023-07-28T10:58:24,922 import numpy as np 2023-07-28T10:58:24,922 data_types_ = [ 2023-07-28T10:58:24,922 TSDataType.BOOLEAN, 2023-07-28T10:58:24,923 TSDataType.INT32, 2023-07-28T10:58:24,923 TSDataType.INT64, 2023-07-28T10:58:24,923 TSDataType.FLOAT, 2023-07-28T10:58:24,923 TSDataType.DOUBLE, 2023-07-28T10:58:24,924 TSDataType.TEXT, 2023-07-28T10:58:24,924 ] 2023-07-28T10:58:24,924 np_values_ = [ 2023-07-28T10:58:24,925 np.array([False, True, False, True], TSDataType.BOOLEAN.np_dtype()), 2023-07-28T10:58:24,925 np.array([10, 100, 100, 0], TSDataType.INT32.np_dtype()), 2023-07-28T10:58:24,925 np.array([11, 11111, 1, 0], TSDataType.INT64.np_dtype()), 2023-07-28T10:58:24,926 np.array([1.1, 1.25, 188.1, 0], TSDataType.FLOAT.np_dtype()), 2023-07-28T10:58:24,926 np.array([10011.1, 101.0, 688.25, 6.25], TSDataType.DOUBLE.np_dtype()), 2023-07-28T10:58:24,926 np.array(["test01", "test02", "test03", "test04"], TSDataType.TEXT.np_dtype()), 2023-07-28T10:58:24,926 ] 2023-07-28T10:58:24,927 np_timestamps_ = np.array([1, 2, 3, 4], TSDataType.INT64.np_dtype()) 2023-07-28T10:58:24,927 np_tablet_ = NumpyTablet( 2023-07-28T10:58:24,927 device_id, measurements_, data_types_, np_values_, np_timestamps_ 2023-07-28T10:58:24,928 ) 2023-07-28T10:58:24,928 session.insert_tablet(np_tablet_) 2023-07-28T10:58:24,929 # insert one numpy tablet with none into the database. 2023-07-28T10:58:24,929 np_values_ = [ 2023-07-28T10:58:24,929 np.array([False, True, False, True], TSDataType.BOOLEAN.np_dtype()), 2023-07-28T10:58:24,929 np.array([10, 100, 100, 0], TSDataType.INT32.np_dtype()), 2023-07-28T10:58:24,930 np.array([11, 11111, 1, 0], TSDataType.INT64.np_dtype()), 2023-07-28T10:58:24,930 np.array([1.1, 1.25, 188.1, 0], TSDataType.FLOAT.np_dtype()), 2023-07-28T10:58:24,930 np.array([10011.1, 101.0, 688.25, 6.25], TSDataType.DOUBLE.np_dtype()), 2023-07-28T10:58:24,931 np.array(["test01", "test02", "test03", "test04"], TSDataType.TEXT.np_dtype()), 2023-07-28T10:58:24,931 ] 2023-07-28T10:58:24,931 np_timestamps_ = np.array([98, 99, 100, 101], TSDataType.INT64.np_dtype()) 2023-07-28T10:58:24,931 np_bitmaps_ = [] 2023-07-28T10:58:24,932 for i in range(len(measurements_)): 2023-07-28T10:58:24,932 np_bitmaps_.append(BitMap(len(np_timestamps_))) 2023-07-28T10:58:24,932 np_bitmaps_[0].mark(0) 2023-07-28T10:58:24,933 np_bitmaps_[1].mark(1) 2023-07-28T10:58:24,933 np_bitmaps_[2].mark(2) 2023-07-28T10:58:24,933 np_bitmaps_[4].mark(3) 2023-07-28T10:58:24,933 np_bitmaps_[5].mark(3) 2023-07-28T10:58:24,934 np_tablet_with_none = NumpyTablet( 2023-07-28T10:58:24,934 device_id, measurements_, data_types_, np_values_, np_timestamps_, np_bitmaps_ 2023-07-28T10:58:24,934 ) 2023-07-28T10:58:24,935 session.insert_tablet(np_tablet_with_none) 2023-07-28T10:58:24,935 ``` 2023-07-28T10:58:24,936 * Insert multiple Tablets 2023-07-28T10:58:24,936 ```python 2023-07-28T10:58:24,937 session.insert_tablets(tablet_lst) 2023-07-28T10:58:24,938 ``` 2023-07-28T10:58:24,938 * Insert a Record 2023-07-28T10:58:24,939 ```python 2023-07-28T10:58:24,939 session.insert_record(device_id, timestamp, measurements_, data_types_, values_) 2023-07-28T10:58:24,939 ``` 2023-07-28T10:58:24,940 * Insert multiple Records 2023-07-28T10:58:24,941 ```python 2023-07-28T10:58:24,941 session.insert_records( 2023-07-28T10:58:24,941 device_ids_, time_list_, measurements_list_, data_type_list_, values_list_ 2023-07-28T10:58:24,942 ) 2023-07-28T10:58:24,942 ``` 2023-07-28T10:58:24,943 * Insert multiple Records that belong to the same device. 2023-07-28T10:58:24,943 With type info the server has no need to do type inference, which leads a better performance 2023-07-28T10:58:24,944 ```python 2023-07-28T10:58:24,944 session.insert_records_of_one_device(device_id, time_list, measurements_list, data_types_list, values_list) 2023-07-28T10:58:24,945 ``` 2023-07-28T10:58:24,945 #### Insert with type inference 2023-07-28T10:58:24,946 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-07-28T10:58:24,947 * Insert a Record, which contains multiple measurement value of a device at a timestamp 2023-07-28T10:58:24,947 ```python 2023-07-28T10:58:24,948 session.insert_str_record(device_id, timestamp, measurements, string_values) 2023-07-28T10:58:24,948 ``` 2023-07-28T10:58:24,949 #### Insert of Aligned Timeseries 2023-07-28T10:58:24,949 The Insert of aligned timeseries uses interfaces like insert_aligned_XXX, and others are similar to the above interfaces: 2023-07-28T10:58:24,950 * insert_aligned_record 2023-07-28T10:58:24,950 * insert_aligned_records 2023-07-28T10:58:24,950 * insert_aligned_records_of_one_device 2023-07-28T10:58:24,951 * insert_aligned_tablet 2023-07-28T10:58:24,951 * insert_aligned_tablets 2023-07-28T10:58:24,952 ### IoTDB-SQL Interface 2023-07-28T10:58:24,952 * Execute query statement 2023-07-28T10:58:24,953 ```python 2023-07-28T10:58:24,953 session.execute_query_statement(sql) 2023-07-28T10:58:24,954 ``` 2023-07-28T10:58:24,954 * Execute non query statement 2023-07-28T10:58:24,955 ```python 2023-07-28T10:58:24,955 session.execute_non_query_statement(sql) 2023-07-28T10:58:24,956 ``` 2023-07-28T10:58:24,956 * Execute statement 2023-07-28T10:58:24,957 ```python 2023-07-28T10:58:24,957 session.execute_statement(sql) 2023-07-28T10:58:24,957 ``` 2023-07-28T10:58:24,958 ### Schema Template 2023-07-28T10:58:24,959 #### Create Schema Template 2023-07-28T10:58:24,959 The step for creating a metadata template is as follows 2023-07-28T10:58:24,959 1. Create the template class 2023-07-28T10:58:24,960 2. Adding child Node,InternalNode and MeasurementNode can be chose 2023-07-28T10:58:24,960 3. Execute create schema template function 2023-07-28T10:58:24,961 ```python 2023-07-28T10:58:24,962 template = Template(name=template_name, share_time=True) 2023-07-28T10:58:24,962 i_node_gps = InternalNode(name="GPS", share_time=False) 2023-07-28T10:58:24,962 i_node_v = InternalNode(name="vehicle", share_time=True) 2023-07-28T10:58:24,963 m_node_x = MeasurementNode("x", TSDataType.FLOAT, TSEncoding.RLE, Compressor.SNAPPY) 2023-07-28T10:58:24,963 i_node_gps.add_child(m_node_x) 2023-07-28T10:58:24,964 i_node_v.add_child(m_node_x) 2023-07-28T10:58:24,964 template.add_template(i_node_gps) 2023-07-28T10:58:24,965 template.add_template(i_node_v) 2023-07-28T10:58:24,965 template.add_template(m_node_x) 2023-07-28T10:58:24,966 session.create_schema_template(template) 2023-07-28T10:58:24,966 ``` 2023-07-28T10:58:24,966 #### Modify Schema Template nodes 2023-07-28T10:58:24,967 Modify nodes in a template, the template must be already created. These are functions that add or delete some measurement nodes. 2023-07-28T10:58:24,967 * add node in template 2023-07-28T10:58:24,967 ```python 2023-07-28T10:58:24,968 session.add_measurements_in_template(template_name, measurements_path, data_types, encodings, compressors, is_aligned) 2023-07-28T10:58:24,968 ``` 2023-07-28T10:58:24,969 * delete node in template 2023-07-28T10:58:24,969 ```python 2023-07-28T10:58:24,969 session.delete_node_in_template(template_name, path) 2023-07-28T10:58:24,969 ``` 2023-07-28T10:58:24,970 #### Set Schema Template 2023-07-28T10:58:24,970 ```python 2023-07-28T10:58:24,971 session.set_schema_template(template_name, prefix_path) 2023-07-28T10:58:24,971 ``` 2023-07-28T10:58:24,971 #### Uset Schema Template 2023-07-28T10:58:24,972 ```python 2023-07-28T10:58:24,972 session.unset_schema_template(template_name, prefix_path) 2023-07-28T10:58:24,972 ``` 2023-07-28T10:58:24,973 #### Show Schema Template 2023-07-28T10:58:24,973 * Show all schema templates 2023-07-28T10:58:24,973 ```python 2023-07-28T10:58:24,974 session.show_all_templates() 2023-07-28T10:58:24,974 ``` 2023-07-28T10:58:24,974 * Count all nodes in templates 2023-07-28T10:58:24,975 ```python 2023-07-28T10:58:24,975 session.count_measurements_in_template(template_name) 2023-07-28T10:58:24,975 ``` 2023-07-28T10:58:24,976 * Judge whether the path is measurement or not in templates, This measurement must be in the template 2023-07-28T10:58:24,976 ```python 2023-07-28T10:58:24,977 session.count_measurements_in_template(template_name, path) 2023-07-28T10:58:24,977 ``` 2023-07-28T10:58:24,978 * Judge whether the path is exist or not in templates, This path may not belong to the template 2023-07-28T10:58:24,978 ```python 2023-07-28T10:58:24,979 session.is_path_exist_in_template(template_name, path) 2023-07-28T10:58:24,979 ``` 2023-07-28T10:58:24,980 * Show nodes under in schema template 2023-07-28T10:58:24,980 ```python 2023-07-28T10:58:24,980 session.show_measurements_in_template(template_name) 2023-07-28T10:58:24,981 ``` 2023-07-28T10:58:24,981 * Show the path prefix where a schema template is set 2023-07-28T10:58:24,981 ```python 2023-07-28T10:58:24,982 session.show_paths_template_set_on(template_name) 2023-07-28T10:58:24,982 ``` 2023-07-28T10:58:24,983 * Show the path prefix where a schema template is used (i.e. the time series has been created) 2023-07-28T10:58:24,983 ```python 2023-07-28T10:58:24,983 session.show_paths_template_using_on(template_name) 2023-07-28T10:58:24,983 ``` 2023-07-28T10:58:24,984 #### Drop Schema Template 2023-07-28T10:58:24,984 Delete an existing metadata template,dropping an already set template is not supported 2023-07-28T10:58:24,985 ```python 2023-07-28T10:58:24,985 session.drop_schema_template("template_python") 2023-07-28T10:58:24,985 ``` 2023-07-28T10:58:24,986 ### Pandas Support 2023-07-28T10:58:24,987 To easily transform a query result to a [Pandas Dataframe](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html) 2023-07-28T10:58:24,987 the SessionDataSet has a method `.todf()` which consumes the dataset and transforms it to a pandas dataframe. 2023-07-28T10:58:24,988 Example: 2023-07-28T10:58:24,988 ```python 2023-07-28T10:58:24,989 from iotdb.Session import Session 2023-07-28T10:58:24,989 ip = "127.0.0.1" 2023-07-28T10:58:24,990 port_ = "6667" 2023-07-28T10:58:24,990 username_ = "root" 2023-07-28T10:58:24,990 password_ = "root" 2023-07-28T10:58:24,990 session = Session(ip, port_, username_, password_) 2023-07-28T10:58:24,991 session.open(False) 2023-07-28T10:58:24,991 result = session.execute_query_statement("SELECT * FROM root.*") 2023-07-28T10:58:24,992 # Transform to Pandas Dataset 2023-07-28T10:58:24,992 df = result.todf() 2023-07-28T10:58:24,993 session.close() 2023-07-28T10:58:24,993 # Now you can work with the dataframe 2023-07-28T10:58:24,993 df = ... 2023-07-28T10:58:24,994 ``` 2023-07-28T10:58:24,995 ### IoTDB Testcontainer 2023-07-28T10:58:24,995 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-07-28T10:58:24,996 To start (and stop) an IoTDB Database in a Docker container simply do: 2023-07-28T10:58:24,996 ```python 2023-07-28T10:58:24,997 class MyTestCase(unittest.TestCase): 2023-07-28T10:58:24,997 def test_something(self): 2023-07-28T10:58:24,998 with IoTDBContainer() as c: 2023-07-28T10:58:24,998 session = Session("localhost", c.get_exposed_port(6667), "root", "root") 2023-07-28T10:58:24,998 session.open(False) 2023-07-28T10:58:24,998 result = session.execute_query_statement("SHOW TIMESERIES") 2023-07-28T10:58:24,999 print(result) 2023-07-28T10:58:24,999 session.close() 2023-07-28T10:58:24,999 ``` 2023-07-28T10:58:25,000 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-07-28T10:58:25,001 ### IoTDB DBAPI 2023-07-28T10:58:25,001 IoTDB DBAPI implements the Python DB API 2.0 specification (https://peps.python.org/pep-0249/), which defines a common 2023-07-28T10:58:25,002 interface for accessing databases in Python. 2023-07-28T10:58:25,002 #### Examples 2023-07-28T10:58:25,003 + Initialization 2023-07-28T10:58:25,003 The initialized parameters are consistent with the session part (except for the sqlalchemy_mode). 2023-07-28T10:58:25,004 ```python 2023-07-28T10:58:25,004 from iotdb.dbapi import connect 2023-07-28T10:58:25,005 ip = "127.0.0.1" 2023-07-28T10:58:25,005 port_ = "6667" 2023-07-28T10:58:25,005 username_ = "root" 2023-07-28T10:58:25,006 password_ = "root" 2023-07-28T10:58:25,006 conn = connect(ip, port_, username_, password_,fetch_size=1024,zone_id="UTC+8",sqlalchemy_mode=False) 2023-07-28T10:58:25,006 cursor = conn.cursor() 2023-07-28T10:58:25,007 ``` 2023-07-28T10:58:25,007 + simple SQL statement execution 2023-07-28T10:58:25,007 ```python 2023-07-28T10:58:25,007 cursor.execute("SELECT * FROM root.*") 2023-07-28T10:58:25,008 for row in cursor.fetchall(): 2023-07-28T10:58:25,008 print(row) 2023-07-28T10:58:25,008 ``` 2023-07-28T10:58:25,009 + execute SQL with parameter 2023-07-28T10:58:25,009 IoTDB DBAPI supports pyformat style parameters 2023-07-28T10:58:25,010 ```python 2023-07-28T10:58:25,010 cursor.execute("SELECT * FROM root.* WHERE time < %(time)s",{"time":"2017-11-01T00:08:00.000"}) 2023-07-28T10:58:25,010 for row in cursor.fetchall(): 2023-07-28T10:58:25,011 print(row) 2023-07-28T10:58:25,011 ``` 2023-07-28T10:58:25,012 + execute SQL with parameter sequences 2023-07-28T10:58:25,012 ```python 2023-07-28T10:58:25,012 seq_of_parameters = [ 2023-07-28T10:58:25,012 {"timestamp": 1, "temperature": 1}, 2023-07-28T10:58:25,013 {"timestamp": 2, "temperature": 2}, 2023-07-28T10:58:25,013 {"timestamp": 3, "temperature": 3}, 2023-07-28T10:58:25,013 {"timestamp": 4, "temperature": 4}, 2023-07-28T10:58:25,014 {"timestamp": 5, "temperature": 5}, 2023-07-28T10:58:25,014 ] 2023-07-28T10:58:25,014 sql = "insert into root.cursor(timestamp,temperature) values(%(timestamp)s,%(temperature)s)" 2023-07-28T10:58:25,015 cursor.executemany(sql,seq_of_parameters) 2023-07-28T10:58:25,015 ``` 2023-07-28T10:58:25,016 + close the connection and cursor 2023-07-28T10:58:25,016 ```python 2023-07-28T10:58:25,016 cursor.close() 2023-07-28T10:58:25,017 conn.close() 2023-07-28T10:58:25,017 ``` 2023-07-28T10:58:25,018 ### IoTDB SQLAlchemy Dialect (Experimental) 2023-07-28T10:58:25,018 The SQLAlchemy dialect of IoTDB is written to adapt to Apache Superset. 2023-07-28T10:58:25,018 This part is still being improved. 2023-07-28T10:58:25,018 Please do not use it in the production environment! 2023-07-28T10:58:25,019 #### Mapping of the metadata 2023-07-28T10:58:25,019 The data model used by SQLAlchemy is a relational data model, which describes the relationships between different entities through tables. 2023-07-28T10:58:25,019 While the data model of IoTDB is a hierarchical data model, which organizes the data through a tree structure. 2023-07-28T10:58:25,020 In order to adapt IoTDB to the dialect of SQLAlchemy, the original data model in IoTDB needs to be reorganized. 2023-07-28T10:58:25,020 Converting the data model of IoTDB into the data model of SQLAlchemy. 2023-07-28T10:58:25,021 The metadata in the IoTDB are: 2023-07-28T10:58:25,021 1. Database 2023-07-28T10:58:25,022 2. Path 2023-07-28T10:58:25,022 3. Entity 2023-07-28T10:58:25,022 4. Measurement 2023-07-28T10:58:25,023 The metadata in the SQLAlchemy are: 2023-07-28T10:58:25,023 1. Schema 2023-07-28T10:58:25,023 2. Table 2023-07-28T10:58:25,024 3. Column 2023-07-28T10:58:25,024 The mapping relationship between them is: 2023-07-28T10:58:25,025 | The metadata in the SQLAlchemy | The metadata in the IoTDB | 2023-07-28T10:58:25,025 | -------------------- | ---------------------------------------------- | 2023-07-28T10:58:25,026 | Schema | Database | 2023-07-28T10:58:25,026 | Table | Path ( from database to entity ) + Entity | 2023-07-28T10:58:25,026 | Column | Measurement | 2023-07-28T10:58:25,027 The following figure shows the relationship between the two more intuitively: 2023-07-28T10:58:25,028 ![sqlalchemy-to-iotdb](https://github.com/apache/iotdb-bin-resources/blob/main/docs/UserGuide/API/IoTDB-SQLAlchemy/sqlalchemy-to-iotdb.png?raw=true) 2023-07-28T10:58:25,028 #### Data type mapping 2023-07-28T10:58:25,029 | data type in IoTDB | data type in SQLAlchemy | 2023-07-28T10:58:25,029 |--------------------|-------------------------| 2023-07-28T10:58:25,029 | BOOLEAN | Boolean | 2023-07-28T10:58:25,030 | INT32 | Integer | 2023-07-28T10:58:25,030 | INT64 | BigInteger | 2023-07-28T10:58:25,030 | FLOAT | Float | 2023-07-28T10:58:25,030 | DOUBLE | Float | 2023-07-28T10:58:25,031 | TEXT | Text | 2023-07-28T10:58:25,031 | LONG | BigInteger | 2023-07-28T10:58:25,031 #### Example 2023-07-28T10:58:25,032 + execute statement 2023-07-28T10:58:25,033 ```python 2023-07-28T10:58:25,033 from sqlalchemy import create_engine 2023-07-28T10:58:25,034 engine = create_engine("iotdb://root:root@127.0.0.1:6667") 2023-07-28T10:58:25,034 connect = engine.connect() 2023-07-28T10:58:25,034 result = connect.execute("SELECT ** FROM root") 2023-07-28T10:58:25,035 for row in result.fetchall(): 2023-07-28T10:58:25,035 print(row) 2023-07-28T10:58:25,035 ``` 2023-07-28T10:58:25,036 + ORM (now only simple queries are supported) 2023-07-28T10:58:25,036 ```python 2023-07-28T10:58:25,037 from sqlalchemy import create_engine, Column, Float, BigInteger, MetaData 2023-07-28T10:58:25,037 from sqlalchemy.ext.declarative import declarative_base 2023-07-28T10:58:25,037 from sqlalchemy.orm import sessionmaker 2023-07-28T10:58:25,038 metadata = MetaData( 2023-07-28T10:58:25,038 schema='root.factory' 2023-07-28T10:58:25,038 ) 2023-07-28T10:58:25,039 Base = declarative_base(metadata=metadata) 2023-07-28T10:58:25,040 class Device(Base): 2023-07-28T10:58:25,040 __tablename__ = "room2.device1" 2023-07-28T10:58:25,040 Time = Column(BigInteger, primary_key=True) 2023-07-28T10:58:25,041 temperature = Column(Float) 2023-07-28T10:58:25,041 status = Column(Float) 2023-07-28T10:58:25,042 engine = create_engine("iotdb://root:root@127.0.0.1:6667") 2023-07-28T10:58:25,042 DbSession = sessionmaker(bind=engine) 2023-07-28T10:58:25,043 session = DbSession() 2023-07-28T10:58:25,043 res = session.query(Device.status).filter(Device.temperature > 1) 2023-07-28T10:58:25,044 for row in res: 2023-07-28T10:58:25,044 print(row) 2023-07-28T10:58:25,045 ``` 2023-07-28T10:58:25,046 ## Developers 2023-07-28T10:58:25,046 ### Introduction 2023-07-28T10:58:25,047 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-07-28T10:58:25,048 ### Prerequisites 2023-07-28T10:58:25,049 Python3.7 or later is preferred. 2023-07-28T10:58:25,049 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-07-28T10:58:25,050 ``` 2023-07-28T10:58:25,050 http://thrift.apache.org/docs/install/ 2023-07-28T10:58:25,051 ``` 2023-07-28T10:58:25,051 Before starting you need to install `requirements_dev.txt` in your python environment, e.g. by calling 2023-07-28T10:58:25,052 ```shell 2023-07-28T10:58:25,052 pip install -r requirements_dev.txt 2023-07-28T10:58:25,052 ``` 2023-07-28T10:58:25,053 ### Compile the thrift library and Debug 2023-07-28T10:58:25,054 In the root of IoTDB's source code folder, run `mvn clean generate-sources -pl client-py -am`. 2023-07-28T10:58:25,055 This will automatically delete and repopulate the folder `iotdb/thrift` with the generated thrift files. 2023-07-28T10:58:25,055 This folder is ignored from git and should **never be pushed to git!** 2023-07-28T10:58:25,056 **Notice** Do not upload `iotdb/thrift` to the git repo. 2023-07-28T10:58:25,057 ### Session Client & Example 2023-07-28T10:58:25,058 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-07-28T10:58:25,059 Or, another simple example: 2023-07-28T10:58:25,060 ```python 2023-07-28T10:58:25,060 from iotdb.Session import Session 2023-07-28T10:58:25,060 ip = "127.0.0.1" 2023-07-28T10:58:25,061 port_ = "6667" 2023-07-28T10:58:25,061 username_ = "root" 2023-07-28T10:58:25,061 password_ = "root" 2023-07-28T10:58:25,062 session = Session(ip, port_, username_, password_) 2023-07-28T10:58:25,062 session.open(False) 2023-07-28T10:58:25,062 zone = session.get_time_zone() 2023-07-28T10:58:25,063 session.close() 2023-07-28T10:58:25,063 ``` 2023-07-28T10:58:25,064 ### Tests 2023-07-28T10:58:25,065 Please add your custom tests in `tests` folder. 2023-07-28T10:58:25,065 To run all defined tests just type `pytest .` in the root folder. 2023-07-28T10:58:25,066 **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-07-28T10:58:25,067 ### Futher Tools 2023-07-28T10:58:25,068 [black](https://pypi.org/project/black/) and [flake8](https://pypi.org/project/flake8/) are installed for autoformatting and linting. 2023-07-28T10:58:25,068 Both can be run by `black .` or `flake8 .` respectively. 2023-07-28T10:58:25,069 ## Releasing 2023-07-28T10:58:25,070 To do a release just ensure that you have the right set of generated thrift files. 2023-07-28T10:58:25,070 Then run linting and auto-formatting. 2023-07-28T10:58:25,071 Then, ensure that all tests work (via `pytest .`). 2023-07-28T10:58:25,071 Then you are good to go to do a release! 2023-07-28T10:58:25,072 ### Preparing your environment 2023-07-28T10:58:25,073 First, install all necessary dev dependencies via `pip install -r requirements_dev.txt`. 2023-07-28T10:58:25,074 ### Doing the Release 2023-07-28T10:58:25,074 There is a convenient script `release.sh` to do all steps for a release. 2023-07-28T10:58:25,075 Namely, these are 2023-07-28T10:58:25,075 * Remove all transient directories from last release (if exists) 2023-07-28T10:58:25,076 * (Re-)generate all generated sources via mvn 2023-07-28T10:58:25,076 * Run Linting (flake8) 2023-07-28T10:58:25,076 * Run Tests via pytest 2023-07-28T10:58:25,077 * Build 2023-07-28T10:58:25,077 * Release to pypi 2023-07-28T10:58:25,120 running bdist_wheel 2023-07-28T10:58:25,200 running build 2023-07-28T10:58:25,200 running build_py 2023-07-28T10:58:25,221 creating build 2023-07-28T10:58:25,222 creating build/lib 2023-07-28T10:58:25,224 creating build/lib/tests 2023-07-28T10:58:25,227 copying tests/test_one_device.py -> build/lib/tests 2023-07-28T10:58:25,231 copying tests/test_dataframe.py -> build/lib/tests 2023-07-28T10:58:25,235 copying tests/tablet_performance_comparison.py -> build/lib/tests 2023-07-28T10:58:25,240 copying tests/test_todf.py -> build/lib/tests 2023-07-28T10:58:25,244 copying tests/test_delete_data.py -> build/lib/tests 2023-07-28T10:58:25,249 copying tests/__init__.py -> build/lib/tests 2023-07-28T10:58:25,252 copying tests/test_session.py -> build/lib/tests 2023-07-28T10:58:25,257 copying tests/test_aligned_timeseries.py -> build/lib/tests 2023-07-28T10:58:25,261 copying tests/test_numpy_tablet.py -> build/lib/tests 2023-07-28T10:58:25,265 copying tests/test_template.py -> build/lib/tests 2023-07-28T10:58:25,269 copying tests/test_tablet.py -> build/lib/tests 2023-07-28T10:58:25,274 copying tests/test_session_pool.py -> build/lib/tests 2023-07-28T10:58:25,279 creating build/lib/iotdb 2023-07-28T10:58:25,281 copying iotdb/__init__.py -> build/lib/iotdb 2023-07-28T10:58:25,285 copying iotdb/IoTDBContainer.py -> build/lib/iotdb 2023-07-28T10:58:25,289 copying iotdb/Session.py -> build/lib/iotdb 2023-07-28T10:58:25,297 copying iotdb/SessionPool.py -> build/lib/iotdb 2023-07-28T10:58:25,303 creating build/lib/iotdb/dbapi 2023-07-28T10:58:25,305 copying iotdb/dbapi/Cursor.py -> build/lib/iotdb/dbapi 2023-07-28T10:58:25,310 copying iotdb/dbapi/Exceptions.py -> build/lib/iotdb/dbapi 2023-07-28T10:58:25,314 copying iotdb/dbapi/__init__.py -> build/lib/iotdb/dbapi 2023-07-28T10:58:25,319 copying iotdb/dbapi/Connection.py -> build/lib/iotdb/dbapi 2023-07-28T10:58:25,325 creating build/lib/iotdb/template 2023-07-28T10:58:25,327 copying iotdb/template/__init__.py -> build/lib/iotdb/template 2023-07-28T10:58:25,332 copying iotdb/template/TemplateNode.py -> build/lib/iotdb/template 2023-07-28T10:58:25,336 copying iotdb/template/MeasurementNode.py -> build/lib/iotdb/template 2023-07-28T10:58:25,340 copying iotdb/template/InternalNode.py -> build/lib/iotdb/template 2023-07-28T10:58:25,344 copying iotdb/template/TemplateQueryType.py -> build/lib/iotdb/template 2023-07-28T10:58:25,348 copying iotdb/template/Template.py -> build/lib/iotdb/template 2023-07-28T10:58:25,353 creating build/lib/iotdb/sqlalchemy 2023-07-28T10:58:25,356 copying iotdb/sqlalchemy/IoTDBDialect.py -> build/lib/iotdb/sqlalchemy 2023-07-28T10:58:25,360 copying iotdb/sqlalchemy/IoTDBSQLCompiler.py -> build/lib/iotdb/sqlalchemy 2023-07-28T10:58:25,364 copying iotdb/sqlalchemy/__init__.py -> build/lib/iotdb/sqlalchemy 2023-07-28T10:58:25,368 copying iotdb/sqlalchemy/IoTDBIdentifierPreparer.py -> build/lib/iotdb/sqlalchemy 2023-07-28T10:58:25,371 copying iotdb/sqlalchemy/IoTDBTypeCompiler.py -> build/lib/iotdb/sqlalchemy 2023-07-28T10:58:25,376 creating build/lib/iotdb/tsfile 2023-07-28T10:58:25,377 copying iotdb/tsfile/__init__.py -> build/lib/iotdb/tsfile 2023-07-28T10:58:25,382 creating build/lib/iotdb/thrift 2023-07-28T10:58:25,385 copying iotdb/thrift/__init__.py -> build/lib/iotdb/thrift 2023-07-28T10:58:25,390 creating build/lib/iotdb/utils 2023-07-28T10:58:25,392 copying iotdb/utils/IoTDBRpcDataSet.py -> build/lib/iotdb/utils 2023-07-28T10:58:25,397 copying iotdb/utils/BitMap.py -> build/lib/iotdb/utils 2023-07-28T10:58:25,400 copying iotdb/utils/RowRecord.py -> build/lib/iotdb/utils 2023-07-28T10:58:25,404 copying iotdb/utils/__init__.py -> build/lib/iotdb/utils 2023-07-28T10:58:25,407 copying iotdb/utils/Field.py -> build/lib/iotdb/utils 2023-07-28T10:58:25,411 copying iotdb/utils/SessionDataSet.py -> build/lib/iotdb/utils 2023-07-28T10:58:25,415 copying iotdb/utils/IoTDBConstants.py -> build/lib/iotdb/utils 2023-07-28T10:58:25,419 copying iotdb/utils/Tablet.py -> build/lib/iotdb/utils 2023-07-28T10:58:25,423 copying iotdb/utils/NumpyTablet.py -> build/lib/iotdb/utils 2023-07-28T10:58:25,429 creating build/lib/iotdb/dbapi/tests 2023-07-28T10:58:25,430 copying iotdb/dbapi/tests/test_cursor.py -> build/lib/iotdb/dbapi/tests 2023-07-28T10:58:25,434 copying iotdb/dbapi/tests/__init__.py -> build/lib/iotdb/dbapi/tests 2023-07-28T10:58:25,438 copying iotdb/dbapi/tests/test_connection.py -> build/lib/iotdb/dbapi/tests 2023-07-28T10:58:25,442 creating build/lib/iotdb/sqlalchemy/tests 2023-07-28T10:58:25,444 copying iotdb/sqlalchemy/tests/__init__.py -> build/lib/iotdb/sqlalchemy/tests 2023-07-28T10:58:25,448 copying iotdb/sqlalchemy/tests/test_dialect.py -> build/lib/iotdb/sqlalchemy/tests 2023-07-28T10:58:25,454 creating build/lib/iotdb/tsfile/common 2023-07-28T10:58:25,456 copying iotdb/tsfile/common/__init__.py -> build/lib/iotdb/tsfile/common 2023-07-28T10:58:25,461 creating build/lib/iotdb/tsfile/utils 2023-07-28T10:58:25,462 copying iotdb/tsfile/utils/__init__.py -> build/lib/iotdb/tsfile/utils 2023-07-28T10:58:25,466 copying iotdb/tsfile/utils/Pair.py -> build/lib/iotdb/tsfile/utils 2023-07-28T10:58:25,469 copying iotdb/tsfile/utils/ReadWriteIOUtils.py -> build/lib/iotdb/tsfile/utils 2023-07-28T10:58:25,474 creating build/lib/iotdb/tsfile/common/constant 2023-07-28T10:58:25,476 copying iotdb/tsfile/common/constant/TsFileConstant.py -> build/lib/iotdb/tsfile/common/constant 2023-07-28T10:58:25,480 copying iotdb/tsfile/common/constant/__init__.py -> build/lib/iotdb/tsfile/common/constant 2023-07-28T10:58:25,485 creating build/lib/iotdb/thrift/rpc 2023-07-28T10:58:25,486 copying iotdb/thrift/rpc/ttypes.py -> build/lib/iotdb/thrift/rpc 2023-07-28T10:58:25,505 copying iotdb/thrift/rpc/__init__.py -> build/lib/iotdb/thrift/rpc 2023-07-28T10:58:25,508 copying iotdb/thrift/rpc/IClientRPCService.py -> build/lib/iotdb/thrift/rpc 2023-07-28T10:58:25,533 copying iotdb/thrift/rpc/constants.py -> build/lib/iotdb/thrift/rpc 2023-07-28T10:58:25,538 creating build/lib/iotdb/thrift/datanode 2023-07-28T10:58:25,539 copying iotdb/thrift/datanode/MPPDataExchangeService.py -> build/lib/iotdb/thrift/datanode 2023-07-28T10:58:25,545 copying iotdb/thrift/datanode/ttypes.py -> build/lib/iotdb/thrift/datanode 2023-07-28T10:58:25,563 copying iotdb/thrift/datanode/__init__.py -> build/lib/iotdb/thrift/datanode 2023-07-28T10:58:25,567 copying iotdb/thrift/datanode/IDataNodeRPCService.py -> build/lib/iotdb/thrift/datanode 2023-07-28T10:58:25,590 copying iotdb/thrift/datanode/constants.py -> build/lib/iotdb/thrift/datanode 2023-07-28T10:58:25,595 creating build/lib/iotdb/thrift/common 2023-07-28T10:58:25,597 copying iotdb/thrift/common/ttypes.py -> build/lib/iotdb/thrift/common 2023-07-28T10:58:25,604 copying iotdb/thrift/common/__init__.py -> build/lib/iotdb/thrift/common 2023-07-28T10:58:25,609 copying iotdb/thrift/common/constants.py -> build/lib/iotdb/thrift/common 2023-07-28T10:58:25,670 installing to build/bdist.linux-armv7l/wheel 2023-07-28T10:58:25,671 running install 2023-07-28T10:58:25,732 running install_lib 2023-07-28T10:58:25,748 creating build/bdist.linux-armv7l 2023-07-28T10:58:25,749 creating build/bdist.linux-armv7l/wheel 2023-07-28T10:58:25,753 creating build/bdist.linux-armv7l/wheel/tests 2023-07-28T10:58:25,755 copying build/lib/tests/test_one_device.py -> build/bdist.linux-armv7l/wheel/tests 2023-07-28T10:58:25,760 copying build/lib/tests/test_dataframe.py -> build/bdist.linux-armv7l/wheel/tests 2023-07-28T10:58:25,765 copying build/lib/tests/tablet_performance_comparison.py -> build/bdist.linux-armv7l/wheel/tests 2023-07-28T10:58:25,770 copying build/lib/tests/test_todf.py -> build/bdist.linux-armv7l/wheel/tests 2023-07-28T10:58:25,776 copying build/lib/tests/test_delete_data.py -> build/bdist.linux-armv7l/wheel/tests 2023-07-28T10:58:25,781 copying build/lib/tests/__init__.py -> build/bdist.linux-armv7l/wheel/tests 2023-07-28T10:58:25,786 copying build/lib/tests/test_session.py -> build/bdist.linux-armv7l/wheel/tests 2023-07-28T10:58:25,793 copying build/lib/tests/test_aligned_timeseries.py -> build/bdist.linux-armv7l/wheel/tests 2023-07-28T10:58:25,799 copying build/lib/tests/test_numpy_tablet.py -> build/bdist.linux-armv7l/wheel/tests 2023-07-28T10:58:25,804 copying build/lib/tests/test_template.py -> build/bdist.linux-armv7l/wheel/tests 2023-07-28T10:58:25,809 copying build/lib/tests/test_tablet.py -> build/bdist.linux-armv7l/wheel/tests 2023-07-28T10:58:25,814 copying build/lib/tests/test_session_pool.py -> build/bdist.linux-armv7l/wheel/tests 2023-07-28T10:58:25,820 creating build/bdist.linux-armv7l/wheel/iotdb 2023-07-28T10:58:25,824 creating build/bdist.linux-armv7l/wheel/iotdb/dbapi 2023-07-28T10:58:25,827 copying build/lib/iotdb/dbapi/Cursor.py -> build/bdist.linux-armv7l/wheel/iotdb/dbapi 2023-07-28T10:58:25,833 copying build/lib/iotdb/dbapi/Exceptions.py -> build/bdist.linux-armv7l/wheel/iotdb/dbapi 2023-07-28T10:58:25,838 creating build/bdist.linux-armv7l/wheel/iotdb/dbapi/tests 2023-07-28T10:58:25,841 copying build/lib/iotdb/dbapi/tests/test_cursor.py -> build/bdist.linux-armv7l/wheel/iotdb/dbapi/tests 2023-07-28T10:58:25,845 copying build/lib/iotdb/dbapi/tests/__init__.py -> build/bdist.linux-armv7l/wheel/iotdb/dbapi/tests 2023-07-28T10:58:25,848 copying build/lib/iotdb/dbapi/tests/test_connection.py -> build/bdist.linux-armv7l/wheel/iotdb/dbapi/tests 2023-07-28T10:58:25,852 copying build/lib/iotdb/dbapi/__init__.py -> build/bdist.linux-armv7l/wheel/iotdb/dbapi 2023-07-28T10:58:25,856 copying build/lib/iotdb/dbapi/Connection.py -> build/bdist.linux-armv7l/wheel/iotdb/dbapi 2023-07-28T10:58:25,860 copying build/lib/iotdb/__init__.py -> build/bdist.linux-armv7l/wheel/iotdb 2023-07-28T10:58:25,863 copying build/lib/iotdb/IoTDBContainer.py -> build/bdist.linux-armv7l/wheel/iotdb 2023-07-28T10:58:25,867 copying build/lib/iotdb/Session.py -> build/bdist.linux-armv7l/wheel/iotdb 2023-07-28T10:58:25,876 creating build/bdist.linux-armv7l/wheel/iotdb/template 2023-07-28T10:58:25,878 copying build/lib/iotdb/template/__init__.py -> build/bdist.linux-armv7l/wheel/iotdb/template 2023-07-28T10:58:25,882 copying build/lib/iotdb/template/TemplateNode.py -> build/bdist.linux-armv7l/wheel/iotdb/template 2023-07-28T10:58:25,885 copying build/lib/iotdb/template/MeasurementNode.py -> build/bdist.linux-armv7l/wheel/iotdb/template 2023-07-28T10:58:25,889 copying build/lib/iotdb/template/InternalNode.py -> build/bdist.linux-armv7l/wheel/iotdb/template 2023-07-28T10:58:25,893 copying build/lib/iotdb/template/TemplateQueryType.py -> build/bdist.linux-armv7l/wheel/iotdb/template 2023-07-28T10:58:25,896 copying build/lib/iotdb/template/Template.py -> build/bdist.linux-armv7l/wheel/iotdb/template 2023-07-28T10:58:25,901 creating build/bdist.linux-armv7l/wheel/iotdb/sqlalchemy 2023-07-28T10:58:25,903 copying build/lib/iotdb/sqlalchemy/IoTDBDialect.py -> build/bdist.linux-armv7l/wheel/iotdb/sqlalchemy 2023-07-28T10:58:25,908 creating build/bdist.linux-armv7l/wheel/iotdb/sqlalchemy/tests 2023-07-28T10:58:25,910 copying build/lib/iotdb/sqlalchemy/tests/__init__.py -> build/bdist.linux-armv7l/wheel/iotdb/sqlalchemy/tests 2023-07-28T10:58:25,915 copying build/lib/iotdb/sqlalchemy/tests/test_dialect.py -> build/bdist.linux-armv7l/wheel/iotdb/sqlalchemy/tests 2023-07-28T10:58:25,918 copying build/lib/iotdb/sqlalchemy/IoTDBSQLCompiler.py -> build/bdist.linux-armv7l/wheel/iotdb/sqlalchemy 2023-07-28T10:58:25,923 copying build/lib/iotdb/sqlalchemy/__init__.py -> build/bdist.linux-armv7l/wheel/iotdb/sqlalchemy 2023-07-28T10:58:25,927 copying build/lib/iotdb/sqlalchemy/IoTDBIdentifierPreparer.py -> build/bdist.linux-armv7l/wheel/iotdb/sqlalchemy 2023-07-28T10:58:25,930 copying build/lib/iotdb/sqlalchemy/IoTDBTypeCompiler.py -> build/bdist.linux-armv7l/wheel/iotdb/sqlalchemy 2023-07-28T10:58:25,935 creating build/bdist.linux-armv7l/wheel/iotdb/tsfile 2023-07-28T10:58:25,937 copying build/lib/iotdb/tsfile/__init__.py -> build/bdist.linux-armv7l/wheel/iotdb/tsfile 2023-07-28T10:58:25,941 creating build/bdist.linux-armv7l/wheel/iotdb/tsfile/common 2023-07-28T10:58:25,943 copying build/lib/iotdb/tsfile/common/__init__.py -> build/bdist.linux-armv7l/wheel/iotdb/tsfile/common 2023-07-28T10:58:25,948 creating build/bdist.linux-armv7l/wheel/iotdb/tsfile/common/constant 2023-07-28T10:58:25,950 copying build/lib/iotdb/tsfile/common/constant/TsFileConstant.py -> build/bdist.linux-armv7l/wheel/iotdb/tsfile/common/constant 2023-07-28T10:58:25,954 copying build/lib/iotdb/tsfile/common/constant/__init__.py -> build/bdist.linux-armv7l/wheel/iotdb/tsfile/common/constant 2023-07-28T10:58:25,959 creating build/bdist.linux-armv7l/wheel/iotdb/tsfile/utils 2023-07-28T10:58:25,960 copying build/lib/iotdb/tsfile/utils/__init__.py -> build/bdist.linux-armv7l/wheel/iotdb/tsfile/utils 2023-07-28T10:58:25,964 copying build/lib/iotdb/tsfile/utils/Pair.py -> build/bdist.linux-armv7l/wheel/iotdb/tsfile/utils 2023-07-28T10:58:25,968 copying build/lib/iotdb/tsfile/utils/ReadWriteIOUtils.py -> build/bdist.linux-armv7l/wheel/iotdb/tsfile/utils 2023-07-28T10:58:25,972 copying build/lib/iotdb/SessionPool.py -> build/bdist.linux-armv7l/wheel/iotdb 2023-07-28T10:58:25,977 creating build/bdist.linux-armv7l/wheel/iotdb/thrift 2023-07-28T10:58:25,979 copying build/lib/iotdb/thrift/__init__.py -> build/bdist.linux-armv7l/wheel/iotdb/thrift 2023-07-28T10:58:25,983 creating build/bdist.linux-armv7l/wheel/iotdb/thrift/rpc 2023-07-28T10:58:25,985 copying build/lib/iotdb/thrift/rpc/ttypes.py -> build/bdist.linux-armv7l/wheel/iotdb/thrift/rpc 2023-07-28T10:58:26,003 copying build/lib/iotdb/thrift/rpc/__init__.py -> build/bdist.linux-armv7l/wheel/iotdb/thrift/rpc 2023-07-28T10:58:26,007 copying build/lib/iotdb/thrift/rpc/IClientRPCService.py -> build/bdist.linux-armv7l/wheel/iotdb/thrift/rpc 2023-07-28T10:58:26,035 copying build/lib/iotdb/thrift/rpc/constants.py -> build/bdist.linux-armv7l/wheel/iotdb/thrift/rpc 2023-07-28T10:58:26,040 creating build/bdist.linux-armv7l/wheel/iotdb/thrift/datanode 2023-07-28T10:58:26,042 copying build/lib/iotdb/thrift/datanode/MPPDataExchangeService.py -> build/bdist.linux-armv7l/wheel/iotdb/thrift/datanode 2023-07-28T10:58:26,047 copying build/lib/iotdb/thrift/datanode/ttypes.py -> build/bdist.linux-armv7l/wheel/iotdb/thrift/datanode 2023-07-28T10:58:26,064 copying build/lib/iotdb/thrift/datanode/__init__.py -> build/bdist.linux-armv7l/wheel/iotdb/thrift/datanode 2023-07-28T10:58:26,068 copying build/lib/iotdb/thrift/datanode/IDataNodeRPCService.py -> build/bdist.linux-armv7l/wheel/iotdb/thrift/datanode 2023-07-28T10:58:26,090 copying build/lib/iotdb/thrift/datanode/constants.py -> build/bdist.linux-armv7l/wheel/iotdb/thrift/datanode 2023-07-28T10:58:26,094 creating build/bdist.linux-armv7l/wheel/iotdb/thrift/common 2023-07-28T10:58:26,096 copying build/lib/iotdb/thrift/common/ttypes.py -> build/bdist.linux-armv7l/wheel/iotdb/thrift/common 2023-07-28T10:58:26,104 copying build/lib/iotdb/thrift/common/__init__.py -> build/bdist.linux-armv7l/wheel/iotdb/thrift/common 2023-07-28T10:58:26,107 copying build/lib/iotdb/thrift/common/constants.py -> build/bdist.linux-armv7l/wheel/iotdb/thrift/common 2023-07-28T10:58:26,112 creating build/bdist.linux-armv7l/wheel/iotdb/utils 2023-07-28T10:58:26,113 copying build/lib/iotdb/utils/IoTDBRpcDataSet.py -> build/bdist.linux-armv7l/wheel/iotdb/utils 2023-07-28T10:58:26,118 copying build/lib/iotdb/utils/BitMap.py -> build/bdist.linux-armv7l/wheel/iotdb/utils 2023-07-28T10:58:26,122 copying build/lib/iotdb/utils/RowRecord.py -> build/bdist.linux-armv7l/wheel/iotdb/utils 2023-07-28T10:58:26,125 copying build/lib/iotdb/utils/__init__.py -> build/bdist.linux-armv7l/wheel/iotdb/utils 2023-07-28T10:58:26,129 copying build/lib/iotdb/utils/Field.py -> build/bdist.linux-armv7l/wheel/iotdb/utils 2023-07-28T10:58:26,132 copying build/lib/iotdb/utils/SessionDataSet.py -> build/bdist.linux-armv7l/wheel/iotdb/utils 2023-07-28T10:58:26,136 copying build/lib/iotdb/utils/IoTDBConstants.py -> build/bdist.linux-armv7l/wheel/iotdb/utils 2023-07-28T10:58:26,140 copying build/lib/iotdb/utils/Tablet.py -> build/bdist.linux-armv7l/wheel/iotdb/utils 2023-07-28T10:58:26,144 copying build/lib/iotdb/utils/NumpyTablet.py -> build/bdist.linux-armv7l/wheel/iotdb/utils 2023-07-28T10:58:26,148 running install_egg_info 2023-07-28T10:58:26,206 running egg_info 2023-07-28T10:58:26,216 writing apache_iotdb.egg-info/PKG-INFO 2023-07-28T10:58:26,221 writing dependency_links to apache_iotdb.egg-info/dependency_links.txt 2023-07-28T10:58:26,224 writing entry points to apache_iotdb.egg-info/entry_points.txt 2023-07-28T10:58:26,226 writing requirements to apache_iotdb.egg-info/requires.txt 2023-07-28T10:58:26,228 writing top-level names to apache_iotdb.egg-info/top_level.txt 2023-07-28T10:58:26,267 reading manifest file 'apache_iotdb.egg-info/SOURCES.txt' 2023-07-28T10:58:26,275 adding license file 'LICENSE' 2023-07-28T10:58:26,288 writing manifest file 'apache_iotdb.egg-info/SOURCES.txt' 2023-07-28T10:58:26,291 Copying apache_iotdb.egg-info to build/bdist.linux-armv7l/wheel/apache_iotdb-1.1.2-py3.7.egg-info 2023-07-28T10:58:26,315 running install_scripts 2023-07-28T10:58:26,362 creating build/bdist.linux-armv7l/wheel/apache_iotdb-1.1.2.dist-info/WHEEL 2023-07-28T10:58:26,367 creating '/tmp/pip-wheel-8ll9kzfd/.tmp-bcpz2gn9/apache_iotdb-1.1.2-py3-none-any.whl' and adding 'build/bdist.linux-armv7l/wheel' to it 2023-07-28T10:58:26,375 adding 'iotdb/IoTDBContainer.py' 2023-07-28T10:58:26,387 adding 'iotdb/Session.py' 2023-07-28T10:58:26,391 adding 'iotdb/SessionPool.py' 2023-07-28T10:58:26,394 adding 'iotdb/__init__.py' 2023-07-28T10:58:26,398 adding 'iotdb/dbapi/Connection.py' 2023-07-28T10:58:26,402 adding 'iotdb/dbapi/Cursor.py' 2023-07-28T10:58:26,405 adding 'iotdb/dbapi/Exceptions.py' 2023-07-28T10:58:26,407 adding 'iotdb/dbapi/__init__.py' 2023-07-28T10:58:26,411 adding 'iotdb/dbapi/tests/__init__.py' 2023-07-28T10:58:26,413 adding 'iotdb/dbapi/tests/test_connection.py' 2023-07-28T10:58:26,416 adding 'iotdb/dbapi/tests/test_cursor.py' 2023-07-28T10:58:26,422 adding 'iotdb/sqlalchemy/IoTDBDialect.py' 2023-07-28T10:58:26,425 adding 'iotdb/sqlalchemy/IoTDBIdentifierPreparer.py' 2023-07-28T10:58:26,428 adding 'iotdb/sqlalchemy/IoTDBSQLCompiler.py' 2023-07-28T10:58:26,431 adding 'iotdb/sqlalchemy/IoTDBTypeCompiler.py' 2023-07-28T10:58:26,434 adding 'iotdb/sqlalchemy/__init__.py' 2023-07-28T10:58:26,437 adding 'iotdb/sqlalchemy/tests/__init__.py' 2023-07-28T10:58:26,441 adding 'iotdb/sqlalchemy/tests/test_dialect.py' 2023-07-28T10:58:26,445 adding 'iotdb/template/InternalNode.py' 2023-07-28T10:58:26,448 adding 'iotdb/template/MeasurementNode.py' 2023-07-28T10:58:26,450 adding 'iotdb/template/Template.py' 2023-07-28T10:58:26,453 adding 'iotdb/template/TemplateNode.py' 2023-07-28T10:58:26,456 adding 'iotdb/template/TemplateQueryType.py' 2023-07-28T10:58:26,459 adding 'iotdb/template/__init__.py' 2023-07-28T10:58:26,462 adding 'iotdb/thrift/__init__.py' 2023-07-28T10:58:26,466 adding 'iotdb/thrift/common/__init__.py' 2023-07-28T10:58:26,469 adding 'iotdb/thrift/common/constants.py' 2023-07-28T10:58:26,476 adding 'iotdb/thrift/common/ttypes.py' 2023-07-28T10:58:26,512 adding 'iotdb/thrift/datanode/IDataNodeRPCService.py' 2023-07-28T10:58:26,524 adding 'iotdb/thrift/datanode/MPPDataExchangeService.py' 2023-07-28T10:58:26,528 adding 'iotdb/thrift/datanode/__init__.py' 2023-07-28T10:58:26,530 adding 'iotdb/thrift/datanode/constants.py' 2023-07-28T10:58:26,559 adding 'iotdb/thrift/datanode/ttypes.py' 2023-07-28T10:58:26,596 adding 'iotdb/thrift/rpc/IClientRPCService.py' 2023-07-28T10:58:26,606 adding 'iotdb/thrift/rpc/__init__.py' 2023-07-28T10:58:26,608 adding 'iotdb/thrift/rpc/constants.py' 2023-07-28T10:58:26,638 adding 'iotdb/thrift/rpc/ttypes.py' 2023-07-28T10:58:26,647 adding 'iotdb/tsfile/__init__.py' 2023-07-28T10:58:26,651 adding 'iotdb/tsfile/common/__init__.py' 2023-07-28T10:58:26,655 adding 'iotdb/tsfile/common/constant/TsFileConstant.py' 2023-07-28T10:58:26,657 adding 'iotdb/tsfile/common/constant/__init__.py' 2023-07-28T10:58:26,661 adding 'iotdb/tsfile/utils/Pair.py' 2023-07-28T10:58:26,664 adding 'iotdb/tsfile/utils/ReadWriteIOUtils.py' 2023-07-28T10:58:26,666 adding 'iotdb/tsfile/utils/__init__.py' 2023-07-28T10:58:26,670 adding 'iotdb/utils/BitMap.py' 2023-07-28T10:58:26,673 adding 'iotdb/utils/Field.py' 2023-07-28T10:58:26,676 adding 'iotdb/utils/IoTDBConstants.py' 2023-07-28T10:58:26,681 adding 'iotdb/utils/IoTDBRpcDataSet.py' 2023-07-28T10:58:26,685 adding 'iotdb/utils/NumpyTablet.py' 2023-07-28T10:58:26,688 adding 'iotdb/utils/RowRecord.py' 2023-07-28T10:58:26,691 adding 'iotdb/utils/SessionDataSet.py' 2023-07-28T10:58:26,695 adding 'iotdb/utils/Tablet.py' 2023-07-28T10:58:26,697 adding 'iotdb/utils/__init__.py' 2023-07-28T10:58:26,701 adding 'tests/__init__.py' 2023-07-28T10:58:26,706 adding 'tests/tablet_performance_comparison.py' 2023-07-28T10:58:26,710 adding 'tests/test_aligned_timeseries.py' 2023-07-28T10:58:26,712 adding 'tests/test_dataframe.py' 2023-07-28T10:58:26,716 adding 'tests/test_delete_data.py' 2023-07-28T10:58:26,719 adding 'tests/test_numpy_tablet.py' 2023-07-28T10:58:26,723 adding 'tests/test_one_device.py' 2023-07-28T10:58:26,727 adding 'tests/test_session.py' 2023-07-28T10:58:26,730 adding 'tests/test_session_pool.py' 2023-07-28T10:58:26,733 adding 'tests/test_tablet.py' 2023-07-28T10:58:26,736 adding 'tests/test_template.py' 2023-07-28T10:58:26,739 adding 'tests/test_todf.py' 2023-07-28T10:58:26,745 adding 'apache_iotdb-1.1.2.dist-info/LICENSE' 2023-07-28T10:58:26,752 adding 'apache_iotdb-1.1.2.dist-info/METADATA' 2023-07-28T10:58:26,754 adding 'apache_iotdb-1.1.2.dist-info/WHEEL' 2023-07-28T10:58:26,756 adding 'apache_iotdb-1.1.2.dist-info/entry_points.txt' 2023-07-28T10:58:26,758 adding 'apache_iotdb-1.1.2.dist-info/top_level.txt' 2023-07-28T10:58:26,761 adding 'apache_iotdb-1.1.2.dist-info/RECORD' 2023-07-28T10:58:26,770 removing build/bdist.linux-armv7l/wheel 2023-07-28T10:58:26,819 /tmp/pip-build-env-1hef8z5g/overlay/lib/python3.7/site-packages/setuptools/_distutils/dist.py:265: UserWarning: Unknown distribution option: 'website' 2023-07-28T10:58:26,820 warnings.warn(msg) 2023-07-28T10:58:26,952 Building wheel for apache-iotdb (pyproject.toml): finished with status 'done' 2023-07-28T10:58:26,975 Created wheel for apache-iotdb: filename=apache_iotdb-1.1.2-py3-none-any.whl size=158896 sha256=47e1ea2a866155bd45db05471a074cd1b4bede6e798d2b6a63e218767c92ae12 2023-07-28T10:58:26,977 Stored in directory: /tmp/pip-ephem-wheel-cache-5fv45ezk/wheels/f3/c7/4e/a7bee845a8e7868bfa3d549fa40e7a3a898aaadf3c93818842 2023-07-28T10:58:27,018 Successfully built apache-iotdb 2023-07-28T10:58:27,036 Removed build tracker: '/tmp/pip-build-tracker-xkvwt5eb'