{"id":50845,"date":"2023-02-02T00:00:00","date_gmt":"2023-02-02T08:00:00","guid":{"rendered":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/%e6%9c%aa%e5%88%86%e9%a1%9e\/scheduling-data-migration-from-postgresql-to-griddb-using-apache-airflow\/"},"modified":"2025-11-14T07:56:00","modified_gmt":"2025-11-14T15:56:00","slug":"scheduling-data-migration-from-postgresql-to-griddb-using-apache-airflow","status":"publish","type":"post","link":"https:\/\/griddb.net\/ja\/%e6%9c%aa%e5%88%86%e9%a1%9e\/scheduling-data-migration-from-postgresql-to-griddb-using-apache-airflow\/","title":{"rendered":"Apache Airflow\u3092\u4f7f\u3063\u3066PostgreSQL\u304b\u3089GridDB\u3078\u306e\u30c7\u30fc\u30bf\u79fb\u884c\u3092\u8a08\u753b\u3059\u308b"},"content":{"rendered":"<p>\u4ee5\u524d\u306e\u30d6\u30ed\u30b0\u3067\u3001<a href=\"https:\/\/www.kaggle.com\/datasets\/garystafford\/environmental-sensor-data-132k\">\u30b5\u30f3\u30d7\u30ebIoT\u30c7\u30fc\u30bf\u30bb\u30c3\u30c8<\/a>\u3092PostgreSQL\u304b\u3089GridDB\u306b\u79fb\u884c\u3059\u308b\u65b9\u6cd5\u306b\u3064\u3044\u3066\u8aac\u660e\u3057\u307e\u3057\u305f\u3002\u305d\u306e\u969b\u3001GridDB\u306e\u516c\u5f0f\u30a4\u30f3\u30dd\u30fc\u30c8\u30fb\u30a8\u30af\u30b9\u30dd\u30fc\u30c8\u30c4\u30fc\u30eb\u3092\u4f7f\u7528\u3057\u3001\u30c4\u30fc\u30eb\u306e\u4f7f\u7528\u65b9\u6cd5\u3068\u3001PostgreSQL\u304b\u3089GridDB\u306b\u79fb\u884c\u3059\u308b\u3079\u304d\u7406\u7531\u306b\u3064\u3044\u3066\u3082\u8aac\u660e\u3057\u307e\u3057\u305f\u3002\u305d\u306e\u5185\u5bb9\u306f\u3053\u3061\u3089\u306e\u30d6\u30ed\u30b0\u3067\u3054\u89a7\u3044\u305f\u3060\u3051\u307e\u3059\u3002<a href=\"https:\/\/griddb.net\/ja\/blog\/using-the-griddb-import-export-tools-to-migrate-from-postgresql-to-griddb\/\">GridDB\u30a4\u30f3\u30dd\u30fc\u30c8\u30fb\u30a8\u30af\u30b9\u30dd\u30fc\u30c8\u30c4\u30fc\u30eb\u3092\u4f7f\u3063\u3066PostgreSQL\u304b\u3089GridDB\u3078\u79fb\u884c\u3059\u308b<\/a>\u3002<\/p>\n<p>\u4eca\u56de\u306f\u3001PostgreSQL\u304b\u3089GridDB\u306b\u79fb\u884c\u3059\u308b\u969b\u306b\u3001\u30a4\u30f3\u30dd\u30fc\u30c8\u30fb\u30a8\u30af\u30b9\u30dd\u30fc\u30c8\u30c4\u30fc\u30eb\u3067\u306f\u306a\u304f<a href=\"https:\/\/airflow.apache.org\/\">Apache Airflow<\/a>\u3092\u4f7f\u3046\u65b9\u6cd5\u3092\u7d39\u4ecb\u3057\u307e\u3059\u3002\u3054\u5b58\u3058\u306a\u3044\u65b9\u306e\u305f\u3081\u306b\u8aac\u660e\u3059\u308b\u3068\u3001Airflow\u306f\u30ef\u30fc\u30af\u30d5\u30ed\u30fc\u3092\u30d7\u30ed\u30b0\u30e9\u30e0\u7684\u306b\u4f5c\u6210\u3001\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u3001\u76e3\u8996\u3059\u308b\u305f\u3081\u306e\u30d7\u30e9\u30c3\u30c8\u30d5\u30a9\u30fc\u30e0\u3067\u3059\u3002Airflow\u306f\u3001Python\u306e\u30b3\u30fc\u30c9\u3092\u4f7f\u3063\u3066\u30ef\u30fc\u30af\u30d5\u30ed\u30fc\u3092\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002\u3053\u308c\u3089\u306e\u30ef\u30fc\u30af\u30d5\u30ed\u30fc\u306f\u901a\u5e38\u3001\u5c0f\u3055\u306a\u30bf\u30b9\u30af\u306b\u5206\u5272\u3055\u308c\u3001\u9078\u629e\u3057\u305f\u9806\u5e8f\u3067\u5b9f\u884c\u3055\u308c\u308b\u3088\u3046\u306b\u4e26\u3079\u66ff\u3048\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002<\/p>\n<p>\u4eca\u56de\u306e\u30d6\u30ed\u30b0\u3067\u306f\u3001\u524d\u56de\u306e\u30d6\u30ed\u30b0\u3068\u540c\u3058\u30c7\u30fc\u30bf\u30bb\u30c3\u30c8\u3092Airflow\u3092\u4f7f\u3063\u3066\u79fb\u884c\u3057\u307e\u3059\u3002\u307e\u305f\u3001PostgeSQL\u304b\u3089GridDB\u3078\u5b9a\u671f\u7684\u306b\u65b0\u3057\u3044\u884c\u3092\u79fb\u884c\u3059\u308b\u305f\u3081\u306e<a href=\"https:\/\/airflow.apache.org\/docs\/apache-airflow\/1.10.12\/concepts.html\">DAG ( Directed Acyclic Graph )<\/a> \u3092\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u3057\u30012\u3064\u306e\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u5e38\u306b\u540c\u7b49\u3067\u3042\u308b\u3053\u3068\u3092\u78ba\u8a8d\u3057\u307e\u3059\u3002\uff08\u5c11\u306a\u304f\u3068\u3082\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u3057\u305f\u9593\u9694\u4ee5\u964d\u306f\u305d\u3046\u306a\u308b\u3067\u3057\u3087\u3046\u3002\uff09<\/p>\n<p>\u3053\u306e\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306e\u6280\u8853\u7684\u306a\u624b\u9806\u3092\u59cb\u3081\u308b\u524d\u306b\u3001\u307e\u305aAirflow\u3092\u30de\u30b7\u30f3\u306b\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3057\u3001\u3059\u3079\u3066\u306e\u524d\u63d0\u6761\u4ef6\u3082\u63c3\u3048\u3066\u304a\u304d\u307e\u3057\u3087\u3046\u3002<\/p>\n<h2>\u6e96\u5099\u3068\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb<\/h2>\n<p>\u3053\u306e\u30bb\u30af\u30b7\u30e7\u30f3\u3067\u306f\u3001\u524d\u8ff0\u306e\u3088\u3046\u306b\u3001\u3053\u306e\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3092\u3042\u306a\u305f\u306e\u30de\u30b7\u30f3\u306b\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3059\u308b\u65b9\u6cd5\u306b\u3064\u3044\u3066\u8aac\u660e\u3057\u307e\u3059\u3002Airflow\u306e\u826f\u3044\u3068\u3053\u308d\u306f\u3001\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3001\u5171\u6709\u3001\u304a\u3088\u3073\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u306e\u62e1\u5f35\u3092\u7c21\u5358\u306b\u5b9f\u73fe\u3059\u308b\u305f\u3081\u306edocker\u30a4\u30e1\u30fc\u30b8\u3092\u63d0\u4f9b\u3057\u3066\u3044\u308b\u3053\u3068\u3067\u3059\u3002\u3053\u306e\u8a18\u4e8b\u306f\u3001Docker\u30b3\u30f3\u30c6\u30ca\u3067Airflow\u3092\u4f7f\u7528\u3059\u308b\u3053\u3068\u304b\u3089\u52d5\u4f5c\u3057\u307e\u3059\u304c\u3001\u305d\u308c\u306b\u3064\u3044\u3066\u306f\u5f8c\u3067\u8a73\u3057\u304f\u8aac\u660e\u3057\u307e\u3059\u3002<\/p>\n<h3>\u524d\u63d0\u6761\u4ef6<\/h3>\n<p>\u3053\u306e\u30d6\u30ed\u30b0\u306e\u624b\u9806\u3092\u30d5\u30a9\u30ed\u30fc\u3059\u308b\u306b\u306f\u3001\u4ee5\u4e0b\u306e\u3082\u306e\u304c\u5fc5\u8981\u3067\u3059\u3002<\/p>\n<ul>\n<li><a href=\"https:\/\/docs.docker.com\/get-docker\/\">Docker<\/a><\/li>\n<li><a href=\"https:\/\/docs.docker.com\/compose\/install\/\">Docker-compose<\/a><\/li>\n<\/ul>\n<p>\u4ed6\u306e\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3084\u30e9\u30a4\u30d6\u30e9\u30ea\u306f\u3059\u3079\u3066docker\u30b3\u30f3\u30c6\u30ca\u3067\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3057\u307e\u3059\u3002<\/p>\n<h3>\u30bd\u30fc\u30b9\u30b3\u30fc\u30c9\u3092\u53d6\u5f97\u3059\u308b<\/h3>\n<p>\u3053\u306e\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306e\u3059\u3079\u3066\u306e\u30bd\u30fc\u30b9\u30b3\u30fc\u30c9\u3092\u53d6\u5f97\u3059\u308b\u306b\u306f\u3001\u4ee5\u4e0b\u306e\u30ea\u30dd\u30b8\u30c8\u30ea<a href=\"https:\/\/github.com\/griddbnet\/Blogs\/tree\/apache_airflow\">GitHub<\/a>\u3092\u30af\u30ed\u30fc\u30f3\u3057\u3066\u304f\u3060\u3055\u3044\u3002<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\">$  git clone https:\/\/github.com\/griddbnet\/Blogs.git --branch apache_airflow<\/code><\/pre>\n<\/div>\n<p>\u30af\u30ed\u30fc\u30f3\u5316\u3055\u308c\u308b\u3068\u3001\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3092\u59cb\u3081\u308b\u306e\u306b\u5fc5\u8981\u306adocker\u30d5\u30a1\u30a4\u30eb\u3084\u30b3\u30fc\u30c9\u304c\u5165\u3063\u305f\u30d5\u30a9\u30eb\u30c0\u304c\u3067\u304d\u307e\u3059\u3002<\/p>\n<h3>Docker\u30b3\u30f3\u30c6\u30ca\u306b\u3064\u3044\u3066<\/h3>\n<p>\u307e\u305a\u3001\u4e0a\u8a18\u3067\u5171\u6709\u3055\u308c\u305f\u30ea\u30dd\u30b8\u30c8\u30ea\u306b\u542b\u307e\u308c\u308bDockerfile\u3092\u78ba\u8a8d\u3057\u3001\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3092\u5b9f\u884c\u3059\u308b\u524d\u306b <code>docker-compose<\/code> \u30d5\u30a1\u30a4\u30eb\u306b\u3064\u3044\u3066\u8aac\u660e\u3057\u307e\u3059\u3002<\/p>\n<h4>Airflow\u30a4\u30e1\u30fc\u30b8\u3092\u62e1\u5f35\u3059\u308b\u305f\u3081\u306eDockerfile<\/h4>\n<p>\u307e\u305a\u3001<code>Dockerfile.airflow<\/code>\u3068\u3044\u3046\u30d5\u30a1\u30a4\u30eb\u304c\u3042\u308b\u3053\u3068\u306b\u6c17\u304c\u3064\u3044\u305f\u304b\u3082\u3057\u308c\u307e\u305b\u3093\u3002\u3053\u306e\u30d5\u30a1\u30a4\u30eb\u306f\u3001\u30aa\u30ea\u30b8\u30ca\u30eb\u306e <code>apache\/airflow<\/code> \u30a4\u30e1\u30fc\u30b8\u3092 <a href=\"https:\/\/airflow.apache.org\/docs\/docker-stack\/build.html#quick-start-scenarios-of-image-extending\">\u62e1\u5f35<\/a> \u3057\u3066\u3001\u3053\u306e\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306b\u5fc5\u8981\u306a Python \u30e9\u30a4\u30d6\u30e9\u30ea\u3092\u3044\u304f\u3064\u304b\u8ffd\u52a0\u3057\u3066\u3044\u307e\u3059\u3002<\/p>\n<p>\u30d5\u30a1\u30a4\u30eb\u306f\u3053\u306e\u3088\u3046\u306b\u306a\u308a\u307e\u3059\u3002<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\">FROM apache\/airflow:latest-python3.10\nCOPY requirements.txt \/requirements.txt\n\nUSER root\nRUN apt-get update \n  && apt-get install -y --no-install-recommends \n         default-jre  wget build-essential swig \n  && apt-get autoremove -yqq --purge \n  && apt-get clean \n  && rm -rf \/var\/lib\/apt\/lists\/*\n\nRUN wget https:\/\/repo1.maven.org\/maven2\/com\/github\/griddb\/gridstore-jdbc\/5.1.0\/gridstore-jdbc-5.1.0.jar -P \/usr\/share\/java\n\n# Install GridDB c_client\nWORKDIR \/\nRUN wget --no-check-certificate https:\/\/github.com\/griddb\/c_client\/releases\/download\/v5.0.0\/griddb-c-client_5.0.0_amd64.deb\nRUN dpkg -i griddb-c-client_5.0.0_amd64.deb\n\nUSER airflow\n\nRUN pip install --user --upgrade pip\nRUN pip install --no-cache-dir --user -r \/requirements.txt\nRUN pip install --no-cache-dir apache-airflow-providers-common-sql\nRUN pip install --no-cache-dir apache-airflow-providers-jdbc\nRUN pip install --no-cache-dir griddb-python\n\nENV JAVA_HOME=\/usr\/share\/java\/gridstore-jdbc-5.1.0.jar<\/code><\/pre>\n<\/div>\n<p>\u307e\u305a\u3001\u4eca\u56de\u306e\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3067\u306f\u3001JDBC\u3068GridDB Python\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u3092\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3057\u307e\u3059\u3002\u3053\u306e\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306e\u6b8b\u308a\u3067\u5b9f\u969b\u306bJDBC\u3092\u4f7f\u7528\u3059\u308b\u3053\u3068\u306f\u3042\u308a\u307e\u305b\u3093\u304c\u3001JDBC\u306fSQL\u3092\u30d5\u30eb\u306b\u4f7f\u7528\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u3001\u5c06\u6765\u306e\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u3067\u4fbf\u5229\u306b\u306a\u308b\u53ef\u80fd\u6027\u304c\u3042\u308b\u305f\u3081\u542b\u307e\u308c\u3066\u3044\u307e\u3059\u3002JDBC\u3092\u4f7f\u3063\u305f\u63a5\u7d9a\u306b\u3064\u3044\u3066\u306f\u3001\u5f8c\u307b\u3069\u8a73\u3057\u304f\u8aac\u660e\u3057\u307e\u3059\u3002<\/p>\n<p>GridDB Python\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u3092\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3059\u308b\u305f\u3081\u306b\u306f\u3001<code>python3.10<\/code>\u304c\u5fc5\u8981\u3067\u3042\u308a\u3001\u305d\u306e\u305f\u3081\u306b<code>apache\/airflow:latest-python3.10<\/code>\u3092\u62e1\u5f35\u3059\u308b\u3053\u3068\u306b\u3057\u307e\u3057\u305f\u3002GridDB Python Client\u3092\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3059\u308b\u3053\u3068\u3067\u3001<a href=\"http:\/\/www.toshiba-sol.co.jp\/en\/pro\/griddb\/docs-en\/v4_3\/GridDB_TQL_Reference.html\">TQL<\/a>\u7d4c\u7531\u3067GridDB\u306b\u30a2\u30af\u30bb\u30b9\u3057\u3001Python\u30b9\u30af\u30ea\u30d7\u30c8\u3067\u76f4\u63a5GridDB\u3092\u5229\u7528\u3059\u308b\u4f5c\u696d\u304c\u3067\u304d\u308b\u3088\u3046\u306b\u306a\u308a\u307e\u3059 \u3002\u3053\u308c\u306fPostgreSQL\u3067\u306f\u306a\u304fGridDB\u3092\u4f7f\u3046\u5927\u304d\u306a\u30e1\u30ea\u30c3\u30c8\u306e1\u3064\u3067\u3042\u308b\u3068\u8a00\u3048\u308b\u3067\u3057\u3087\u3046\u3002<\/p>\n<h4>GridDB\u30a4\u30e1\u30fc\u30b8\u3092\u62e1\u5f35\u3059\u308b\u305f\u3081\u306eDockerfile<\/h4>\n<p>\u6b21\u306b\u3053\u3053\u3067\u7d39\u4ecb\u3057\u305f\u3044\u306e\u306f\u3001<code>Dockerfile.griddb<\/code>\u3068\u3044\u3046\u30d5\u30a1\u30a4\u30eb\u3067\u3059\u3002\u4ee5\u4e0b\u306f\u305d\u306e\u5185\u5bb9\u3067\u3059\u3002<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\">from griddb\/griddb\n\nUSER root\n\n# Install GridDB c_client\nWORKDIR \/\nRUN wget --no-check-certificate https:\/\/github.com\/griddb\/c_client\/releases\/download\/v5.0.0\/griddb-c-client_5.0.0_amd64.deb\nRUN dpkg -i griddb-c-client_5.0.0_amd64.deb\n\nRUN wget --no-check-certificate https:\/\/github.com\/griddb\/cli\/releases\/download\/v5.0.0\/griddb-ce-cli_5.0.0_amd64.deb\nRUN dpkg -i griddb-ce-cli_5.0.0_amd64.deb\n\nUSER gsadm<\/code><\/pre>\n<\/div>\n<p>GridDB\u306e\u57fa\u672c\u30a4\u30e1\u30fc\u30b8\u3092\u62e1\u5f35\u3057\u3001\u4ed6\u306eGridDB\u30e9\u30a4\u30d6\u30e9\u30ea\u306e\u524d\u63d0\u6761\u4ef6\u3068\u3057\u3066GridDB C-Client\u3092\u8ffd\u52a0\u3057\u3066\u3044\u307e\u3059\u3002\u307e\u305f\u3001\u5fc5\u8981\u306b\u5fdc\u3058\u3066DB\u306b\u7c21\u5358\u306b\u554f\u3044\u5408\u308f\u305b\u304c\u3067\u304d\u308b\u3088\u3046\u306bGridDB CLI\u30c4\u30fc\u30eb\u3082\u8ffd\u52a0\u3057\u3066\u3044\u307e\u3059\u3002<\/p>\n<h4>Airflow\u306eDocker-Compose\u30d5\u30a1\u30a4\u30eb<\/h4>\n<p>\u3053\u306e\u30d5\u30a1\u30a4\u30eb\u306b\u306fAirflow\u30c4\u30fc\u30eb\u3092\u5b9f\u884c\u3059\u308b\u305f\u3081\u306b\u5fc5\u8981\u306a\u3059\u3079\u3066\u306e\u7570\u306a\u308b\u30b5\u30fc\u30d3\u30b9\u30fb\u30b3\u30f3\u30c6\u30ca\u304c\u542b\u307e\u308c\u3066\u3044\u307e\u3059\u3002\u3053\u306e\u30d5\u30a1\u30a4\u30eb\u306b\u306f\u3001Airflow\u30c4\u30fc\u30eb\u306e\u5b9f\u884c\u306b\u5fc5\u8981\u306a\u3059\u3079\u3066\u306e\u7570\u306a\u308b\u30b5\u30fc\u30d3\u30b9\u30fb\u30b3\u30f3\u30c6\u30ca\u304c\u542b\u307e\u308c\u3066\u3044\u307e\u3059\u3002<code>docker-compose<\/code>\u3092\u4f7f\u7528\u3059\u308b\u3053\u3068\u306e\u826f\u3044\u70b9\u306f\u3001\u30d5\u30a1\u30a4\u30eb\u5185\u306e\u3059\u3079\u3066\u306e\u30b5\u30fc\u30d3\u30b9\u304c\u81ea\u52d5\u7684\u306b\u5171\u6709\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u30b9\u30da\u30fc\u30b9\u306b\u914d\u7f6e\u3055\u308c\u308b\u3053\u3068\u3067\u3059\u3002\u305d\u308c\u3060\u3051\u3067\u306a\u304f\u3001\u81ea\u5206\u305f\u3061\u3067\u62e1\u5f35\u3057\u305f\u30a4\u30e1\u30fc\u30b8\u3082\u542b\u3081\u3066\u30011\u3064\u306e\u30b3\u30de\u30f3\u30c9\u3067\u3059\u3079\u3066\u306e\u30b5\u30fc\u30d3\u30b9\u3092\u7acb\u3061\u4e0a\u3052\u305f\u308a\u3001\u4e0b\u3052\u305f\u308a\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u3001\u3068\u3066\u3082\u4fbf\u5229\u3067\u3059\u3002<\/p>\n<p>\u30d5\u30a1\u30a4\u30eb\u304c\u672c\u5f53\u306b\u5927\u304d\u3044\u306e\u3067\u3001\u3053\u3053\u3067\u306f\u305d\u306e\u4e00\u90e8\u3092\u7d39\u4ecb\u3057\u307e\u3059\u3002<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\">---\nversion: '3'\nx-airflow-common:\n  &airflow-common\n  image: ${AIRFLOW_IMAGE_NAME:-extending_airflow:latest}\n  environment:\n    &airflow-common-env\n    AIRFLOW__CORE__EXECUTOR: CeleryExecutor\n    AIRFLOW__DATABASE__SQL_ALCHEMY_CONN: postgresql+psycopg2:\/\/airflow:airflow@postgres\/airflow\n    # For backward compatibility, with Airflow &lt;2.3\n    AIRFLOW__CORE__SQL_ALCHEMY_CONN: postgresql+psycopg2:\/\/airflow:airflow@postgres\/airflow\n    AIRFLOW__CELERY__RESULT_BACKEND: db+postgresql:\/\/airflow:airflow@postgres\/airflow\n    AIRFLOW__CELERY__BROKER_URL: redis:\/\/:@redis:6379\/0\n    AIRFLOW__CORE__FERNET_KEY: ''\n    AIRFLOW__CORE__DAGS_ARE_PAUSED_AT_CREATION: 'true'\n    AIRFLOW__CORE__LOAD_EXAMPLES: 'true'\n    AIRFLOW__API__AUTH_BACKENDS: 'airflow.api.auth.backend.basic_auth'\n    _PIP_ADDITIONAL_REQUIREMENTS: ${_PIP_ADDITIONAL_REQUIREMENTS:-}\n  volumes:\n    - .\/dags:\/opt\/airflow\/dags\n    - .\/logs:\/opt\/airflow\/logs\n    - .\/plugins:\/opt\/airflow\/plugins\n  user: \"${AIRFLOW_UID:-50000}:0\"\n  depends_on:\n    &airflow-common-depends-on\n    redis:\n      condition: service_healthy\n    postgres:\n      condition: service_healthy\n\n  griddb-server:\n    build:\n      context: .\n      dockerfile: Dockerfile.griddb\n    expose:\n      - \"10001\"\n      - \"10010\"\n      - \"10020\"\n      - \"10040\"\n      - \"20001\"\n      - \"41999\"\n    environment:\n      NOTIFICATION_MEMBER: 1\n      GRIDDB_CLUSTER_NAME: myCluster\n\n\n  postgres:\n    image: postgres:13\n    environment:\n      POSTGRES_USER: airflow\n      POSTGRES_PASSWORD: airflow\n      POSTGRES_DB: airflow\n    volumes:\n      - postgres-db-volume:\/var\/lib\/postgresql\/data\n      - .\/dags:\/var\/lib\/postgresql\/dags\n    ports: \n      - 5432:5432\n    healthcheck:\n      test: [\"CMD\", \"pg_isready\", \"-U\", \"airflow\"]\n      interval: 5s\n      retries: 5\n    restart: always\n\n      airflow-webserver:\n    &lt;&lt;: *airflow-common\n    command: webserver\n    ports:\n      - 8080:8080\n    healthcheck:\n      test: [\"CMD\", \"curl\", \"--fail\", \"http:\/\/localhost:8080\/health\"]\n      interval: 10s\n      timeout: 10s\n      retries: 5\n    restart: always\n    depends_on:\n      &lt;&lt;: *airflow-common-depends-on\n      airflow-init:\n        condition: service_completed_successfully<\/code><\/pre>\n<\/div>\n<p>\u3053\u306e\u30d5\u30a1\u30a4\u30eb\u306b\u306f\u3001\u4eca\u56de\u7d39\u4ecb\u3059\u308b2\u3064\u306e\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3092\u542b\u3080\u69d8\u3005\u306a\u30b3\u30f3\u30c6\u30ca\u3092\u5b9f\u884c\u3059\u308b\u305f\u3081\u306e\u624b\u9806\u304c\u542b\u307e\u308c\u3066\u3044\u307e\u3059\u3002\u307e\u305f\u3001GridDB\u30b5\u30fc\u30d3\u30b9\u304c\u30ed\u30fc\u30ab\u30eb\u306e <code>Dockerfile.griddb<\/code> \u30d5\u30a1\u30a4\u30eb\u304b\u3089\u76f4\u63a5\u30d3\u30eb\u30c9\u3055\u308c\u3066\u3044\u307e\u3059\u3002Airflow\u304c\u3053\u306e\u30ea\u30dd\u30b8\u30c8\u30ea\u306b\u72ec\u81ea\u306e<code>Dockerfile<\/code>\u3092\u6301\u3063\u3066\u3044\u308b\u306b\u3082\u304b\u304b\u308f\u3089\u305a\u3001\u540c\u3058\u6271\u3044\u3092\u53d7\u3051\u3066\u3044\u306a\u3044\u3053\u3068\u306b\u6c17\u304c\u3064\u3044\u305f\u65b9\u3082\u3044\u308b\u304b\u3082\u3057\u308c\u307e\u305b\u3093\u3002<\/p>\n<p>\u305d\u306e\u7406\u7531\u306f\u3001\u30aa\u30ea\u30b8\u30ca\u30eb\u306e Airflow compose \u30aa\u30fc\u30b1\u30b9\u30c8\u30ec\u30fc\u30b7\u30e7\u30f3\u30d5\u30a1\u30a4\u30eb\u3067\u306f\u3001\u591a\u304f\u306e\u7570\u306a\u308b\u30b5\u30fc\u30d3\u30b9\u9593\u3067\u3053\u306e\u30d5\u30a1\u30a4\u30eb\u3068\u306e\u4e00\u8cab\u6027\u3092\u4fdd\u3064\u305f\u3081\u306b <code>x-airflow-common<\/code> \u74b0\u5883\u5909\u6570\u3092\u4f7f\u7528\u3057\u3066\u3044\u308b\u304b\u3089\u3067\u3059\u3002\u3053\u306e\u3088\u3046\u306adocker-compose\u30d5\u30a1\u30a4\u30eb\u306e\u69cb\u7bc9\u3068\u3046\u307e\u304f\u3084\u308b\u305f\u3081\u306b\u306f\u3001compose\u30d5\u30a1\u30a4\u30eb\u304c\u3053\u306e\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306e\u76ee\u7684\u306e\u305f\u3081\u306b\u305d\u306e\u69cb\u7bc9\u6e08\u307f\u306e\u30a4\u30e1\u30fc\u30b8\u3092\u4f7f\u7528\u3067\u304d\u308b\u3088\u3046\u306b\u3001\u30ed\u30fc\u30ab\u30eb\u306b\u30a4\u30e1\u30fc\u30b8\u3092\u69cb\u7bc9\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002<\/p>\n<h3>Docker\u30b3\u30f3\u30c6\u30ca\u3092\u5b9f\u884c\u3059\u308b<\/h3>\n<p>\u4e0a\u3067\u8ff0\u3079\u305f\u901a\u308a\u3001\u307e\u305a\u6700\u521d\u306b <code>Dockerfile.airflow<\/code> \u30a4\u30e1\u30fc\u30b8\u306e\u30d3\u30eb\u30c9\u3092\u884c\u3044\u3001\u305d\u308c\u304c\u5b8c\u4e86\u3057\u305f\u3089\u3001<code>docker-compose<\/code> \u30b3\u30de\u30f3\u30c9\u3092\u4f7f\u3063\u3066\u3059\u3079\u3066\u3092\u4e00\u5ea6\u306b\u5b9f\u884c\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u308b\u3088\u3046\u306b\u306a\u308a\u307e\u3059\u3002<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\">$ docker build -f Dockerfile.airflow . --tag extending_airflow:latest<\/code><\/pre>\n<\/div>\n<p>\u3053\u306e\u30a4\u30e1\u30fc\u30b8\u304c\u30d3\u30eb\u30c9\u3055\u308c\u308b\u3068\u3001\u30ed\u30fc\u30ab\u30eb\u74b0\u5883\uff08<code>$ docker images<\/code>\uff09\u306b <code>extending_airflow:latest<\/code> \u30a4\u30e1\u30fc\u30b8\u304c\u8868\u793a\u3055\u308c\u308b\u3088\u3046\u306b\u306a\u308a\u307e\u3059\u3002<\/p>\n<p>\u3053\u308c\u3067\u6e96\u5099\u304c\u3067\u304d\u3001\u3059\u3079\u3066\u306e\u30b5\u30fc\u30d3\u30b9\u3092\u5b9f\u884c\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u308b\u3088\u3046\u306b\u306a\u308a\u307e\u3057\u305f\u3002<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\">$ docker-compose up -d<\/code><\/pre>\n<\/div>\n<pre><code>[+] Running 8\/8\n\u283f Container griddb-airflow      Running                                                                  0.0s\n\u283f Container airflow-redis-1              Healthy                                                                 18.6s\n\u283f Container postgres-airflow           Healthy                                                                 18.6s\n\u283f Container airflow-airflow-init-1       Exited                                                                  37.2s\n\u283f Container airflow-airflow-triggerer-1  Started                                                                 37.9s\n\u283f Container airflow-airflow-scheduler-1  Started                                                                 37.9s\n\u283f Container airflow-airflow-worker-1     Started                                                                 37.9s\n\u283f Container airflow-airflow-webserver-1  Started                                                                 37.5s\n<\/code><\/pre>\n<p>\u3053\u308c\u306f\u3001dockerhub\u304b\u3089\u95a2\u9023\u3059\u308b\u3059\u3079\u3066\u306e\u30a4\u30e1\u30fc\u30b8\u3092\u53d6\u5f97\u3059\u308b\u304b\u3001\u30ed\u30fc\u30ab\u30eb\u3067\u30a4\u30e1\u30fc\u30b8\u3092\u69cb\u7bc9\uff08<code>Dockerfile.griddb<\/code>\uff09\u3057\u307e\u3059\u3002\u6e96\u5099\u304c\u6574\u3046\u3068\u3001\u3059\u3079\u3066\u306e\u30b3\u30f3\u30c6\u30ca\u304c\u3042\u306a\u305f\u306e\u30de\u30b7\u30f3\u4e0a\u3067\u76f4\u63a5\u5b9f\u884c\u3055\u308c\u308b\u3088\u3046\u306b\u306a\u308a\u307e\u3059\u3002<\/p>\n<p>\u3053\u308c\u306f\u3001<code>process status<\/code>\u30b3\u30de\u30f3\u30c9\u3092\u5b9f\u884c\u3057\u3066\u78ba\u8a8d\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\">$ docker ps<\/code><\/pre>\n<\/div>\n<pre><code>CONTAINER ID   IMAGE                                      COMMAND                  CREATED              STATUS                          PORTS                                                                                                                                                                                                                                                                                                                NAMES\nad1511b22415   extending_airflow:latest                   \"\/usr\/bin\/dumb-init \u2026\"   About a minute ago   Up About a minute (healthy)     0.0.0.0:8080-&gt;8080\/tcp, :::8080-&gt;8080\/tcp                                                                                                                                                                                                                                                                            3_airflow_migration-airflow-webserver-1\n68bdef86bf4f   extending_airflow:latest                   \"\/usr\/bin\/dumb-init \u2026\"   About a minute ago   Up About a minute (healthy)     8080\/tcp                                                                                                                                                                                                                                                                                                             3_airflow_migration-airflow-scheduler-1\nb020473ce932   extending_airflow:latest                   \"\/usr\/bin\/dumb-init \u2026\"   About a minute ago   Up About a minute (healthy)     8080\/tcp                                                                                                                                                                                                                                                                                                             3_airflow_migration-airflow-triggerer-1\n69c99ea8ce87   extending_airflow:latest                   \"\/usr\/bin\/dumb-init \u2026\"   About a minute ago   Up About a minute (healthy)     8080\/tcp                                                                                                                                                                                                                                                                                                             3_airflow_migration-airflow-worker-1\n9c778c1f1d72   3_airflow_migration_griddb-server          \"\/bin\/bash \/start-gr\u2026\"   About a minute ago   Up About a minute               10001\/tcp, 10010\/tcp, 10020\/tcp, 10040\/tcp, 20001\/tcp, 41999\/tcp                                                                                                                                                                                                                                                     griddb-airflow\n921cc78b8c1b   redis:latest                               \"docker-entrypoint.s\u2026\"   About a minute ago   Up About a minute (healthy)     6379\/tcp                                                                                                                                                                                                                                                                                                             3_airflow_migration-redis-1\n0ba780dd6b99   postgres:13                                \"docker-entrypoint.s\u2026\"   About a minute ago   Up About a minute (healthy)     0.0.0.0:5432-&gt;5432\/tcp, :::5432-&gt;5432\/tcp                                                                                                                                                                                                                                                                            postgres-airflow\n<\/code><\/pre>\n<h2>Apache Airflow\u3092\u4f7f\u7528\u3059\u308b<\/h2>\n<p>\u3055\u3066\u3001\u30c4\u30fc\u30eb\u3092\u7acb\u3061\u4e0a\u3052\u3066\u5b9f\u884c\u3057\u305f\u3068\u3053\u308d\u3067\u3001\u6b21\u306b\u3084\u308a\u305f\u3044\u3053\u3068\u306f\u3082\u3061\u308d\u3093\u3001\u30c4\u30fc\u30eb\u3068\u306e\u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30a4\u30b9\u3067\u3059\u3002docker-compose \u30d5\u30a1\u30a4\u30eb\u5185\u306e\u30b3\u30f3\u30c6\u30ca\u30fb\u30b5\u30fc\u30d3\u30b9\u306e 1 \u3064\u306f\u3001\u30ef\u30fc\u30af\u30d5\u30ed\u30fc\u3092\u7ba1\u7406\u3059\u308b\u305f\u3081\u306e\u512a\u308c\u305f UI \u3092\u5099\u3048\u305f Web \u30b5\u30fc\u30d0\u30fc\u3092\u30db\u30b9\u30c8\u3057\u3066\u3044\u307e\u3059\u3002<\/p>\n<p>\u30d6\u30e9\u30a6\u30b6\u3067 http:\/\/localhost:8080\/ \u306b\u30a2\u30af\u30bb\u30b9\u3057\u3001\u8a8d\u8a3c\u60c5\u5831\u3092\u5165\u529b\u3057\u307e\u3059\u3002\uff08\u30e6\u30fc\u30b6\u30fc\u540d\u3068\u30d1\u30b9\u30ef\u30fc\u30c9\u306f\u3069\u3061\u3089\u3082 <code>airflow<\/code> \u3067\u3059\u3002\uff09\u3053\u3053\u304b\u3089\u3001\u4e8b\u524d\u306b\u4f5c\u6210\u3055\u308c\u305fDAG\u306e\u5927\u304d\u306a\u30ea\u30b9\u30c8\u304c\u8868\u793a\u3055\u308c\u307e\u3059\u3002\u3053\u308c\u3089\u306f\u3001\u30c7\u30fc\u30bf\u30d5\u30ed\u30fc\u3092\u30aa\u30fc\u30b1\u30b9\u30c8\u30ec\u30fc\u30b7\u30e7\u30f3\u3059\u308b\u305f\u3081\u306b\u7ba1\u7406\u3055\u308c\u308b\u30ef\u30fc\u30af\u30d5\u30ed\u30fc\u3067\u3059\u3002\u4eca\u56de\u306e\u30b1\u30fc\u30b9\u3067\u306f\u3001Postgresql\u306e\u5168\u30c7\u30fc\u30bf\u30921\u56de\u3067\u79fb\u884c\u3059\u308b\u305f\u3081\u306eDAG\u3068\u3001\u7d99\u7d9a\u7684\u306b\u79fb\u884c\u3059\u308b\u305f\u3081\u306eDAG\u306e2\u7a2e\u985e\u3092\u4f5c\u6210\u3057\u305f\u3044\u3068\u601d\u3044\u307e\u3059\u3002<\/p>\n<p>\u305d\u306e\u524d\u306b\u3001\u65b0\u3057\u304f\u4f5c\u6210\u3057\u305fPostgreSQL\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u3001\u79fb\u884c\u3057\u305f\u3044\u30c7\u30fc\u30bf\u304c\u3042\u308b\u3053\u3068\u3092\u78ba\u8a8d\u3057\u3066\u304a\u304d\u307e\u3057\u3087\u3046\u3002<\/p>\n<p><a href=\"https:\/\/griddb.net\/wp-content\/uploads\/2023\/01\/airflow-1.png\"><img fetchpriority=\"high\" decoding=\"async\" src=\"https:\/\/griddb.net\/wp-content\/uploads\/2023\/01\/airflow-1.png\" alt=\"\" width=\"1396\" height=\"646\" class=\"aligncenter size-full wp-image-29061\" srcset=\"\/wp-content\/uploads\/2023\/01\/airflow-1.png 1396w, \/wp-content\/uploads\/2023\/01\/airflow-1-300x139.png 300w, \/wp-content\/uploads\/2023\/01\/airflow-1-1024x474.png 1024w, \/wp-content\/uploads\/2023\/01\/airflow-1-768x355.png 768w, \/wp-content\/uploads\/2023\/01\/airflow-1-600x278.png 600w\" sizes=\"(max-width: 1396px) 100vw, 1396px\" \/><\/a><\/p>\n<h3>Airflow UI \u3092\u4f7f\u7528\u3057\u3066\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3068\u63a5\u7d9a\u3059\u308b<\/h3>\n<p>Python\u306e\u30b3\u30fc\u30c9\uff08DAG\uff09\u3092\u66f8\u304f\u524d\u306b\u3001\u307e\u305aAirflow\u306e\u30b9\u30b1\u30b8\u30e5\u30fc\u30e9\u30fc\u30fb\u30ef\u30fc\u30ab\u30fc\u30fb\u30a6\u30a7\u30d6\u30b5\u30fc\u30d0\u30fc\u304cGridDB\u30b5\u30fc\u30d0\u30fc\u3084PostgreSQL\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3068\u5bfe\u8a71\u3067\u304d\u308b\u3053\u3068\u3092\u78ba\u8a8d\u3057\u307e\u3057\u3087\u3046\u3002\u5148\u306b\u8aac\u660e\u3057\u305f\u3088\u3046\u306b\u3001\u3053\u308c\u3089\u306e\u30b5\u30fc\u30d3\u30b9\u306f\u3059\u3079\u3066docker-compose\u30d5\u30a1\u30a4\u30eb\u3092\u5171\u6709\u3057\u3066\u3044\u308b\u305f\u3081\u3001\u81ea\u52d5\u7684\u306b\u3059\u3079\u3066\u540c\u3058\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u7a7a\u9593\u3092\u5171\u6709\u3059\u308b\u3053\u3068\u306b\u306a\u308a\u307e\u3059\u3002<\/p>\n<p>\u307e\u305a\u3001PostgreSQL\u306b\u63a5\u7d9a\u3057\u3066\u307f\u307e\u3057\u3087\u3046\u3002<\/p>\n<h4>PostgreSQL\u306b\u63a5\u7d9a\u3059\u308b<\/h4>\n<p>\u3067\u306f\u307e\u305a\u3001PostgreSQL\u306e\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u63a5\u7d9a\u3057\u3066\u307f\u307e\u3057\u3087\u3046\u3002<\/p>\n<p>\u30d6\u30e9\u30a6\u30b6\u3067Admin &#8211;> Connections\u306b\u79fb\u52d5\u3057\u307e\u3059\u3002<\/p>\n<p>\u3053\u3053\u3067\u3001\u5bfe\u8c61\u3068\u306a\u308b\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3078\u306e\u660e\u793a\u7684\u306a\u63a5\u7d9a\u3092\u884c\u3046\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002PostgreSQL\u306e\u5834\u5408\u306f\u3001\u63a5\u7d9a\u306e\u7a2e\u985e\u306e\u30c9\u30ed\u30c3\u30d7\u30c0\u30a6\u30f3\u304b\u3089\u9078\u629e\u3057\u3001\u8a8d\u8a3c\u60c5\u5831\u3092\u5165\u529b\u3057\u307e\u3059\u3002<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\">Host: postgres\nSchema: airflow\nLogin: airflow\nPassword: airflow\nPort: 5432<\/code><\/pre>\n<\/div>\n<p>test\u3092\u62bc\u3057\u305f\u3089\u3001\u6210\u529f\u3057\u305f\u3068\u8868\u793a\u3055\u308c\u308b\u306f\u305a\u3067\u3059\u3002host\u306fdocker-compose\u30d5\u30a1\u30a4\u30eb\u5185\u306e\u30b5\u30fc\u30d3\u30b9\u540d\u3067\u3059\u3002\uff08\u30b5\u30fc\u30d3\u30b9\u540d\u306f\u30db\u30b9\u30c8\u540d\u3067\u3001\u5171\u6709\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3067\u306fIP\u30a2\u30c9\u30ec\u30b9\u306b\u76f8\u5f53\u3057\u307e\u3059\u3002\uff09<\/p>\n<p><a href=\"https:\/\/griddb.net\/wp-content\/uploads\/2023\/02\/airflow-2.png\"><img decoding=\"async\" src=\"https:\/\/griddb.net\/wp-content\/uploads\/2023\/02\/airflow-2.png\" alt=\"\" width=\"1079\" height=\"875\" class=\"aligncenter size-full wp-image-29383\" srcset=\"\/wp-content\/uploads\/2023\/02\/airflow-2.png 1079w, \/wp-content\/uploads\/2023\/02\/airflow-2-300x243.png 300w, \/wp-content\/uploads\/2023\/02\/airflow-2-1024x830.png 1024w, \/wp-content\/uploads\/2023\/02\/airflow-2-768x623.png 768w, \/wp-content\/uploads\/2023\/02\/airflow-2-600x487.png 600w\" sizes=\"(max-width: 1079px) 100vw, 1079px\" \/><\/a><\/p>\n<h4>GridDB\u306b\u63a5\u7d9a\u3059\u308b<\/h4>\n<p>GridDB\u306b\u63a5\u7d9a\u3059\u308b\u306b\u306f\u3001\u4e0a\u8a18\u306e\u65b9\u6cd5\u3068\u540c\u3058\u3088\u3046\u306bJDBC\u3067\u63a5\u7d9a\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\">Connection Type: JDBC Connection\nConnection URL: jdbc:gs:\/\/griddb-server:20001\/myCluster\/public\nLogin: admin\nPassword: admin\nDriver Path: \/usr\/share\/java\/gridstore-jdbc-5.1.0.jar\nDriver Class: com.toshiba.mwcloud.gs.sql.Driver<\/code><\/pre>\n<\/div>\n<p><a href=\"https:\/\/griddb.net\/wp-content\/uploads\/2023\/01\/airflow-3.png\"><img decoding=\"async\" src=\"https:\/\/griddb.net\/wp-content\/uploads\/2023\/01\/airflow-3.png\" alt=\"\" width=\"1873\" height=\"1260\" class=\"aligncenter size-full wp-image-29063\" srcset=\"\/wp-content\/uploads\/2023\/01\/airflow-3.png 1873w, \/wp-content\/uploads\/2023\/01\/airflow-3-300x202.png 300w, \/wp-content\/uploads\/2023\/01\/airflow-3-1024x689.png 1024w, \/wp-content\/uploads\/2023\/01\/airflow-3-768x517.png 768w, \/wp-content\/uploads\/2023\/01\/airflow-3-1536x1033.png 1536w, \/wp-content\/uploads\/2023\/01\/airflow-3-600x404.png 600w\" sizes=\"(max-width: 1873px) 100vw, 1873px\" \/><\/a><\/p>\n<p>\u4ed6\u306b\u3001Python\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u3067\u63a5\u7d9a\u3059\u308b\u3053\u3068\u3082\u53ef\u80fd\u3067\u3059\u3002<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-python\">import griddb_python as griddb\n\nfactory = griddb.StoreFactory.get_instance()\nDB_HOST = \"griddb-server:10001\" #griddb-server is the hostname of the service\nDB_CLUSTER = \"myCluster\"\nDB_USER = \"admin\"\nDB_PASS = \"admin\"\n\ngridstore = factory.get_store(\n    notification_member=DB_HOST, cluster_name=DB_CLUSTER, username=DB_USER, password=DB_PASS\n)<\/code><\/pre>\n<\/div>\n<p>\u4e0a\u8a18\u306ePython\u30b3\u30fc\u30c9\u306f\u3001GridDB\u3092\u5229\u7528\u3057\u3088\u3046\u3068\u3059\u308bPython DAG\u306e\u5185\u90e8\u306b\u633f\u5165\u3055\u308c\u308b\u3060\u3051\u3067\u3001UI\u306eConnections\u30bf\u30d6\u3067\u660e\u793a\u3055\u308c\u308b\u308f\u3051\u3067\u306f\u3042\u308a\u307e\u305b\u3093\u3002<\/p>\n<h3>PostgreSQL\u30b3\u30f3\u30c6\u30ca\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u30c7\u30fc\u30bf\u3092\u53d6\u308a\u8fbc\u3080<\/h3>\n<p>\u3053\u306e\u30c7\u30e2\u3067\u306f\u3001CSV\u3092PostgreSQL\u30b3\u30f3\u30c6\u30ca\u306b\u30b3\u30d4\u30fc\u3057\u3001<code>COPY<\/code>\u30b3\u30de\u30f3\u30c9\u3092\u4f7f\u7528\u3057\u3066\u3001\u5fc5\u8981\u306a\u95a2\u9023\u30c7\u30fc\u30bf\u3092\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u53d6\u308a\u8fbc\u307f\u307e\u3059\u3002<\/p>\n<p>\u307e\u305a\u6700\u521d\u306b\u3001\u30ed\u30fc\u30ab\u30eb\u30de\u30b7\u30f3\u304b\u3089PostgreSQL\u30b3\u30f3\u30c6\u30ca\u3078<code>.csv<\/code>\u30d5\u30a1\u30a4\u30eb\u3092\u30b3\u30d4\u30fc\u3057\u307e\u3059\u3002\u3053\u308c\u306f<code>docker-compose<\/code>\u30d5\u30a1\u30a4\u30eb\u306b\u3088\u3063\u3066\u547d\u540d\u3055\u308c\u305f\u30a4\u30e1\u30fc\u30b8\u540d(airflow-postgres-1)\u3068<code>docker cp<\/code>\u30b3\u30de\u30f3\u30c9\u3092\u4f7f\u7528\u3059\u308b\u3053\u3068\u306b\u3088\u3063\u3066\u5b9f\u73fe\u3067\u304d\u307e\u3059\u3002\u30b3\u30d4\u30fc\u3059\u308b\u30d5\u30a1\u30a4\u30eb\u306f\u3001<code>dags\/data\/device.csv<\/code>\u306e\u4e2d\u306b\u3042\u308a\u307e\u3059\u3002<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\">$ docker cp dags\/data\/device.csv postgres-airflow:\/tmp\/<\/code><\/pre>\n<\/div>\n<p><code>docker cp<\/code> \u30b3\u30de\u30f3\u30c9\u306f\u3001\u901a\u5e38\u306eCLI\u64cd\u4f5c\u306b\u304a\u3051\u308b <code>scp<\/code> \u3084 <code>cp<\/code> \u30b3\u30de\u30f3\u30c9\u3068\u540c\u69d8\u306b\u5b9f\u884c\u3055\u308c\u307e\u3059\u3002<\/p>\n<p>csv\u30d5\u30a1\u30a4\u30eb\u3092\u30b3\u30d4\u30fc\u3057\u305f\u3089\u3001PostgreSQL\u30b3\u30f3\u30c6\u30ca\u306bssh\u3057\u307e\u3059\u3002<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\">$ docker exec -it airflow-postgres-1 bash<\/code><\/pre>\n<\/div>\n<p>\u305d\u3053\u306b\u5165\u3063\u305f\u3089\u3001\u30e6\u30fc\u30b6\u30fcairflow\u3068\u3057\u3066<code>psql shell<\/code>\u306b\u30c9\u30ed\u30c3\u30d7\u3057\u307e\u3059\u3002<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\"># psql -U airflow\npsql (13.9 (Debian 13.9-1.pgdg110+1))\nType \"help\" for help.\n\nairflow=#<\/code><\/pre>\n<\/div>\n<p>\u3053\u3053\u304b\u3089\u7c21\u5358\u306bCSV\u30c7\u30fc\u30bf\u3092DB\u306b\u53d6\u308a\u8fbc\u3080\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002\u307e\u305a\u3001\u30c6\u30fc\u30d6\u30eb\u3092\u4f5c\u6210\u3057\u3001CSV\u306e\u884c\u3092\u305d\u306e\u30c6\u30fc\u30d6\u30eb\u306b\u30b3\u30d4\u30fc\u3059\u308b\u3088\u3046\u306b\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u6307\u793a\u3057\u307e\u3059\u3002<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\">airflow=# CREATE TABLE if not exists device ( ts timestamp, device varchar(30), co float8, humidity float8, light bool, lpg float8, motion bool, smoke float8, temp float8 );<\/code><\/pre>\n<\/div>\n<pre><code>CREATE TABLE\n<\/code><\/pre>\n<p>\u305d\u3057\u3066\u3001\u3059\u3079\u3066\u3092 <code>COPY<\/code> \u3057\u307e\u3059\u3002<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\">airflow=# copy device(ts, device, co, humidity, light, lpg, motion, smoke, temp) from '\/tmp\/device.csv' DELIMITER ',' CSV HEADER;<\/code><\/pre>\n<\/div>\n<h3>PostgreSQL\u304b\u3089GridDB\u3078\u79fb\u884c\u3059\u308b<\/h3>\n<p>\u3053\u3053\u3067\u3001GridDB\u3078\u306e\u79fb\u884c\u306e\u305f\u3081\u306e\u6700\u521d\u306eDAG\u3092\u4f5c\u6210\u3057\u307e\u3059\u3002Airflow\u306fPython\u3067\u69cb\u7bc9\u3055\u308c\u3066\u3044\u308b\u305f\u3081\u3001DAG\u306f\u5358\u7d14\u306bPython\u30b3\u30fc\u30c9\u3068\u3044\u304f\u3064\u304b\u306e\u7c21\u5358\u306aAirflow\u5b9a\u578b\u6587\u3067\u69cb\u6210\u3055\u308c\u3066\u3044\u307e\u3059\u3002\u30d5\u30a1\u30a4\u30eb\u30b9\u30cb\u30da\u30c3\u30c8\u306b\u5165\u308b\u524d\u306b\u3001\u7b46\u8005\u306fGridDB Python\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u3092\u4f7f\u7528\u3057\u3066\u3044\u308b\u306e\u3067\u3001\u7b46\u8005\u306eAirflow DAG\u306e\u4e2d\u304b\u3089\u76f4\u63a5GridDB\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u3068\u7c21\u5358\u306b\u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30fc\u30b9\u3067\u304d\u308b\u3053\u3068\u3092\u7279\u7b46\u3057\u3066\u304a\u304d\u307e\u3059\u3002\u305d\u306e\u305f\u3081\u3001\u95a2\u4fc2\u3059\u308b\u30b3\u30fc\u30c9\u3092\u898b\u3066\u3082\u3001\u305d\u306e\u591a\u304f\u306f\u901a\u5e38\u306ePython\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3068\u3042\u307e\u308a\u5909\u308f\u308a\u307e\u305b\u3093\u3002<\/p>\n<h4>\u30a8\u30a2\u30d5\u30ed\u30fc\u5c02\u7528Python\u30b3\u30fc\u30c9<\/h4>\n<p>\u3053\u3053\u306b\u7b46\u8005\u306eGridDB Migration DAG\u306e\u30b9\u30cb\u30da\u30c3\u30c8\u304c\u3042\u308a\u307e\u3059\u3002\u3053\u306e\u6700\u521d\u306e\u90e8\u5206\u306f\u3001\u30b3\u30fc\u30c9\u306eAirflow\u56fa\u6709\u306e\u90e8\u5206\u306e\u307f\u3092\u7d39\u4ecb\u3059\u308b\u3053\u3068\u306b\u7559\u3081\u3066\u304a\u304d\u307e\u3059\u3002\u307e\u305a\u3001Airflow\u306e\u30e9\u30a4\u30d6\u30e9\u30ea\u3092\u30a4\u30f3\u30dd\u30fc\u30c8\u3057\u307e\u3059\u3002<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-python\">from airflow import DAG\nfrom airflow.providers.postgres.operators.postgres import PostgresOperator\nfrom airflow.hooks.postgres_hook import PostgresHook\n\nfrom airflow.operators.python import PythonOperator\n\ndefault_args = {\n    'owner': 'israel',\n    'retries': 5,\n    'retry_delay': timedelta(minutes=5)\n}\n\nwith DAG(\n    dag_id='dag_migrating_postgres_to_griddb_v04',\n    default_args=default_args,\n    start_date=datetime(2021, 12, 19),\n    schedule_interval='@once'\n) as dag:\n\n    task1 = PythonOperator(\n        task_id='migrate_from_postgres_to_griddb',\n        python_callable=migrate_from_postgres_to_griddb\n    )\n\n    task1<\/code><\/pre>\n<\/div>\n<p>\u3053\u308c\u304c\u7d42\u308f\u3063\u305f\u3089\u3001DAG\u306e\u8a2d\u5b9a\u30aa\u30d7\u30b7\u30e7\u30f3\u3001\u3064\u307e\u308aID\uff08\u540d\u524d\uff09\u3068\u3001\u3053\u306e\u30bf\u30b9\u30af\u3092\u5b9f\u884c\u3059\u308b\u305f\u3081\u306e\u9078\u629e\u3057\u305f\u9593\u9694\u3092\u5165\u529b\u3057\u307e\u3059\u3002\u3053\u306eDAG\u306b\u3064\u3044\u3066\u4e00\u3064\u6307\u6458\u3057\u3066\u304a\u304f\u3068\u3001\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u3055\u308c\u305f\u9593\u9694\u306f\u5358\u306b<code>@once<\/code>\u3067\u3042\u308a\u3001\u3064\u307e\u308a\u3053\u306eDAG\u3092\u4e00\u5ea6\u5b9f\u884c\u3059\u308b\u3068\u3001\u518d\u5ea6\u5b9f\u884c\u3059\u308b\u305f\u3081\u306e\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u306f\u7d44\u307e\u308c\u306a\u3044\u3053\u3068\u306b\u6ce8\u610f\u3057\u3066\u304f\u3060\u3055\u3044\u3002<\/p>\n<p>\u6b21\u306b\u3001\u30d5\u30a1\u30a4\u30eb\u306e\u4e00\u756a\u4e0b\u3067\u3001\u3069\u306e\u3088\u3046\u306a\u30bf\u30b9\u30af\u3092\u3069\u306e\u3088\u3046\u306a\u9806\u5e8f\u3067\u5b9f\u884c\u3059\u308b\u304b\u3092\u9078\u629e\u3057\u307e\u3059\u3002\u3053\u306e\u30ef\u30fc\u30af\u30d5\u30ed\u30fc\u3067\u306f\u3001task1\u3068\u3044\u30461\u3064\u306e\u30bf\u30b9\u30af\u3092\u547c\u3073\u51fa\u3059\u3060\u3051\u3067\u3001python\u306e\u95a2\u6570 <code>migrate_from_postgres_to_griddb<\/code> \u304c\u547c\u3073\u51fa\u3055\u308c\u307e\u3059\u3002<\/p>\n<p>PostgreSQL\u306b\u554f\u3044\u5408\u308f\u305b\u3001\u95a2\u9023\u3059\u308b\u3059\u3079\u3066\u306e\u30c7\u30fc\u30bf\u3092\u53d6\u5f97\u3057\u3001\u5fc5\u8981\u306b\u5fdc\u3058\u3066\u5909\u63db\u3057\u3066\u3001GridDB\u30b5\u30fc\u30d0\u306b<code>put<\/code>\u3057\u307e\u3059\u3002<\/p>\n<h4>DAG \u5185\u3067 PostgreSQL \u3092\u63a5\u7d9a\u3001\u30af\u30a8\u30ea\u3059\u308b<\/h4>\n<p>\u3053\u3053\u3067\u306f\u3001\u5b9f\u969b\u306e\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u3092\u51e6\u7406\u3059\u308bPython\u95a2\u6570\u3092\u7d39\u4ecb\u3057\u307e\u3059\u3002<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-python\">def migrate_from_postgres_to_griddb(**context):\n    \"\"\"\n    Queries Postgres and places all data into GridDB\n    \"\"\"\n\n    gridstore = factory.get_store(\n        notification_member=DB_HOST, cluster_name=DB_CLUSTER, username=DB_USER, password=DB_PASS\n    )\n\n    postgres = PostgresHook(postgres_conn_id=\"postgres\")\n    conn = postgres.get_conn()\n    cursor = conn.cursor()\n    cursor.execute(\"SELECT * FROM device;\")<\/code><\/pre>\n<\/div>\n<p>\u524d\u56de\u306e\u30d6\u30ed\u30b0\u3068\u540c\u69d8\u306b\u3001PostgreSQL\u306e\u30c6\u30fc\u30d6\u30eb\u3092\u305d\u306e\u307e\u307eGridDB\u306e\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u5185\u306b\u914d\u7f6e\u3059\u308b\u306e\u3067\u306f\u306a\u304f\u3001\u3088\u308aIoT\u306b\u7279\u5316\u3057\u305f\u30b9\u30ad\u30fc\u30de\u3092\u63a1\u7528\u3057\u3066\u3044\u307e\u3059\u3002IoT\u306b\u7279\u5316\u3057\u305f\u30b9\u30ad\u30fc\u30de\u3067\u3001\u30c7\u30fc\u30bf\u30bb\u30c3\u30c8\u306e\u5404\u30bb\u30f3\u30b5\u30fc\u304c\u305d\u308c\u305e\u308c\u30b3\u30f3\u30c6\u30ca\uff08\u30c6\u30fc\u30d6\u30eb\uff09\u3092\u6301\u3063\u3066\u3044\u307e\u3059\u3002\u307e\u305a\u306f\u5404\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u5fc5\u8981\u306a\u63a5\u7d9a\u3092\u884c\u3044\u307e\u3059\u3002<\/p>\n<p>PostgreSQL\u306b\u63a5\u7d9a\u3059\u308b\u306b\u306f\u3001\u3053\u306e\u30d6\u30ed\u30b0\u3067\u4ee5\u524d\u306b\u78ba\u7acb\u3057\u305f\u63a5\u7d9a\u304b\u3089\u76f4\u63a5\u5f15\u304d\u51fa\u3059\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002DAG\u5185\u3067\u3053\u308c\u3092\u884c\u3046\u306b\u306f\u3001<code>Dockerfile.airflow<\/code>\u30d5\u30a1\u30a4\u30eb\u3067\u30b3\u30f3\u30c6\u30ca\u306b\u5c0e\u5165\u3057\u305fPostgresHook python\u30e9\u30a4\u30d6\u30e9\u30ea\u3092\u30a4\u30f3\u30dd\u30fc\u30c8\u3057\u307e\u3059\u3002\u305d\u3057\u3066\u3001Postgres\u306e\u63a5\u7d9aID<code>postgres = PostgresHook(postgres_conn_id=\"postgres\")<\/code>\u3092\u6307\u5b9a\u3057\u307e\u3059\u3002<\/p>\n<p>\u63a5\u7d9a\u304c\u5b8c\u4e86\u3057\u305f\u3089\u3001\u30ab\u30fc\u30bd\u30eb\u3092\u4f7f\u3063\u3066\u30af\u30a8\u30ea\u3092\u5b9f\u884c\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002\u3053\u306e\u5834\u5408\u3001 <code>device<\/code> \u30c6\u30fc\u30d6\u30eb\u304b\u3089\u3059\u3079\u3066\u306e\u30c7\u30fc\u30bf\u3092\u53d6\u5f97\u3057\u307e\u3059\u3002<\/p>\n<h4>GridDB\u306b\u63a5\u7d9a\u3059\u308b<\/h4>\n<p>GridDB \u30b5\u30fc\u30d0\u3078\u306e\u63a5\u7d9a\u306f\u3001PostgreSQL \u3068\u540c\u69d8\u306b JdbcHook \u3092\u5229\u7528\u3059\u308b\u65b9\u6cd5\u3068\u3001GridDB Python \u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u3092\u5229\u7528\u3059\u308b\u65b9\u6cd5\u304c\u3042\u308a\u307e\u3059\u3002Python\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u3092\u5229\u7528\u3059\u308b\u3053\u3068\u3067\u3001\u4ed6\u306ePython\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3068\u540c\u69d8\u306b\u5229\u7528\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u3001\u4f7f\u3044\u52dd\u624b\u304c\u826f\u3044\u306e\u3067\u3001\u3053\u306e\u65b9\u6cd5\u3092\u5229\u7528\u3059\u308b\u3053\u3068\u306b\u3057\u307e\u3059\u3002\u63a5\u7d9a\u306e\u8a73\u7d30\u306b\u3064\u3044\u3066\u306f\u3001\u3053\u308c\u3089\u306e\u30b5\u30fc\u30d3\u30b9\u306f <code>docker-compose<\/code> \u74b0\u5883\u3092\u5171\u6709\u3057\u3066\u3044\u308b\u305f\u3081\u3001\u5358\u7d14\u306b\u30db\u30b9\u30c8\u540d\u3092\u4f7f\u7528\u3057\u307e\u3059\u3002<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-python\">factory = griddb.StoreFactory.get_instance()\nDB_HOST = \"griddb-server:10001\"\nDB_CLUSTER = \"myCluster\"\nDB_USER = \"admin\"\nDB_PASS = \"admin\"\n\n  gridstore = factory.get_store(\n        notification_member=DB_HOST, cluster_name=DB_CLUSTER, username=DB_USER, password=DB_PASS\n  )<\/code><\/pre>\n<\/div>\n<p>\u6b8b\u308a\u306e\u8a73\u7d30\u306f\u3001<code>FIXED_LIST<\/code>\u30e2\u30fc\u30c9\u306eGridDB\u3067\u4f7f\u7528\u3055\u308c\u308b\u30c7\u30d5\u30a9\u30eb\u30c8\u306e\u3082\u306e\u3067\u3059\u3002\u307e\u305f\u3001Docker\u30b3\u30f3\u30c6\u30ca\u306e\u5916\u3067GridDB\u3092\u4f7f\u3063\u3066Python\u306e\u30b3\u30fc\u30c9\u3092\u66f8\u304f\u5834\u5408\u306b\u3082\u3001<code>DB_HOST<\/code>\u3092\u9069\u5207\u306aIP\u30a2\u30c9\u30ec\u30b9\u306b\u7f6e\u304d\u63db\u3048\u308b\u3060\u3051\u3067\u540c\u3058\u3088\u3046\u306b\u63a5\u7d9a\u3067\u304d\u307e\u3059\u3002\uff08\u30dd\u30fc\u30c8\u306f\u305d\u306e\u307e\u307e\u3067\u3059\u3002\uff09<\/p>\n<p>\u63a5\u7d9a\u304c\u5b8c\u4e86\u3057\u305f\u3089\u3001PostgreSQL\u304b\u3089\u884c\u3092\u5909\u63db\u3057\u3066\u3001\u305d\u306e\u884c\u3092GridDB\u306b\u914d\u7f6e\u3057\u3066\u307f\u307e\u3057\u3087\u3046\u3002<\/p>\n<h4>GridDB\u3067\u30b3\u30f3\u30c6\u30ca\u3092\u4f5c\u6210\u3059\u308b<\/h4>\n<p>\u4e0a\u8a18\u3067\u8aac\u660e\u3057\u305f\u3088\u3046\u306b\u3001PostgreSQL \u304b\u3089\u3059\u3079\u3066\u306e\u884c\u3092\u53d6\u308a\u51fa\u3057\u3001GridDB \u5074\u3067 3 \u3064\u306e\u7570\u306a\u308b\u30b3\u30f3\u30c6\u30ca\u306b\u5206\u5272\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002\u5143\u306e\u30c7\u30fc\u30bf\u30bb\u30c3\u30c8\u306b\u542b\u307e\u308c\u308b\u4e00\u610f\u306e\u30c7\u30d0\u30a4\u30b9\u540d\u304c\u3001\u65b0\u3057\u3044\u6642\u7cfb\u5217\u30b3\u30f3\u30c6\u30ca\u306e\u30ad\u30fc\u306b\u306a\u308b\u306f\u305a\u3067\u3059\u3002Python\u306e\u30b3\u30fc\u30c9\u3092\u4f7f\u3063\u3066\u3001DAG\u306e\u4e2d\u3067\u5b9f\u73fe\u3067\u304d\u307e\u3059\u3002\u307e\u305f\u3001\u4f5c\u6210\u6642\u306b\u30b9\u30ad\u30fc\u30de\u3092\u8a2d\u5b9a\u3059\u308b\u3053\u3068\u3082\u53ef\u80fd\u3067\u3059\u3002<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-python\">def create_container(gridstore, device_name):\n    gridstore.drop_container(device_name)\n    conInfo = griddb.ContainerInfo(name=device_name,\n                column_info_list=[[\"ts\", griddb.Type.TIMESTAMP],\n                                    [\"co\", griddb.Type.DOUBLE],\n                                    [\"humidity\", griddb.Type.DOUBLE],\n                                    [\"light\", griddb.Type.BOOL],\n                                    [\"lpg\", griddb.Type.DOUBLE],\n                                    [\"motion\", griddb.Type.BOOL],\n                                    [\"smoke\", griddb.Type.DOUBLE],\n                                    [\"temperature\", griddb.Type.DOUBLE]],\n                type=griddb.ContainerType.TIME_SERIES)\n    # Create the container\n    try:\n        gridstore.put_container(conInfo)\n        print(conInfo.name, \"container successfully created\")\n    except griddb.GSException as e:\n        for i in range(e.get_error_stack_size()):\n            print(\"[\", i, \"]\")\n            print(e.get_error_code(i))\n            print(e.get_location(i))\n            print(e.get_message(i))<\/code><\/pre>\n<\/div>\n<p>\u3053\u3053\u3067\u306f\u3001<code>column_info_list<\/code>\u306b\u3042\u308b\u3088\u3046\u306a\u30b9\u30ad\u30fc\u30de\u3092\u6301\u3064\u30b3\u30f3\u30c6\u30ca\u3092\u4f5c\u6210\u3059\u308b\u3053\u3068\u306b\u3057\u307e\u3059\u3002\u3053\u306e\u95a2\u6570\u306f\u3001\u30bb\u30f3\u30b5\u30fc\u3054\u3068\u306b3\u56de\u5b9f\u884c\u3059\u308b\u5fc5\u8981\u304c\u3042\u308b\u305f\u3081\u3001\u72ec\u7acb\u3057\u305f\u95a2\u6570\u306b\u5206\u5272\u3057\u3066\u3044\u307e\u3059\u3002<\/p>\n<p>\u6700\u7d42\u7684\u306b\u306f\u4ee5\u4e0b\u306e\u3088\u3046\u306a\u30b7\u30f3\u30d7\u30eb\u306a\u3082\u306e\u3092\u5b9f\u884c\u3057\u307e\u3059\u3002<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-python\">  container_name_list = [\"device1\", \"device2\", \"device3\"]\n\n  for container_name in container_name_list:\n      create_container(gridstore, container_name)<\/code><\/pre>\n<\/div>\n<h4>GridDB\u3078\u306e\u53d6\u308a\u8fbc\u307f\u306e\u305f\u3081\u306bPostgreSQL\u304b\u3089\u30c7\u30fc\u30bf\u3092\u5909\u63db\u3059\u308b<\/h4>\n<p>\u3067\u306f\u6700\u5f8c\u306b\u3001\u5143\u306e\u30c7\u30fc\u30bf\u3092<a href=\"https:\/\/griddb.net\/en\/blog\/using-pandas-dataframes-with-griddb\/\">dataframe<\/a>\u306b\u914d\u7f6e\u3057\u3001\u64cd\u4f5c\u3084\u5206\u5272\u304c\u3057\u3084\u3059\u3044\u3088\u3046\u306b\u3057\u307e\u3059\u3002\u305d\u3053\u304b\u3089\u3001\u884c\u3092\u542b\u3080\u65b0\u3057\u3044\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3092GridDB\u306b\u5165\u308c\u307e\u3059\u3002<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-python\">    cursor.execute(\"SELECT * FROM device;\")\n    import pandas as pd\n    rows = pd.DataFrame(cursor.fetchall())\n\n    dfs = dict(tuple(rows.groupby([1])))\n\n    device1 = dfs['b8:27:eb:bf:9d:51']\n    device1 = device1.drop([1], axis=1)\n    device1 = device1.values.tolist()\n\n    device2 = dfs['00:0f:00:70:91:0a']\n    device2 = device2.drop([1], axis=1)\n    device2 = device2.values.tolist()\n\n    device3 = dfs['1c:bf:ce:15:ec:4d']\n    device3 = device3.drop([1], axis=1)\n    device3 = device3.values.tolist()<\/code><\/pre>\n<\/div>\n<p>\u5404 deviceX \u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u306f <code>multi_put<\/code> \u3067 GridDB \u306b\u76f4\u63a5\u914d\u7f6e\u3067\u304d\u308b\u3059\u3079\u3066\u306e\u884c\u3092\u542b\u307f\u307e\u3059\u3002<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-python\">    try: \n        d1_cont = gridstore.get_container(\"device1\")\n        d1_cont.multi_put(device1)\n\n        d2_cont = gridstore.get_container(\"device2\")\n        d2_cont.multi_put(device1)\n\n        d3_cont = gridstore.get_container(\"device3\")\n        d3_cont.multi_put(device1)\n\n    except griddb.GSException as e:\n        for i in range(e.get_error_stack_size()):\n            print(\"[\", i, \"]\")\n            print(e.get_error_code(i))\n            print(e.get_location(i))\n            print(e.get_message(i))<\/code><\/pre>\n<\/div>\n<p>\u305d\u3053\u304b\u3089GridDB\u306e\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u306f\u3001Kaggle\u306e\u30c7\u30fc\u30bf\u30bb\u30c3\u30c8\u304b\u3089\u95a2\u9023\u3059\u308b\u3059\u3079\u3066\u306e\u30bb\u30f3\u30b5\u30fc\u60c5\u5831\u304c\u5165\u3063\u305f3\u3064\u306e\u65b0\u3057\u3044\u30b3\u30f3\u30c6\u30ca\u304c\u8ffd\u52a0\u3055\u308c\u308b\u306f\u305a\u3067\u3059\u3002<\/p>\n<h3>\u7d99\u7d9a\u7684\u306a\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3<\/h3>\n<p>\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u304c\u63c3\u3063\u305f\u3068\u3053\u308d\u3067\u3001\u6b21\u306e\u30b9\u30c6\u30c3\u30d7\u306b\u9032\u307f\u307e\u3057\u3087\u3046\u3002\u4f8b\u3048\u3070\u3001\u30bb\u30f3\u30b5\u30fc\u306e\u30c7\u30fc\u30bf\u304cPostgreSQL\u306b\u9001\u4fe1\u3055\u308c\u7d9a\u3051\u3066\u3044\u3066\u3001\u305d\u308c\u3092GridDB\u306b\u9001\u4fe1\u3057\u305f\u3044\u3068\u3057\u307e\u3059\u3002\u5b9a\u671f\u7684\u306b\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u3055\u308c\u305fDAG\u3092\u4f7f\u3048\u3070\u3001\u3059\u3079\u3066\u306e\u65b0\u3057\u3044\u884c\u304cGridDB\u306b\u30d7\u30c3\u30b7\u30e5\u3055\u308c\u308b\u3088\u3046\u306b\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002<\/p>\n<p>\u5404\u30bb\u30f3\u30b5\u30fc\u306e\u30b3\u30f3\u30c6\u30ca\u306b\u554f\u3044\u5408\u308f\u305b\u3001\u30c7\u30fc\u30bf\u306e\u6700\u65b0\uff08<code>MAX<\/code>\uff09\u306e\u30bf\u30a4\u30e0\u30b9\u30bf\u30f3\u30d7\u3092\u898b\u3064\u3051\u3001\u305d\u308c\u3092PostgreSQL\u3067\u30af\u30ed\u30b9\u30ea\u30d5\u30a1\u30ec\u30f3\u30b9\u3057\u307e\u3059\u3002PostgreSQL\u3067\u30c7\u30fc\u30bf\u304c\u65b0\u3057\u3044\u304b\u300c\u5927\u304d\u3044\u300d\u5834\u5408\u3001\u554f\u984c\u306e\u3042\u308b\u884c\u3092\u3059\u3079\u3066\u53d6\u308a\u51fa\u3057\u3001\u9069\u5207\u306a\u30b3\u30f3\u30c6\u30ca\u306b\u30d7\u30c3\u30b7\u30e5\u3057\u307e\u3059\u3002<\/p>\n<h4>GridDB\u3067MAX\u30bf\u30a4\u30e0\u30b9\u30bf\u30f3\u30d7\u3092\u30af\u30a8\u30ea\u3059\u308b<\/h4>\n<p>GridDB\u3078\u306e\u63a5\u7d9a\u304c\u5b8c\u4e86\u3057\u305f\u3089\u3001\u30af\u30a8\u30ea\u3092\u4f5c\u6210\u3057\u307e\u3059\u3002\u3053\u306e\u5834\u5408\u3001TQL\u306f\u30b3\u30f3\u30c6\u30ca\u5358\u4f4d\u3067\u52d5\u4f5c\u3059\u308b\u305f\u3081\u3001\u30af\u30a8\u30ea\u81ea\u4f53\u306b\u30b3\u30f3\u30c6\u30ca\u540d\u3092\u6307\u5b9a\u3059\u308b\u5fc5\u8981\u306f\u3042\u308a\u307e\u305b\u3093\u3002\u3064\u307e\u308a\u30011\u3064\u306e\u6587\u5b57\u5217\u3092\u4f5c\u6210\u3059\u308b\u3060\u3051\u3067\u3001\u3059\u3079\u3066\u306e\u30b3\u30f3\u30c6\u30ca\u3067\u518d\u5229\u7528\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-python\">    try:\n        d1_cont = gridstore.get_container(\"device1\")\n        d2_cont = gridstore.get_container(\"device2\")\n        d3_cont = gridstore.get_container(\"device3\")\n\n        sql = \"SELECT MAX(ts)\"\n\n        d1_query = d1_cont.query(sql)\n        d2_query = d2_cont.query(sql)\n        d3_query = d3_cont.query(sql)<\/code><\/pre>\n<\/div>\n<p>\u3053\u3053\u3067\u306f\u3001\u30b3\u30f3\u30c6\u30ca\u5185\u306e\u7d76\u5bfe\u7684\u306a\u6700\u65b0\u306e\u30bf\u30a4\u30e0\u30b9\u30bf\u30f3\u30d7\uff08ts\uff09\u3092\u898b\u3064\u3051\u308bMAX\u306eTQL\u96c6\u8a08\u30af\u30a8\u30ea\u3092\u4f7f\u7528\u3057\u3066\u3044\u307e\u3059\u3002<\/p>\n<h4>GridDB \u306e\u30bf\u30a4\u30e0\u30b9\u30bf\u30f3\u30d7\u5024\u3092\u4f7f\u3063\u3066 PostgreSQL \u3078\u30af\u30a8\u30ea\u3092\u5b9f\u884c\u3059\u308b<\/h4>\n<p>\u305d\u306e\u5024\u304c\u4fdd\u5b58\u3055\u308c\u305f\u3089\u3001\u305d\u308c\u3092\u4f7f\u3063\u3066PostgreSQL\u306b\u30af\u30a8\u30ea\u3092\u5b9f\u884c\u3057\u307e\u3059\u3002<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-python\">        d1_rs = d1_query.fetch()\n        d2_rs = d2_query.fetch()\n        d3_rs = d3_query.fetch()\n\n        d1_row = d1_rs.next().get(griddb.Type.TIMESTAMP)\n        d1_latest_time = d1_row.replace(microsecond=999999) # adding in max microseconds as GridDB does not save these values\n\n        d2_row = d2_rs.next().get(griddb.Type.TIMESTAMP)\n        d2_latest_time = d2_row.replace(microsecond=999999)\n\n        d3_row = d3_rs.next().get(griddb.Type.TIMESTAMP)\n        d3_latest_time = d3_row.replace(microsecond=999999)\n      \n      \n        d1_sql = \"SELECT DISTINCT ON (ts) * FROM device WHERE ts > '\" + str(d1_latest_time)+ \"' AND device = 'b8:27:eb:bf:9d:51' ORDER BY ts DESC;\"\n        d2_sql = \"SELECT DISTINCT ON (ts) * FROM device WHERE ts > '\" + str(d2_latest_time)+ \"' AND device = '00:0f:00:70:91:0a' ORDER BY ts DESC;\"\n        d3_sql = \"SELECT DISTINCT ON (ts) * FROM device WHERE ts > '\" + str(d3_latest_time)+ \"' AND device = '1c:bf:ce:15:ec:4d' ORDER BY ts DESC;\"\n        \n        cursor.execute(d1_sql)\n        d1_result = cursor.fetchall()\n\n        cursor.execute(d2_sql)\n        d2_result = cursor.fetchall()\n\n        cursor.execute(d3_sql)\n        d3_result = cursor.fetchall()<\/code><\/pre>\n<\/div>\n<p>\u3053\u308c\u3067\u3001GridDB\u306e\u5bfe\u5fdc\u3059\u308b\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3088\u308a\u3082\u5f8c\u306b\u884c\u3092\u683c\u7d0d\u3059\u308b3\u3064\u306e\u7570\u306a\u308b\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u304c\u3067\u304d\u307e\u3057\u305f\u3002\u6b21\u306b\u3001\u30ea\u30b9\u30c8\u304c\u7a7a\u304b\u3069\u3046\u304b\u3092\u30c1\u30a7\u30c3\u30af\u3057\u3001\u7a7a\u3067\u306a\u3051\u308c\u3070GridDB\u306b\u884c\u3092\u914d\u7f6e\u3057\u307e\u3059\u3002<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-python\">    if not d1_result:\n        print(\"Device1 contains 0 new rows to add\")\n    else:\n        print(d1_latest_time)\n        print(d1_sql)\n        print(\"Device1 contains \" + str(len(d1_result)) + \" new rows to add\")\n        for row in d1_result:\n            print(\"putting row to device1 in GridDB\")\n            row = list(row)\n            del row[1] #get rid of device name\n            print(row)\n            d1_cont.put(row)\n\n    if not d2_result:\n        print(\"Device2 contains 0 new rows to add\")\n    else:\n        print(d2_latest_time)\n        print(d2_sql)\n        print(\"Device2 contains \" + str(len(d2_result)) + \" new rows to add\")\n        for row in d2_result:\n            print(\"putting row to device2 in GridDB\")\n            row = list(row)\n            del row[1] #get rid of device name\n            print(row)\n            d2_cont.put(list(row))\n\n    if not d3_result:\n        print(\"Device3 contains 0 new rows to add\")\n    else:\n        print(\"Device3 contains \" + str(len(d3_result)) + \" new rows to add\")\n        print(d3_latest_time)\n        print(d3_sql)\n        for row in d3_result:\n            print(\"putting row to device3 in GridDB\")\n            row = list(row)\n            del row[1]\n            print(row)\n            d3_cont.put(list(row))<\/code><\/pre>\n<\/div>\n<p>DAG\u306e\u6e96\u5099\u304c\u3067\u304d\u305f\u306e\u3067\u3001UI\u306b\u5411\u304b\u3044\u3053\u308c\u3089\u3092\u30aa\u30f3\u306b\u3057\u3066\u3001\u5b9f\u884c\u3055\u308c\u671f\u5f85\u901a\u308a\u306b\u52d5\u304f\u304b\u3069\u3046\u304b\u3092\u78ba\u8a8d\u3057\u307e\u3059\u3002<\/p>\n<h3>DAG\u3092\u8d77\u52d5\u3057\u7d50\u679c\u3092\u78ba\u8a8d\u3059\u308b<\/h3>\n<p>Let&#8217;s head back over to the UI and activate these DAGs. Our DAG which simply does an initial bulk migration is scheduled to run only once. Let&#8217;s turn that one on and make sure it runs. Use the search bar <code>search DAGs<\/code> and search GridDB.<\/p>\n<p><a href=\"https:\/\/griddb.net\/wp-content\/uploads\/2023\/01\/airflow-4.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/griddb.net\/wp-content\/uploads\/2023\/01\/airflow-4.png\" alt=\"\" width=\"1662\" height=\"440\" class=\"aligncenter size-full wp-image-29055\" srcset=\"\/wp-content\/uploads\/2023\/01\/airflow-4.png 1662w, \/wp-content\/uploads\/2023\/01\/airflow-4-300x79.png 300w, \/wp-content\/uploads\/2023\/01\/airflow-4-1024x271.png 1024w, \/wp-content\/uploads\/2023\/01\/airflow-4-768x203.png 768w, \/wp-content\/uploads\/2023\/01\/airflow-4-1536x407.png 1536w, \/wp-content\/uploads\/2023\/01\/airflow-4-600x159.png 600w\" sizes=\"(max-width: 1662px) 100vw, 1662px\" \/><\/a><\/p>\n<p>\u307e\u305a\u3001<code>griddb_postgres_migration_initial<\/code>\u3068\u3044\u3046ID\u306eDAG\u3092\u30aa\u30f3\u306b\u3057\u3066\u307f\u307e\u3057\u3087\u3046\u3002\u30af\u30ea\u30c3\u30af\u3059\u308b\u3068\u3001\u540d\u524d\u306e\u6a2a\u306b\u5c0f\u3055\u306a\u30b9\u30a4\u30c3\u30c1\u304c\u3042\u308a\u3001\u305d\u3053\u3067\u30aa\u30f3\u30fb\u30aa\u30d5\u3092\u5207\u308a\u66ff\u3048\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002<\/p>\n<p><a href=\"https:\/\/griddb.net\/wp-content\/uploads\/2023\/01\/airflow-5.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/griddb.net\/wp-content\/uploads\/2023\/01\/airflow-5.png\" alt=\"\" width=\"945\" height=\"278\" class=\"aligncenter size-full wp-image-29056\" srcset=\"\/wp-content\/uploads\/2023\/01\/airflow-5.png 945w, \/wp-content\/uploads\/2023\/01\/airflow-5-300x88.png 300w, \/wp-content\/uploads\/2023\/01\/airflow-5-768x226.png 768w, \/wp-content\/uploads\/2023\/01\/airflow-5-600x177.png 600w\" sizes=\"(max-width: 945px) 100vw, 945px\" \/><\/a><\/p>\n<p>\u958b\u59cb\u65e5\u3092\u904e\u53bb\u306b\u8a2d\u5b9a\u3057\u3001\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u9593\u9694\u30921\u56de\u306b\u8a2d\u5b9a\u3057\u305f\u305f\u3081\u3001\u4e00\u5ea6\u30aa\u30f3\u306b\u3059\u308b\u3068\u3001\u3059\u3050\u306b\u5b9f\u884c\u3055\u308c\u3001\u305d\u306e\u5f8c\u3001\u505c\u6b62\u3057\u307e\u3059\u3002\u30ed\u30b0\u3092\u78ba\u8a8d\u3059\u308b\u306b\u306f\u3001\u30b0\u30e9\u30d5\u30dc\u30bf\u30f3\u3092\u30af\u30ea\u30c3\u30af\u3057\u3001DAG\u30de\u30c3\u30d7\u306e\u4e2d\u304b\u3089\u81ea\u5206\u306e\u30bf\u30b9\u30af\u3092\u63a2\u3057\u307e\u3059\u3002\u30bf\u30b9\u30af\u306f1\u3064\u3060\u3051\u306a\u306e\u3067\u3001\u7a7a\u9593\u4e0a\u306b\u3042\u308b\u5c0f\u3055\u306a\u56db\u89d2\u304c1\u3064\u3042\u308b\u3060\u3051\u3067\u3059\u3002<\/p>\n<p><a href=\"https:\/\/griddb.net\/wp-content\/uploads\/2023\/01\/airflow-7.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/griddb.net\/wp-content\/uploads\/2023\/01\/airflow-7.png\" alt=\"\" width=\"1303\" height=\"412\" class=\"aligncenter size-full wp-image-29058\" srcset=\"\/wp-content\/uploads\/2023\/01\/airflow-7.png 1303w, \/wp-content\/uploads\/2023\/01\/airflow-7-300x95.png 300w, \/wp-content\/uploads\/2023\/01\/airflow-7-1024x324.png 1024w, \/wp-content\/uploads\/2023\/01\/airflow-7-768x243.png 768w, \/wp-content\/uploads\/2023\/01\/airflow-7-600x190.png 600w\" sizes=\"(max-width: 1303px) 100vw, 1303px\" \/><\/a><\/p>\n<p>\u305d\u3053\u304b\u3089\u3001\u4e0a\u90e8\u306e\u30ed\u30b0\u30dc\u30bf\u30f3\u3092\u30af\u30ea\u30c3\u30af\u3057\u307e\u3059\u3002\u3082\u3057DAG\u306e\u7d50\u679c\u304c\u671f\u5f85\u901a\u308a\u3067\u306a\u3044\u5834\u5408\u306f\u3001\u30b9\u30b1\u30b8\u30e5\u30fc\u30ea\u30f3\u30b0\u306b\u6642\u9593\u3092\u639b\u3051\u305f\u308a\u518d\u5b9f\u884c\u3092\u5f85\u3064\u4ee3\u308f\u308a\u306b\u3001\u30af\u30ea\u30a2\u30dc\u30bf\u30f3\u3092\u30af\u30ea\u30c3\u30af\u3059\u308b\u3068\u3001DAG\u304c\u81ea\u52d5\u3067\u518d\u5b9f\u884c\u3055\u308c\u307e\u3059\u3002<\/p>\n<p><a href=\"https:\/\/griddb.net\/wp-content\/uploads\/2023\/01\/airflow-8.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/griddb.net\/wp-content\/uploads\/2023\/01\/airflow-8.png\" alt=\"\" width=\"707\" height=\"652\" class=\"aligncenter size-full wp-image-29059\" srcset=\"\/wp-content\/uploads\/2023\/01\/airflow-8.png 707w, \/wp-content\/uploads\/2023\/01\/airflow-8-300x277.png 300w, \/wp-content\/uploads\/2023\/01\/airflow-8-600x553.png 600w\" sizes=\"(max-width: 707px) 100vw, 707px\" \/><\/a><\/p>\n<p>\u305d\u3057\u3066\u3001\u4eca\u5ea6\u306f\u30ed\u30b0\u3092\u898b\u3066\u3001\u30bf\u30b9\u30af\u304c\u6b63\u5e38\u306b\u5b8c\u4e86\u3057\u305f\u304b\u3069\u3046\u304b\u3092\u78ba\u8a8d\u3057\u307e\u3059\u3002<\/p>\n<p><a href=\"https:\/\/griddb.net\/wp-content\/uploads\/2023\/01\/airflow-6.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/griddb.net\/wp-content\/uploads\/2023\/01\/airflow-6.png\" alt=\"\" width=\"1861\" height=\"813\" class=\"aligncenter size-full wp-image-29057\" srcset=\"\/wp-content\/uploads\/2023\/01\/airflow-6.png 1861w, \/wp-content\/uploads\/2023\/01\/airflow-6-300x131.png 300w, \/wp-content\/uploads\/2023\/01\/airflow-6-1024x447.png 1024w, \/wp-content\/uploads\/2023\/01\/airflow-6-768x336.png 768w, \/wp-content\/uploads\/2023\/01\/airflow-6-1536x671.png 1536w, \/wp-content\/uploads\/2023\/01\/airflow-6-600x262.png 600w\" sizes=\"(max-width: 1861px) 100vw, 1861px\" \/><\/a><\/p>\n<h4>GridDB\u306b\u30af\u30a8\u30ea\u3092\u5b9f\u884c\u3059\u308b<\/h4>\n<p>\u3053\u308c\u3067\u30013\u3064\u306e\u30b3\u30f3\u30c6\u30ca\u304c\u6b63\u5e38\u306b\u4f5c\u6210\u3055\u308c\u307e\u3057\u305f\u3002\u4ed6\u306b\u3001GridDB\u30b3\u30f3\u30c6\u30ca\u306bSSH\u3067\u63a5\u7d9a\u3057\u3001CLI\u30b7\u30a7\u30eb\u3067\u30af\u30a8\u30ea\u3092\u5b9f\u884c\u3059\u308b\u3053\u3068\u3082\u3067\u304d\u307e\u3059\u3002<\/p>\n<p>\u4ee5\u4e0b\u306e\u3088\u3046\u306b\u30b7\u30a7\u30eb\u306b\u843d\u3068\u3057\u8fbc\u307f\u307e\u3059\u3002<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\">$ docker exec -it griddb-airflow gs_sh<\/code><\/pre>\n<\/div>\n<pre><code>The connection attempt was successful(NoSQL).\nThe connection attempt was successful(NewSQL).\ngs&gt;\n<\/code><\/pre>\n<p>\u305d\u3053\u304b\u3089\u30b3\u30f3\u30c6\u30ca\u60c5\u5831\u3092\u78ba\u8a8d\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\">gs[public]> showcontainer device2\nDatabase    : public\nName        : device2\nType        : TIME_SERIES\nPartition ID: 38\nDataAffinity: -\n\nCompression Method : NO\nCompression Window : -\nRow Expiration Time: -\nRow Expiration Division Count: -\n\nColumns:\nNo  Name                  Type            CSTR  RowKey   Compression\n------------------------------------------------------------------------------\n 0  ts                    TIMESTAMP       NN    [RowKey]\n 1  co                    DOUBLE\n 2  humidity              DOUBLE\n 3  light                 BOOL\n 4  lpg                   DOUBLE\n 5  motion                BOOL\n 6  smoke                 DOUBLE\n 7  temperature           DOUBLE<\/code><\/pre>\n<\/div>\n<p>\u305d\u3057\u3066\u30af\u30a8\u30ea\u30fc\u3092\u5b9f\u884c\u3057\u307e\u3059\u3002<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\">gs[public]> select * from device2;\n111,817 results. (13 ms)\ngs[public]> get 3\nts,co,humidity,light,lpg,motion,smoke,temperature\n2020-07-12T00:01:34.735Z,0.00284008860710157,76.0,false,0.005114383400977071,false,0.013274836704851536,19.700000762939453\n2020-07-12T00:01:46.869Z,0.002938115626660429,76.0,false,0.005241481841731117,false,0.013627521132019194,19.700000762939453\n2020-07-12T00:02:02.785Z,0.0029050147565559607,75.80000305175781,false,0.0051986974792943095,false,0.013508733329556249,19.700000762939453\nThe 3 results had been acquired.<\/code><\/pre>\n<\/div>\n<h4>\u7d99\u7d9a\u7684\u306a\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3<\/h4>\n<p>\u6b21\u306b\u30011\u6642\u9593\u3054\u3068\u306e\u30b9\u30b1\u30b8\u30e5\u30fc\u30eb\u3067\u8a2d\u5b9a\u3057\u305f\u6b21\u306eDAG\u3092\u958b\u59cb\u3057\u307e\u3059\u3002<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-python\">with DAG(\n    dag_id='griddb_postgres_migration_continuous',\n    default_args=default_args,\n    start_date=datetime(2022, 12, 19),\n    schedule_interval='0 * * * *'<\/code><\/pre>\n<\/div>\n<p>schedule_interval\u306e\u30b9\u30bf\u30a4\u30eb\u306f<code>cron<\/code>\u3067\u3059\u304c\u3001\u3042\u307e\u308a\u6163\u308c\u3066\u3044\u306a\u3044\u5834\u5408\u306f\u3001<a href=\"https:\/\/airflow.apache.org\/docs\/apache-airflow\/1.10.1\/scheduler.html#dag-runs\">\u30b7\u30e7\u30fc\u30c8\u30ab\u30c3\u30c8<\/a>\u3082\u7528\u610f\u3055\u308c\u3066\u3044\u307e\u3059\u3002\u4f8b\u3048\u3070\u3001&#8217;@hourly&#8217;\u3068\u5165\u529b\u3059\u308b\u3053\u3068\u3082\u53ef\u80fd\u3067\u3001\u3053\u308c\u3082\u540c\u69d8\u306b\u6709\u52b9\u3067\u3059\u3002<\/p>\n<p>\u3044\u305a\u308c\u306e\u65b9\u6cd5\u3067\u3082\u826f\u3044\u306e\u3067\u624b\u52d5\u3067PostgreSQL\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306b\u3044\u304f\u3064\u304b\u306e\u884c\u3092\u8ffd\u52a0\u3057\u3066\u3001\u7d99\u7d9a\u7684\u306a\u30de\u30a4\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u304c\u5b9f\u969b\u306b\u884c\u308f\u308c\u3066\u3044\u308b\u306e\u3092\u78ba\u8a8d\u3057\u3066\u307f\u307e\u3057\u3087\u3046\u3002\u3072\u3068\u307e\u305a\u4eca\u306f\u3053\u306e\u307e\u307e\u3067\u3001\u3044\u304f\u3064\u304b\u306e\u884c\u3092\u8ffd\u52a0\u3057\u307e\u3059\u3002<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\">$ docker exec -it postgres-airflow bash\n\/# psql -U airflow\npsql (13.9 (Debian 13.9-1.pgdg110+1))\nType \"help\" for help.<\/code><\/pre>\n<\/div>\n<p>\u305d\u3057\u3066\u4eca\u5ea6\u306f\u3001\u3044\u304f\u3064\u304b\u306e\u884c\u3092\u8ffd\u52a0\u3057\u3066\u307f\u307e\u3057\u3087\u3046\u3002<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\">postgres=# INSERT INTO device VALUES (now(), 'b8:27:eb:bf:9d:51', 0.003551, 50.0, false, 0.00754352, false, 0.0232432, 21.6);<\/code><\/pre>\n<\/div>\n<pre><code>INSERT 0 1\n<\/code><\/pre>\n<p>\u30c6\u30b9\u30c8\u3068\u3057\u3066\u4f55\u5ea6\u3067\u3082\u3067\u304d\u307e\u3059\u3002\u307e\u305f\u3001\u30bb\u30f3\u30b5\u30fc\u540d\u3092\u5909\u3048\u3066\u633f\u5165\u3059\u308b\u3053\u3068\u3067\u3001\u7570\u306a\u308b\u30b3\u30f3\u30c6\u30ca\u3078\u306e\u633f\u5165\u3092\u8a66\u307f\u308b\u3053\u3068\u3082\u53ef\u80fd\u3067\u3059\u3002<\/p>\n<p>\u6b21\u306b\u3001DAG\u306e\u96fb\u6e90\u3092\u5165\u308c\u3001\u30ed\u30b0\u3092\u78ba\u8a8d\u3057\u3066\u307f\u307e\u3057\u3087\u3046\u3002<\/p>\n<p><a href=\"https:\/\/griddb.net\/wp-content\/uploads\/2023\/01\/airflow-9.png\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/griddb.net\/wp-content\/uploads\/2023\/01\/airflow-9.png\" alt=\"\" width=\"2046\" height=\"702\" class=\"aligncenter size-full wp-image-29060\" srcset=\"\/wp-content\/uploads\/2023\/01\/airflow-9.png 2046w, \/wp-content\/uploads\/2023\/01\/airflow-9-300x103.png 300w, \/wp-content\/uploads\/2023\/01\/airflow-9-1024x351.png 1024w, \/wp-content\/uploads\/2023\/01\/airflow-9-768x264.png 768w, \/wp-content\/uploads\/2023\/01\/airflow-9-1536x527.png 1536w, \/wp-content\/uploads\/2023\/01\/airflow-9-600x206.png 600w\" sizes=\"(max-width: 2046px) 100vw, 2046px\" \/><\/a><\/p>\n<p>\u7b46\u8005\u306e\u30b7\u30a7\u30eb\u3067\u306f\u3001\u7570\u306a\u308b\u30b3\u30f3\u30c6\u30ca\u306e\u9593\u306b\u5408\u8a085\u3064\u306e\u65b0\u3057\u3044\u884c\u3092\u8ffd\u52a0\u3057\u307e\u3057\u305f\u3002\u305d\u306e\u7d50\u679c\u306f\u4ee5\u4e0b\u306e\u901a\u308a\u3067\u3059\u3002<\/p>\n<pre><code>[2023-01-12, 16:14:21 PST] {logging_mixin.py:137} INFO - SELECT DISTINCT ON (ts) * FROM device WHERE ts &gt; '2023-01-13 00:04:42.999999' AND device = 'b8:27:eb:bf:9d:51' ORDER BY ts DESC;\n[2023-01-12, 16:14:21 PST] {logging_mixin.py:137} INFO - Device1 contains 4 new rows to add\n[2023-01-12, 16:14:21 PST] {logging_mixin.py:137} INFO - putting row to device1 in GridDB\n[2023-01-12, 16:14:21 PST] {logging_mixin.py:137} INFO - [datetime.datetime(2023, 1, 13, 0, 13, 17, 145397), 0.003551, 50.0, False, 0.00754352, False, 0.0232432, 21.6]\n[2023-01-12, 16:14:21 PST] {logging_mixin.py:137} INFO - putting row to device1 in GridDB\n[2023-01-12, 16:14:21 PST] {logging_mixin.py:137} INFO - [datetime.datetime(2023, 1, 13, 0, 13, 16, 116032), 0.003551, 50.0, False, 0.00754352, False, 0.0232432, 21.6]\n[2023-01-12, 16:14:21 PST] {logging_mixin.py:137} INFO - putting row to device1 in GridDB\n[2023-01-12, 16:14:21 PST] {logging_mixin.py:137} INFO - [datetime.datetime(2023, 1, 13, 0, 13, 15, 321145), 0.003551, 50.0, False, 0.00754352, False, 0.0232432, 21.6]\n[2023-01-12, 16:14:21 PST] {logging_mixin.py:137} INFO - putting row to device1 in GridDB\n[2023-01-12, 16:14:21 PST] {logging_mixin.py:137} INFO - [datetime.datetime(2023, 1, 13, 0, 13, 13, 344482), 0.003551, 50.0, False, 0.00754352, False, 0.0232432, 21.6]\n[2023-01-12, 16:14:21 PST] {logging_mixin.py:137} INFO - 2023-01-12 23:55:08.999999\n[2023-01-12, 16:14:21 PST] {logging_mixin.py:137} INFO - SELECT DISTINCT ON (ts) * FROM device WHERE ts &gt; '2023-01-12 23:55:08.999999' AND device = '00:0f:00:70:91:0a' ORDER BY ts DESC;\n[2023-01-12, 16:14:21 PST] {logging_mixin.py:137} INFO - Device2 contains 1 new rows to add\n[2023-01-12, 16:14:21 PST] {logging_mixin.py:137} INFO - putting row to device2 in GridDB\n[2023-01-12, 16:14:21 PST] {logging_mixin.py:137} INFO - [datetime.datetime(2023, 1, 13, 0, 13, 26, 633364), 0.003551, 50.0, False, 0.00754352, False, 0.0232432, 21.6]\n[2023-01-12, 16:14:21 PST] {logging_mixin.py:137} INFO - Device3 contains 0 new rows to add\n[2023-01-12, 16:14:21 PST] {python.py:177} INFO - Done. Returned value was: None\n[2023-01-12, 16:14:21 PST] {taskinstance.py:1322} INFO - Marking task as SUCCESS. dag_id=griddb_postgres_migration_continuous, task_id=griddb_postgres_migration_continuous, execution_date=20230112T230000, start_date=20230113T001421, end_date=20230113T001421\n<\/code><\/pre>\n<p>GridDB\u30b7\u30a7\u30eb\u306b\u623b\u308a\u3001\u884c\u304c\u633f\u5165\u3055\u308c\u3066\u3044\u308b\u3053\u3068\u3092\u78ba\u8a8d\u3057\u307e\u3059\u3002<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-sh\">gs[public]> tql device1 select MAX(ts);\n1 results. (15 ms)\ngs[public]> get\nResult\n2023-01-13T00:13:17.145Z\nThe 1 results had been acquired.<\/code><\/pre>\n<\/div>\n<p>\u5408\u3063\u3066\u3044\u308b\u3053\u3068\u304c\u78ba\u8a8d\u3067\u304d\u307e\u3057\u305f\u3002<\/p>\n<h2>\u307e\u3068\u3081<\/h2>\n<p>\u3053\u308c\u3067\u3001Docker\u3092\u4f7f\u3063\u3066Apache Airflow\u3092\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7\u3057\u3001PostgreSQL\u304b\u3089GridDB\u3078\u7d99\u7d9a\u7684\u306b\u30c7\u30fc\u30bf\u3092\u79fb\u884c\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u308b\u3088\u3046\u306b\u306a\u308a\u307e\u3057\u305f\u3002\u305c\u3072\u4f7f\u3063\u3066\u307f\u3066\u304f\u3060\u3055\u3044\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u4ee5\u524d\u306e\u30d6\u30ed\u30b0\u3067\u3001\u30b5\u30f3\u30d7\u30ebIoT\u30c7\u30fc\u30bf\u30bb\u30c3\u30c8\u3092PostgreSQL\u304b\u3089GridDB\u306b\u79fb\u884c\u3059\u308b\u65b9\u6cd5\u306b\u3064\u3044\u3066\u8aac\u660e\u3057\u307e\u3057\u305f\u3002\u305d\u306e\u969b\u3001GridDB\u306e\u516c\u5f0f\u30a4\u30f3\u30dd\u30fc\u30c8\u30fb\u30a8\u30af\u30b9\u30dd\u30fc\u30c8\u30c4\u30fc\u30eb\u3092\u4f7f\u7528\u3057\u3001\u30c4\u30fc\u30eb\u306e\u4f7f\u7528\u65b9\u6cd5\u3068\u3001PostgreSQ [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":50344,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1005],"tags":[],"class_list":["post-50845","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-1005"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.1.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Apache Airflow\u3092\u4f7f\u3063\u3066PostgreSQL\u304b\u3089GridDB\u3078\u306e\u30c7\u30fc\u30bf\u79fb\u884c\u3092\u8a08\u753b\u3059\u308b | GridDB: Open Source Time Series Database for IoT<\/title>\n<meta name=\"description\" content=\"\u4ee5\u524d\u306e\u30d6\u30ed\u30b0\u3067\u3001\u30b5\u30f3\u30d7\u30ebIoT\u30c7\u30fc\u30bf\u30bb\u30c3\u30c8\u3092PostgreSQL\u304b\u3089GridDB\u306b\u79fb\u884c\u3059\u308b\u65b9\u6cd5\u306b\u3064\u3044\u3066\u8aac\u660e\u3057\u307e\u3057\u305f\u3002\u305d\u306e\u969b\u3001GridDB\u306e\u516c\u5f0f\u30a4\u30f3\u30dd\u30fc\u30c8\u30fb\u30a8\u30af\u30b9\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/griddb.net\/ja\/\u672a\u5206\u985e\/scheduling-data-migration-from-postgresql-to-griddb-using-apache-airflow\/\" \/>\n<meta property=\"og:locale\" content=\"ja_JP\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Apache Airflow\u3092\u4f7f\u3063\u3066PostgreSQL\u304b\u3089GridDB\u3078\u306e\u30c7\u30fc\u30bf\u79fb\u884c\u3092\u8a08\u753b\u3059\u308b | GridDB: Open Source Time Series Database for IoT\" \/>\n<meta property=\"og:description\" content=\"\u4ee5\u524d\u306e\u30d6\u30ed\u30b0\u3067\u3001\u30b5\u30f3\u30d7\u30ebIoT\u30c7\u30fc\u30bf\u30bb\u30c3\u30c8\u3092PostgreSQL\u304b\u3089GridDB\u306b\u79fb\u884c\u3059\u308b\u65b9\u6cd5\u306b\u3064\u3044\u3066\u8aac\u660e\u3057\u307e\u3057\u305f\u3002\u305d\u306e\u969b\u3001GridDB\u306e\u516c\u5f0f\u30a4\u30f3\u30dd\u30fc\u30c8\u30fb\u30a8\u30af\u30b9\" \/>\n<meta property=\"og:url\" content=\"https:\/\/griddb.net\/ja\/\u672a\u5206\u985e\/scheduling-data-migration-from-postgresql-to-griddb-using-apache-airflow\/\" \/>\n<meta property=\"og:site_name\" content=\"GridDB: Open Source Time Series Database for IoT\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/griddbcommunity\/\" \/>\n<meta property=\"article:published_time\" content=\"2023-02-02T08:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-11-14T15:56:00+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/griddb.net\/wp-content\/uploads\/2023\/03\/airflowandgriddb1.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1160\" \/>\n\t<meta property=\"og:image:height\" content=\"653\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Israel\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@GridDBCommunity\" \/>\n<meta name=\"twitter:site\" content=\"@GridDBCommunity\" \/>\n<meta name=\"twitter:label1\" content=\"\u57f7\u7b46\u8005\" \/>\n\t<meta name=\"twitter:data1\" content=\"Israel\" \/>\n\t<meta name=\"twitter:label2\" content=\"\u63a8\u5b9a\u8aad\u307f\u53d6\u308a\u6642\u9593\" \/>\n\t<meta name=\"twitter:data2\" content=\"12\u5206\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/griddb.net\/ja\/%e6%9c%aa%e5%88%86%e9%a1%9e\/scheduling-data-migration-from-postgresql-to-griddb-using-apache-airflow\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/griddb.net\/ja\/%e6%9c%aa%e5%88%86%e9%a1%9e\/scheduling-data-migration-from-postgresql-to-griddb-using-apache-airflow\/\"},\"author\":{\"name\":\"Israel\",\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/person\/c8a430e7156a9e10af73b1fbb46c2740\"},\"headline\":\"Apache Airflow\u3092\u4f7f\u3063\u3066PostgreSQL\u304b\u3089GridDB\u3078\u306e\u30c7\u30fc\u30bf\u79fb\u884c\u3092\u8a08\u753b\u3059\u308b\",\"datePublished\":\"2023-02-02T08:00:00+00:00\",\"dateModified\":\"2025-11-14T15:56:00+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/griddb.net\/ja\/%e6%9c%aa%e5%88%86%e9%a1%9e\/scheduling-data-migration-from-postgresql-to-griddb-using-apache-airflow\/\"},\"wordCount\":292,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#organization\"},\"image\":{\"@id\":\"https:\/\/griddb.net\/ja\/%e6%9c%aa%e5%88%86%e9%a1%9e\/scheduling-data-migration-from-postgresql-to-griddb-using-apache-airflow\/#primaryimage\"},\"thumbnailUrl\":\"\/wp-content\/uploads\/2023\/03\/airflowandgriddb1.png\",\"inLanguage\":\"ja\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/griddb.net\/ja\/%e6%9c%aa%e5%88%86%e9%a1%9e\/scheduling-data-migration-from-postgresql-to-griddb-using-apache-airflow\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/griddb.net\/ja\/%e6%9c%aa%e5%88%86%e9%a1%9e\/scheduling-data-migration-from-postgresql-to-griddb-using-apache-airflow\/\",\"url\":\"https:\/\/griddb.net\/ja\/%e6%9c%aa%e5%88%86%e9%a1%9e\/scheduling-data-migration-from-postgresql-to-griddb-using-apache-airflow\/\",\"name\":\"Apache Airflow\u3092\u4f7f\u3063\u3066PostgreSQL\u304b\u3089GridDB\u3078\u306e\u30c7\u30fc\u30bf\u79fb\u884c\u3092\u8a08\u753b\u3059\u308b | GridDB: Open Source Time Series Database for IoT\",\"isPartOf\":{\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/griddb.net\/ja\/%e6%9c%aa%e5%88%86%e9%a1%9e\/scheduling-data-migration-from-postgresql-to-griddb-using-apache-airflow\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/griddb.net\/ja\/%e6%9c%aa%e5%88%86%e9%a1%9e\/scheduling-data-migration-from-postgresql-to-griddb-using-apache-airflow\/#primaryimage\"},\"thumbnailUrl\":\"\/wp-content\/uploads\/2023\/03\/airflowandgriddb1.png\",\"datePublished\":\"2023-02-02T08:00:00+00:00\",\"dateModified\":\"2025-11-14T15:56:00+00:00\",\"description\":\"\u4ee5\u524d\u306e\u30d6\u30ed\u30b0\u3067\u3001\u30b5\u30f3\u30d7\u30ebIoT\u30c7\u30fc\u30bf\u30bb\u30c3\u30c8\u3092PostgreSQL\u304b\u3089GridDB\u306b\u79fb\u884c\u3059\u308b\u65b9\u6cd5\u306b\u3064\u3044\u3066\u8aac\u660e\u3057\u307e\u3057\u305f\u3002\u305d\u306e\u969b\u3001GridDB\u306e\u516c\u5f0f\u30a4\u30f3\u30dd\u30fc\u30c8\u30fb\u30a8\u30af\u30b9\",\"inLanguage\":\"ja\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/griddb.net\/ja\/%e6%9c%aa%e5%88%86%e9%a1%9e\/scheduling-data-migration-from-postgresql-to-griddb-using-apache-airflow\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"ja\",\"@id\":\"https:\/\/griddb.net\/ja\/%e6%9c%aa%e5%88%86%e9%a1%9e\/scheduling-data-migration-from-postgresql-to-griddb-using-apache-airflow\/#primaryimage\",\"url\":\"\/wp-content\/uploads\/2023\/03\/airflowandgriddb1.png\",\"contentUrl\":\"\/wp-content\/uploads\/2023\/03\/airflowandgriddb1.png\",\"width\":1160,\"height\":653},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#website\",\"url\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/\",\"name\":\"GridDB: Open Source Time Series Database for IoT\",\"description\":\"GridDB is an open source time-series database with the performance of NoSQL and convenience of SQL\",\"publisher\":{\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"ja\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#organization\",\"name\":\"Fixstars\",\"url\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"ja\",\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/griddb.net\/wp-content\/uploads\/2019\/04\/fixstars_logo_web_tagline.png\",\"contentUrl\":\"https:\/\/griddb.net\/wp-content\/uploads\/2019\/04\/fixstars_logo_web_tagline.png\",\"width\":200,\"height\":83,\"caption\":\"Fixstars\"},\"image\":{\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/griddbcommunity\/\",\"https:\/\/x.com\/GridDBCommunity\",\"https:\/\/www.linkedin.com\/company\/griddb-by-toshiba\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/person\/c8a430e7156a9e10af73b1fbb46c2740\",\"name\":\"Israel\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"ja\",\"@id\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/4df8cfc155402a2928d11f80b0220037b8bd26c4f1b19c4598d826e0306e6307?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/4df8cfc155402a2928d11f80b0220037b8bd26c4f1b19c4598d826e0306e6307?s=96&d=mm&r=g\",\"caption\":\"Israel\"},\"url\":\"https:\/\/griddb.net\/ja\/author\/israel\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Apache Airflow\u3092\u4f7f\u3063\u3066PostgreSQL\u304b\u3089GridDB\u3078\u306e\u30c7\u30fc\u30bf\u79fb\u884c\u3092\u8a08\u753b\u3059\u308b | GridDB: Open Source Time Series Database for IoT","description":"\u4ee5\u524d\u306e\u30d6\u30ed\u30b0\u3067\u3001\u30b5\u30f3\u30d7\u30ebIoT\u30c7\u30fc\u30bf\u30bb\u30c3\u30c8\u3092PostgreSQL\u304b\u3089GridDB\u306b\u79fb\u884c\u3059\u308b\u65b9\u6cd5\u306b\u3064\u3044\u3066\u8aac\u660e\u3057\u307e\u3057\u305f\u3002\u305d\u306e\u969b\u3001GridDB\u306e\u516c\u5f0f\u30a4\u30f3\u30dd\u30fc\u30c8\u30fb\u30a8\u30af\u30b9","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/griddb.net\/ja\/\u672a\u5206\u985e\/scheduling-data-migration-from-postgresql-to-griddb-using-apache-airflow\/","og_locale":"ja_JP","og_type":"article","og_title":"Apache Airflow\u3092\u4f7f\u3063\u3066PostgreSQL\u304b\u3089GridDB\u3078\u306e\u30c7\u30fc\u30bf\u79fb\u884c\u3092\u8a08\u753b\u3059\u308b | GridDB: Open Source Time Series Database for IoT","og_description":"\u4ee5\u524d\u306e\u30d6\u30ed\u30b0\u3067\u3001\u30b5\u30f3\u30d7\u30ebIoT\u30c7\u30fc\u30bf\u30bb\u30c3\u30c8\u3092PostgreSQL\u304b\u3089GridDB\u306b\u79fb\u884c\u3059\u308b\u65b9\u6cd5\u306b\u3064\u3044\u3066\u8aac\u660e\u3057\u307e\u3057\u305f\u3002\u305d\u306e\u969b\u3001GridDB\u306e\u516c\u5f0f\u30a4\u30f3\u30dd\u30fc\u30c8\u30fb\u30a8\u30af\u30b9","og_url":"https:\/\/griddb.net\/ja\/\u672a\u5206\u985e\/scheduling-data-migration-from-postgresql-to-griddb-using-apache-airflow\/","og_site_name":"GridDB: Open Source Time Series Database for IoT","article_publisher":"https:\/\/www.facebook.com\/griddbcommunity\/","article_published_time":"2023-02-02T08:00:00+00:00","article_modified_time":"2025-11-14T15:56:00+00:00","og_image":[{"width":1160,"height":653,"url":"https:\/\/griddb.net\/wp-content\/uploads\/2023\/03\/airflowandgriddb1.png","type":"image\/png"}],"author":"Israel","twitter_card":"summary_large_image","twitter_creator":"@GridDBCommunity","twitter_site":"@GridDBCommunity","twitter_misc":{"\u57f7\u7b46\u8005":"Israel","\u63a8\u5b9a\u8aad\u307f\u53d6\u308a\u6642\u9593":"12\u5206"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/griddb.net\/ja\/%e6%9c%aa%e5%88%86%e9%a1%9e\/scheduling-data-migration-from-postgresql-to-griddb-using-apache-airflow\/#article","isPartOf":{"@id":"https:\/\/griddb.net\/ja\/%e6%9c%aa%e5%88%86%e9%a1%9e\/scheduling-data-migration-from-postgresql-to-griddb-using-apache-airflow\/"},"author":{"name":"Israel","@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/person\/c8a430e7156a9e10af73b1fbb46c2740"},"headline":"Apache Airflow\u3092\u4f7f\u3063\u3066PostgreSQL\u304b\u3089GridDB\u3078\u306e\u30c7\u30fc\u30bf\u79fb\u884c\u3092\u8a08\u753b\u3059\u308b","datePublished":"2023-02-02T08:00:00+00:00","dateModified":"2025-11-14T15:56:00+00:00","mainEntityOfPage":{"@id":"https:\/\/griddb.net\/ja\/%e6%9c%aa%e5%88%86%e9%a1%9e\/scheduling-data-migration-from-postgresql-to-griddb-using-apache-airflow\/"},"wordCount":292,"commentCount":0,"publisher":{"@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#organization"},"image":{"@id":"https:\/\/griddb.net\/ja\/%e6%9c%aa%e5%88%86%e9%a1%9e\/scheduling-data-migration-from-postgresql-to-griddb-using-apache-airflow\/#primaryimage"},"thumbnailUrl":"\/wp-content\/uploads\/2023\/03\/airflowandgriddb1.png","inLanguage":"ja","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/griddb.net\/ja\/%e6%9c%aa%e5%88%86%e9%a1%9e\/scheduling-data-migration-from-postgresql-to-griddb-using-apache-airflow\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/griddb.net\/ja\/%e6%9c%aa%e5%88%86%e9%a1%9e\/scheduling-data-migration-from-postgresql-to-griddb-using-apache-airflow\/","url":"https:\/\/griddb.net\/ja\/%e6%9c%aa%e5%88%86%e9%a1%9e\/scheduling-data-migration-from-postgresql-to-griddb-using-apache-airflow\/","name":"Apache Airflow\u3092\u4f7f\u3063\u3066PostgreSQL\u304b\u3089GridDB\u3078\u306e\u30c7\u30fc\u30bf\u79fb\u884c\u3092\u8a08\u753b\u3059\u308b | GridDB: Open Source Time Series Database for IoT","isPartOf":{"@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#website"},"primaryImageOfPage":{"@id":"https:\/\/griddb.net\/ja\/%e6%9c%aa%e5%88%86%e9%a1%9e\/scheduling-data-migration-from-postgresql-to-griddb-using-apache-airflow\/#primaryimage"},"image":{"@id":"https:\/\/griddb.net\/ja\/%e6%9c%aa%e5%88%86%e9%a1%9e\/scheduling-data-migration-from-postgresql-to-griddb-using-apache-airflow\/#primaryimage"},"thumbnailUrl":"\/wp-content\/uploads\/2023\/03\/airflowandgriddb1.png","datePublished":"2023-02-02T08:00:00+00:00","dateModified":"2025-11-14T15:56:00+00:00","description":"\u4ee5\u524d\u306e\u30d6\u30ed\u30b0\u3067\u3001\u30b5\u30f3\u30d7\u30ebIoT\u30c7\u30fc\u30bf\u30bb\u30c3\u30c8\u3092PostgreSQL\u304b\u3089GridDB\u306b\u79fb\u884c\u3059\u308b\u65b9\u6cd5\u306b\u3064\u3044\u3066\u8aac\u660e\u3057\u307e\u3057\u305f\u3002\u305d\u306e\u969b\u3001GridDB\u306e\u516c\u5f0f\u30a4\u30f3\u30dd\u30fc\u30c8\u30fb\u30a8\u30af\u30b9","inLanguage":"ja","potentialAction":[{"@type":"ReadAction","target":["https:\/\/griddb.net\/ja\/%e6%9c%aa%e5%88%86%e9%a1%9e\/scheduling-data-migration-from-postgresql-to-griddb-using-apache-airflow\/"]}]},{"@type":"ImageObject","inLanguage":"ja","@id":"https:\/\/griddb.net\/ja\/%e6%9c%aa%e5%88%86%e9%a1%9e\/scheduling-data-migration-from-postgresql-to-griddb-using-apache-airflow\/#primaryimage","url":"\/wp-content\/uploads\/2023\/03\/airflowandgriddb1.png","contentUrl":"\/wp-content\/uploads\/2023\/03\/airflowandgriddb1.png","width":1160,"height":653},{"@type":"WebSite","@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#website","url":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/","name":"GridDB: Open Source Time Series Database for IoT","description":"GridDB is an open source time-series database with the performance of NoSQL and convenience of SQL","publisher":{"@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"ja"},{"@type":"Organization","@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#organization","name":"Fixstars","url":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/","logo":{"@type":"ImageObject","inLanguage":"ja","@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/logo\/image\/","url":"https:\/\/griddb.net\/wp-content\/uploads\/2019\/04\/fixstars_logo_web_tagline.png","contentUrl":"https:\/\/griddb.net\/wp-content\/uploads\/2019\/04\/fixstars_logo_web_tagline.png","width":200,"height":83,"caption":"Fixstars"},"image":{"@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/griddbcommunity\/","https:\/\/x.com\/GridDBCommunity","https:\/\/www.linkedin.com\/company\/griddb-by-toshiba"]},{"@type":"Person","@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/person\/c8a430e7156a9e10af73b1fbb46c2740","name":"Israel","image":{"@type":"ImageObject","inLanguage":"ja","@id":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/4df8cfc155402a2928d11f80b0220037b8bd26c4f1b19c4598d826e0306e6307?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/4df8cfc155402a2928d11f80b0220037b8bd26c4f1b19c4598d826e0306e6307?s=96&d=mm&r=g","caption":"Israel"},"url":"https:\/\/griddb.net\/ja\/author\/israel\/"}]}},"_links":{"self":[{"href":"https:\/\/griddb.net\/ja\/wp-json\/wp\/v2\/posts\/50845","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/griddb.net\/ja\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/griddb.net\/ja\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/griddb.net\/ja\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/griddb.net\/ja\/wp-json\/wp\/v2\/comments?post=50845"}],"version-history":[{"count":1,"href":"https:\/\/griddb.net\/ja\/wp-json\/wp\/v2\/posts\/50845\/revisions"}],"predecessor-version":[{"id":51672,"href":"https:\/\/griddb.net\/ja\/wp-json\/wp\/v2\/posts\/50845\/revisions\/51672"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/griddb.net\/ja\/wp-json\/wp\/v2\/media\/50344"}],"wp:attachment":[{"href":"https:\/\/griddb.net\/ja\/wp-json\/wp\/v2\/media?parent=50845"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/griddb.net\/ja\/wp-json\/wp\/v2\/categories?post=50845"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/griddb.net\/ja\/wp-json\/wp\/v2\/tags?post=50845"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}