【Github】Github Actions ~ Python関連 ~

■ はじめに

* Pythonにまつわる以下の事項について扱う

[1] egg / wheel ファイルをGithub Actionsを使って作成する
 その際に学べたことメモする。
[2] Python の Linter について実装する

なお、Pythonを実行させる場合は、以下の関連記事を参照のこと

Github Actions ~ Pythonを使うには ~
https://dk521123.hatenablog.com/entry/2024/02/04/011205

目次

【1】egg / wheel ファイル作成
 1)今回やりたいこと
 2)今回Github Actionsで学べたこと
 3)サンプル
 4)動作確認
【2】Python の Linterを組み込む
 1)flake8/black/isort を使う
 2)Ruff を使う

【1】egg / wheel ファイル作成

1)今回やりたいこと

* egg / wheel ファイルをGithub Actionsを使って作成する
* その際、ファイルサイズを確認
 + 一定サイズ以下であれば、エラー
 + 一定サイズを超えていたら、Githubにコミット&プッシュ

2)今回Github Actionsで学べたこと

[1] 環境変数 GITHUB_ENV

以下の関連記事を参照のこと

Github Actions ~ GITHUB_ENV ~
https://dk521123.hatenablog.com/entry/2023/12/29/000840

[2] if

ファイルサイズの大きさによっては、中断させたいので
分岐になる if が必要

https://zenn.dev/matken/articles/github-actions-if-and-env#if

以下の関連記事を参照のこと

Github Actions ~ if ~
https://dk521123.hatenablog.com/entry/2024/03/11/000000

3)サンプル

前提条件
https://dk521123.hatenablog.com/entry/2020/02/09/234350

で、egg / wheel ファイルを作成したが、それを Push のタイミングで、
「python setup.py bdist_egg」/「python setup.py bdist_wheel」を
実行するようにする

なお、以下のサイトを参考にして実装した。

https://andrewpwheeler.com/2022/05/10/building-wheel-files-in-github-actions/

github-actions-demo2.yml

# This is a basic workflow to help you get started with Actions

name: CI

# Controls when the workflow will run
on:
  # Triggers the workflow on push or pull request events but only for the "develop" branch
  push:
    branches: [ "develop" ]
  pull_request:
    branches: [ "develop" ]

  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  # This workflow contains a single job called "build"
  build:
    # The type of runner that the job will run on
    runs-on: ubuntu-latest

    # Steps represent a sequence of tasks that will be executed as part of the job
    steps:
      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
      - uses: actions/checkout@v3

      - name: Setup Python
        uses: actions/setup-python@v2
        with:
          python-version: '3.7'
          architecture: 'x64'
      - name: Get Python version
        run: python -V
      - name: Build wheel and install
        run: |
          python -m pip install --upgrade pip --user
          pip install wheel
          pip install PasteScript
      # Wheelファイル作成およびファイルサイズをWHL_FILE_SIZEに格納
      - name: Run Python
        run: |
          python ./DemoLib/setup.py bdist_wheel
          cp ./dist/*.whl ./DemoLib/dist/*.whl
          echo "WHL_FILE_SIZE=$(wc -c ./dist/*.whl | awk '{print $1}')" >> $GITHUB_ENV
      # Wheelファイルサイズを確認(2000byte以下であれば中断)
      - name: File size check
        if: ${{ env.WHL_FILE_SIZE <= 2000 }}
        run: exit 1
      - name: Configure Git
        run: |
          git config --global user.email "xxxxx@gmail.com"
          git config --global user.name "xxxxx"
      # Git コミット&プッシュ
      - name: Commit and push wheel
        run: |
          git add -f ./DemoLib/dist/*.whl
          git commit -m 'pushing new wheel'
          git push

4)動作確認

[1] ダウンロード

[1] Github で、[Code]-[Download ZIP]でモジュールをダウンロード
 => 今回は「github-actions-demo-develop.zip」
[2] ダウンロードしたモジュールを解凍する

[2] インストール

# インストール
pip install DemoLib-0.1.dev0-py3-none-any.whl 

# 確認1:pip list
pip list
・・・
DemoLib            0.0
・・・

# 確認2:pip show <package>
pip show DemoLib

[3] 動作確認

from demolib.demo_lib import *

if __name__=='__main__':
  result = say_hello('Mike')
  print('Result = {}'.format(result)) # Result = Hello, Mike.

[4] アンインストール

# アンインストール
pip uninstall DemoLib

# 動作確認(DemoLibが存在しないことを確認)
pip list

【2】Python の Linterを組み込む

1)flake8/black/isort を使う

Github Actionsで「flake8」「black」「isort」を使いたい
=> 各ツールの詳細については、以下の関連記事を参照のこと。

Python を奇麗に書くためのツール群
https://dk521123.hatenablog.com/entry/2021/11/08/221219
flake8 ~ Pythonコードチェック ~
https://dk521123.hatenablog.com/entry/2020/02/07/000000
black ~ Python formatter ~
https://dk521123.hatenablog.com/entry/2021/11/10/095258

サンプル

# This is a basic workflow to help you get started with Actions

name: CI

# Controls when the workflow will run
on:
  # Triggers the workflow on push or pull request events but only for the develop branch
  push:
    branches: [develop]
  pull_request:
    branches: [develop]

  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  # This workflow contains a single job called "build"
  build:
    # The type of runner that the job will run on
    runs-on: ubuntu-latest
    env:
      PYTHON_VERSION: 3.7
      MAX_LINE_LENGTH: 120
    steps:
      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
      - uses: actions/checkout@v2
      - name: Set up Python 3.X
        uses: actions/setup-python@v2
        with:
          python-version: ${PYTHON_VERSION}
      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install flake8 isort black
      - name: Lint
        run: |
          flake8 . --max-line-length=${MAX_LINE_LENGTH}
          isort --check --diff .
          black --check --line-length ${MAX_LINE_LENGTH} .

2)Ruff を使う

* Ruff に関する詳細は、以下の関連記事を参照のこと

Python解析ツール ~ Ruff ~
https://dk521123.hatenablog.com/entry/2024/03/13/000021

name: DemoWorkflowLinter

on:
  workflow_dispatch:

jobs:
  sample-job:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: '3.10'
      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install ruff
      - name: Lint with Ruff
        run: |
          ruff check --output-format=github .
        continue-on-error: true

DemoLib/setup.py

from setuptools import setup, find_packages
import sys, os

version = '0.0'

setup(name='DemoLib',
      version=version,
      description="",
      long_description="""\
""",
      classifiers=[], # Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers
      keywords='',
      author='',
      author_email='',
      url='',
      license='',
      packages=find_packages(exclude=['ez_setup', 'examples', 'tests']),
      include_package_data=True,
      zip_safe=False,
      install_requires=[
          # -*- Extra requirements: -*-
      ],
      entry_points="""
      # -*- Entry points: -*-
      """,
      )

main.py

from demolib.demo_lib import *

if __name__=='__main__':
  result = say_hello('Mike')
  print('Result = {}'.format(result))

https://docs.github.com/ja/actions/automating-builds-and-tests/building-and-testing-python#using-ruff-to-lint-code

出力結果

Error: DemoLib/setup.py:2:1: E401 Multiple imports on one line
Error: DemoLib/setup.py:2:8: F401 `sys` imported but unused
Error: DemoLib/setup.py:2:13: F401 `os` imported but unused
Error: main.py:1:1: F403 `from demolib.demo_lib import *` used; unable to detect undefined names
Error: main.py:4:12: F405 `say_hello` may be undefined, or defined from star imports
Error: Process completed with exit code 1.

関連記事

Github ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2019/07/18/234652
Github Actions ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2021/11/04/142835
Github Actions ~ 基本編 ~
https://dk521123.hatenablog.com/entry/2022/06/16/151443
Github Actions ~ Pythonを使うには ~
https://dk521123.hatenablog.com/entry/2024/02/04/011205
Github Actions ~ GITHUB_ENV ~
https://dk521123.hatenablog.com/entry/2023/12/29/000840
Github Actions ~ ワークフロー制御 ~
https://dk521123.hatenablog.com/entry/2024/01/28/004128
Github Actions ~ if ~
https://dk521123.hatenablog.com/entry/2024/03/11/000000
Github Actions ~ SQL Linter ~
https://dk521123.hatenablog.com/entry/2024/03/04/180308
Github Actions ~ reviewdog ~
https://dk521123.hatenablog.com/entry/2024/04/13/232832
egg / wheel ファイルを作成する
https://dk521123.hatenablog.com/entry/2020/02/09/234350
大きいファイルを扱う際のコマンド
https://dk521123.hatenablog.com/entry/2020/06/12/000000
Python解析ツール ~ Ruff ~
https://dk521123.hatenablog.com/entry/2024/03/13/000021

【Snowflake】Snowflake ~ テストデータ作成 / generator ~

■ はじめに

 Snowflake の generator() ってメソッドで、
テストデータを簡単に作れるって聞いたので調べてみた。
 調べてみて generator() だけでなく、
他のメソッドと組み合わせる必要があるので、それらもまとめてみる。

 Snowflakeに関して、調べてみたも日本語の情報は
通常皆無なんだが、今回は2件ほど記事(以下のサイト)が見つかった。
とてもいいことだと思った、、、

参考文献
https://dev.classmethod.jp/articles/snowflake-generator/
https://zenn.dev/indigo13love/articles/6c3a3b234e5279

目次

【1】基本
 1)GENERATOR関数
 2)TABLEリテラル
【2】シーケンス
 1)SEQ1 / SEQ2 / SEQ4 / SEQ8関数
 2)ROW_NUMBER関数
【3】乱数・ランダム文字列
 1)UNIFORM関数
 2)RANDOM関数
 3)RANDSTR関数
【4】半構造化データ
 1)OBJECT_CONSTRUCT
【5】サンプル
 例1)テストデータ作成
 例2)既存テーブルにINSERTしてテストデータ追加
 例3)アンロードを利用してテストデータファイル作成

【1】基本

1)GENERATOR関数

https://docs.snowflake.com/ja/sql-reference/functions/generator.html

より抜粋
~~~~~
指定された行数、指定された生成期間(秒単位)、
またはその両方に基づいてデータの行を作成します。
~~~~~

構文

GENERATOR( ROWCOUNT => <count> [ , TIMELIMIT => <sec> ] )

GENERATOR( [ TIMELIMIT => <sec> ] )

--  1 を格納したの行を 10 行生成
SELECT 1 FROM TABLE(GENERATOR(ROWCOUNT => 10));
-- TABLE については、後述「2)TABLEリテラル」を参照

-- テーブル「demo_table」にデータを入れる例
create or replace table demo_table (item1 int) as
select 1 from table(generator(rowcount => 10));

2)TABLEリテラル

* GENERATOR関数は、FROM句の後にTABLEリテラルと併せて使う
 => とりあえず、決まり事だと思ってよさそう
* TABLEリテラルの詳細は、以下の公式ドキュメントを参照。

https://docs.snowflake.com/ja/sql-reference/literals-table.html

【2】シーケンス

1)SEQ1 / SEQ2 / SEQ4 / SEQ8関数

* 整数値をラウンドアップで返す

https://docs.snowflake.com/ja/sql-reference/functions/seq1.html

select seq8() from table(generator(rowcount => 5));

+--------+
| SEQ8() |
|--------|
|      0 |
|      1 |
|      2 |
|      3 |
|      4 |
+--------+
# 関数名 説明
1 SEQ1 1バイト(-128~127)の値を返す
2 SEQ2 2バイト(-32768~32767)の値を返す
3 SEQ4 4バイト(-2147483648~2147483647)の値を返す
4 SEQ8 8バイト(-9223372036854775807~9223372036854775807)の値を返す

構文

-- 0(デフォルト) : シーケンスはラップアラウンド後も0で継続
-- 1: 表現可能な最小の数で継続(SEQ1の場合、127になったら、-128,-127,...)
SEQ1( [0|1] )

2)ROW_NUMBER関数

使用上の注意
https://docs.snowflake.com/ja/sql-reference/functions/seq1.html

より抜粋
~~~~~~~
必ずしもギャップのないシーケンスを生成するわけではありません。
大量のデータを処理する場合、シーケンスにギャップが生じることがあります。
完全に順序付けられたギャップのないシーケンスが必要な場合は、 
ROW_NUMBER ウィンドウ関数の使用を検討してください。
~~~~~~~

select row_number() over (order by seq4()) 
    from table(generator(rowcount => 5));

【3】乱数・ランダム文字列

1)UNIFORM関数

* 指定された範囲[第1引数:最小、第2引数: 最大]で一様に乱数を返す

https://docs.snowflake.com/ja/sql-reference/functions/uniform.html
構文

-- 第1引数/第2引数で指定した値の間 (from-to)
-- 第3引数に指定した内容に基づき、乱数を生成
UNIFORM( <min> , <max> , <gen> )

select uniform(1, 10, random()) from table(generator(rowcount => 5));

--------------------------+
 uniform(1, 10, random()) |
--------------------------+
 6                        |
 4                        |
 7                        |
 9                        |
 4                        |
--------------------------+

2)RANDOM関数

* ランダム関数(そのまんま)
 => 64ビット整数を返す

https://docs.snowflake.com/ja/sql-reference/functions/random.html

3)RANDSTR関数

* 任意の長さの文字列を生成

https://docs.snowflake.com/ja/sql-reference/functions/randstr.html

-- RANDSTR( <length> , <gen> )
-- <length>: 文字列数(今回は、「3」)
select randstr(3, random())
from table(generator(rowcount => 5));

--------------------------+
 randstr(3, random())      |
--------------------------+
 jrE                      |
 jTS                        |
 MCi                        |
 dKS                        |
 Dsj                        |
--------------------------+

【4】半構造化データ

https://zenn.dev/indigo13love/articles/6c3a3b234e5279

1)OBJECT_CONSTRUCT

* 引数から構築された OBJECT を返す
 => JSONファイルを作成する際に使用

https://docs.snowflake.com/ja/sql-reference/functions/object_construct.html

【5】サンプル

例1)テストデータ作成

-- 後は、上述の関数を組み合わせて、自分好みにするだけ
select seq4(), uniform(1, 10, random(12)),  randstr(5, random())
  from table(generator(timelimit => 1)) v;

-- 1sec 秒間実行され、時間枠内で可能な限り多くの行が生成されます。
-- => 結構、作成されるので要調節。

https://docs.snowflake.com/ja/sql-reference/functions/generator.html#usage-notes

例2)既存テーブルにINSERTしてテストデータ追加

insert into sample_table (
  no,
  id,
  name
)
select seq4(), uniform(1, 10, random(12)),  randstr(5, random())
  from table(generator(rowcount => 10));

例3)アンロードを利用してテストデータファイル作成

https://zenn.dev/indigo13love/articles/6c3a3b234e5279#%E3%82%A2%E3%83%B3%E3%83%AD%E3%83%BC%E3%83%89%E3%81%A7%E3%83%80%E3%83%9F%E3%83%BC%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E7%94%9F%E6%88%90%E3%81%99%E3%82%8B

が参考になる

アンロードとは?
https://dk521123.hatenablog.com/entry/2022/07/04/172738

より抜粋

~~~~~~~~~
Snowflakeテーブルからデータをアンロード(つまり、エクスポート)
~~~~~~~~~
 => つまり、Snowflakeテーブルからデータをファイル出力すること

例:AWS S3へのダミーファイル出力

-- Step1: 外部ステージを作成する
-- https://docs.snowflake.com/ja/user-guide/data-unload-s3.html#unloading-data-into-an-external-stage  
create or replace stage ext_demo_stage
  url='s3://your-bucket/path/to/'
  storage_integration = s3_int;

-- Step2: ダミーデータ用テーブルを用意
create or replace table demo_dummy_table (
  id int,
  name varchar
) as
select random(), randstr(5, random()), 
from table(generator(rowcount => 5));

-- Step3: アンロードする

-- 3-1) CSVの場合
copy into @ext_demo_stage/output.csv from demo_dummy_table
  file_format = (type = csv)
  single = true;

-- 3-2) JSONの場合
copy into @ext_demo_stage/output.json 
from (select object_construct('id', id, 'name', name) from demo_dummy_table)
  file_format = (type = json)
  single = true;

-- 3-3) Parquetの場合
copy into @ext_demo_stage/output.parquet  from demo_dummy_table
  file_format = (type = parquet)
  single = true;

https://docs.snowflake.com/ja/user-guide/data-unload-considerations.html

補足:COPY INTO
https://docs.snowflake.com/ja/sql-reference/sql/copy-into-location.html

より
~~~~~~~~~~~~~~~~~~
SINGLE = TRUE | FALSE

定義
単一のファイルを生成する(TRUE)か
複数のファイルを生成する(FALSE)かを指定するブール値。 
FALSE の場合、ファイル名プレフィックスを パス に含める必要があります。
~~~~~~~~~~~~~~~~~~

参考文献

https://dev.classmethod.jp/articles/snowflake-generator/
https://zenn.dev/indigo13love/articles/6c3a3b234e5279

関連記事

Snowflake ~ 基礎知識編 ~
https://dk521123.hatenablog.com/entry/2021/11/02/130111
Snowflake ~ 入門編 / Hello world
https://dk521123.hatenablog.com/entry/2021/11/22/212520
Snowflake ~ 基本編 / データロード ~
https://dk521123.hatenablog.com/entry/2021/11/15/221245
Snowflake ~ データ アンロード ~
https://dk521123.hatenablog.com/entry/2022/07/04/172738
Snowflake ~ ストレージ統合 ~
https://dk521123.hatenablog.com/entry/2022/06/29/221037
Snowflake】ストアド ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2022/12/11/202904

【Snowflake】Snowflake ~ 日時関連 ~

■ はじめに

Snowflake の 日時(日付、時刻含む)について
少しづつだが、まとめておく。

目次

【1】日時(日付、時刻含む)のデータ型
【2】現在日時を返す関数
【3】日時(日付、時刻含む)の変換
 1)キャスト
 2)DATE_FROM_PARTS関数
【4】日時の計算
 1)DATEADD関数
 2)DATEDIFF関数
 3)DATE_TRUNC関数
 4)DAYNAME関数
 5)DATE_PART関数 / TO_VARCHAR関数
【5】日時関連のその他の技術事項
 1)Timezone を変更する
 2)間隔定数 - INTERVAL キーワード
 3)変換
 4)生年月日(生年) <=> 年齢

【1】日時(日付、時刻含む)のデータ型

https://docs.snowflake.com/ja/sql-reference/data-types-datetime.html

より抜粋
~~~~~~~~
1)DATE
2)DATETIME
3)TIME
4)TIMESTAMP
5)TIMESTAMP_LTZ , TIMESTAMP_NTZ , TIMESTAMP_TZ
~~~~~~~~
 => 詳細は、以下の関連記事を参照のこと

Snowflake ~ 基本編 / データ型 ~
https://dk521123.hatenablog.com/entry/2021/12/16/095524

【2】現在日時を返す関数

* sysdate() や current_timestamp() などがある
* 詳細は、以下の関連記事を参照のこと。

Snowflake ~ 日時関連 / 日時取得関数 ~
https://dk521123.hatenablog.com/entry/2022/09/02/092144

【3】日時(日付、時刻含む)の変換

1)キャスト

[1] CAST
[2] :: 演算子
[3] TO_ データ型
[4] TRY_CAST
[5] TRY_TO_ データ型

 => 詳細は、以下の関連記事を参照のこと

Snowflake ~ 基本編 / キャスト ~
https://dk521123.hatenablog.com/entry/2021/12/15/162658

[1] CAST

select cast('05-Mar-2014' as timestamp);

[2] :: 演算子

select '05-Mar-2014'::timestamp;

[3] TO_ データ型

-- TO_DATEの場合
select to_date('2013-05-17'), date('2013-05-17');

select to_date('20120723', 'YYYYMMDD');

select to_date('2012/07/23', 'YYYY/MM/DD');

select to_date('2012.07.23', 'YYYY.MM.DD'), date('2012.07.23', 'YYYY.MM.DD');

https://docs.snowflake.com/ja/sql-reference/functions/to_date.html
https://docs.snowflake.com/ja/sql-reference/functions/to_timestamp.html

[4] TRY_CAST

-- 変換できた場合は、そのままキャスト
select try_cast('05-Mar-2016' as timestamp);

+--------------------------------------+
| TRY_CAST('05-MAR-2016' AS TIMESTAMP) |
|--------------------------------------|
| 2016-03-05 00:00:00.000              |
+--------------------------------------+

-- 変換できなかった場合は、null を返却
select try_cast('05/16' as timestamp);

+--------------------------------+
| TRY_CAST('05/16' AS TIMESTAMP) |
|--------------------------------|
| NULL                           |
+--------------------------------+

https://docs.snowflake.com/ja/sql-reference/functions/try_cast.html

[5] TRY_TO_ データ型

select try_to_date('2018-09-15'), try_to_date('Invalid');

+---------------------------+------------------------+
| TRY_TO_DATE('2018-09-15') | TRY_TO_DATE('INVALID') |
|---------------------------+------------------------|
| 2018-09-15                | NULL                   |
+---------------------------+------------------------+

https://docs.snowflake.com/ja/sql-reference/functions/try_to_date.html
https://docs.snowflake.com/ja/sql-reference/functions/try_to_time.html
https://docs.snowflake.com/ja/sql-reference/functions/try_to_timestamp.html

2)DATE_FROM_PARTS関数

* 年、月、月の各数値から日付を作成

https://docs.snowflake.com/ja/sql-reference/functions/date_from_parts.html

-- DATE_FROM_PARTS( <year>, <month>, <day> )
select date_from_parts(1977, 8, 7);

+-----------------------------+
| DATE_FROM_PARTS(1977, 8, 7) |
|-----------------------------|
| 1977-08-07                  |
+-----------------------------+

【4】日時の計算

1)DATEADD関数

* 日時の加算

https://docs.snowflake.com/ja/sql-reference/functions/dateadd.html

select to_date('2013-05-08') as v1, dateadd(year, 2, to_date('2013-05-08')) as v;

-- 2013-05-08 + 2 year = 2015-05-08
+------------+------------+
| V1         | V          |
|------------+------------|
| 2013-05-08 | 2015-05-08 |
+------------+------------+

構文

DATEADD( <date_or_time_part>, <value>, <date_or_time_expr> )

補足:関数以外での加減算

* 「【5】日時関連のその他の技術事項」の
 「2)間隔定数 - INTERVAL キーワード」を参照。

2)DATEDIFF関数

* 2つの日付/時刻/タイムスタンプの差を計算

https://docs.snowflake.com/ja/sql-reference/functions/datediff.html

select
  datediff(
    year,
    '2010-04-09 14:39:20'::timestamp, 
    '2013-05-08 23:39:20'::timestamp) as diff_years;

+------------+
| DIFF_YEARS |
|------------|
|          3 |
+------------+

3)DATE_TRUNC関数

* DATE/TIME/TIMESTAMP を指定された精度に切り捨てる

https://docs.snowflake.com/ja/sql-reference/functions/date_trunc.html

select
  to_date('2015-05-08T23:39:20.123-07:00') as "DATE1",
  date_trunc('YEAR', "DATE1") as "TRUNCATED TO YEAR",
  date_trunc('MONTH', "DATE1") as "TRUNCATED TO MONTH",
  date_trunc('DAY', "DATE1") as "TRUNCATED TO DAY";

+------------+-------------------+--------------------+------------------+
| DATE1      | TRUNCATED TO YEAR | TRUNCATED TO MONTH | TRUNCATED TO DAY |
|------------+-------------------+--------------------+------------------|
| 2015-05-08 | 2015-01-01        | 2015-05-01         | 2015-05-08       |
+------------+-------------------+--------------------+------------------+

4)DAYNAME関数

* 曜日を算出

https://docs.snowflake.com/ja/sql-reference/functions/dayname.html

select dayname(to_date('2015-05-01')) as day;
+-----+
| DAY |
|-----|
| Fri |
+-----+

5)DATE_PART関数 / TO_VARCHAR関数

* 日時のパース処理

DATE_PART関数

* 日付/時刻/タイムスタンプから指定された各パーツ(year etc)を抽出

https://docs.snowflake.com/ja/sql-reference/functions/date_part.html

select
  to_timestamp('2013-05-08T23:39:20.123-07:00') as "TIME_STAMP1",
  date_part(year, "TIME_STAMP1") as "EXTRACTED YEAR";

-- yearを抽出 => 2013
+-------------------------+----------------+
| TIME_STAMP1             | EXTRACTED YEAR |
|-------------------------+----------------|
| 2013-05-08 23:39:20.123 |           2013 |
+-------------------------+----------------+

TO_VARCHAR

文字列型に変換する関数だが、この関数を使っても
日付のパーツをばらすことができる
 => 「DATE_PART関数」との違いは、文字列として返す点
  (以下の例を参照のこと)

select
  date('2022-01-03') as target_date,
  to_varchar(target_date, 'yyyy'), -- 2022
  to_varchar(target_date, 'MM'), -- 01
  to_varchar(target_date, 'dd') -- 03
;

-- 比較:date_partとの違い
-- 数字で出すので、01だった場合は、1として出力される
select
  date('2022-01-03') as target_date,
  date_part(year, target_date), -- 2022
  date_part(month, target_date), -- 1
  date_part(day, target_date) -- 3
;

【5】日時関連のその他の技術事項

1)Timezone を変更する

--  TIMEZONE を UTC時間に設定
alter session set timezone = 'UTC';

https://docs.snowflake.com/ja/user-guide/date-time-examples.html

2)間隔定数 - INTERVAL キーワード

* 簡単に日時を加減算することができる。

https://docs.snowflake.com/ja/sql-reference/data-types-datetime.html#interval-constants

-- 現在日時から+8時間
select current_timestamp + interval '8 hours' as interval1;

構文

{ + | - } INTERVAL '<integer> [ <date_time_part> ] [ , <integer> [ <date_time_part> ] ... ]'

3)変換

日時の部分取得

-- 2023
SELECT to_varchar(current_date(), 'yyyy');

-- 変数で取得
let year := to_varchar(current_date(), 'yyyy');
let month := to_varchar(current_date(), 'MM');
let day := to_varchar(current_date(), 'dd');

日付をINTで取得

-- 20230809
SELECT to_char(current_date(), 'YYYYMMDD')::int;

4)生年月日(生年) <=> 年齢

[1] 生年月日 => 年齢
https://qiita.com/r_1204/items/872f21e0fb13b22e650a

-- 1975-10-01 の場合
select
case when dateadd(year, datediff(years, '1975-10-01', current_date), '1975-10-01') > current_date
   then datediff(years, '1975-10-01', current_date) -1
   else datediff(years, '1975-10-01', current_date)
end as age;

[2] 年齢 => 生年

-- 35 歳(で、「YYYY-01-01 00:00:00」は固定)
select
    (YEAR(current_date) - 35) || '-01-01 00:00:00' as barth_date
;

関連記事

Snowflake ~ 基礎知識編 ~
https://dk521123.hatenablog.com/entry/2021/11/02/130111
Snowflake ~ 入門編 / Hello world
https://dk521123.hatenablog.com/entry/2021/11/22/212520
Snowflake ~ 基本編 / データ型 ~
https://dk521123.hatenablog.com/entry/2021/12/16/095524
Snowflake ~ 基本編 / キャスト ~
https://dk521123.hatenablog.com/entry/2021/12/15/162658
Snowflake ~ 日時関連 / 日時取得関数 ~
https://dk521123.hatenablog.com/entry/2022/09/02/092144