/// BANGBOO BLOG ///

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

May 2, 2021

Terrafirma
公式
https://www.terraform.io/docs/index.html
導入
https://www.terraform.io/guides/core-workflow.html
推奨方法
https://www.terraform.io/docs/cloud/guides/recommended-practices/index.html
 https://www.terraform.io/docs/cloud/guides/recommended-practices/part1.html
 https://www.terraform.io/docs/cloud/guides/recommended-practices/part2.html
 https://www.terraform.io/docs/cloud/guides/recommended-practices/part3.html
 https://www.terraform.io/docs/cloud/guides/recommended-practices/part3.1.html
 https://www.terraform.io/docs/cloud/guides/recommended-practices/part3.2.html
 https://www.terraform.io/docs/cloud/guides/recommended-practices/part3.3.html
 https://www.terraform.io/docs/cloud/guides/recommended-practices/part3.4.html
チュートリアル
https://learn.hashicorp.com/collections/terraform/gcp-get-started
HCL
https://www.terraform.io/docs/language/index.html
CLI aka cmd(アルファベットリストから使う)
https://www.terraform.io/docs/cli/auth/index.html
GCP用リファレンス
https://registry.terraform.io/providers/hashicorp/google/latest/docs

お便強
https://qiita.com/minamijoyo/items/1f57c62bed781ab8f4d7
https://qiita.com/donko_/items/6289bb31fecfce2cda79
https://www.apps-gcp.com/infra-automation-01/
https://colsis.jp/blog/gcpterraform/

Infra as codeとしてインフラの構築や設定をコード化できる
特にクラウドだと構築の自動化や構成管理等でのレバレッジが強力

■段階
Terraformとは?基本知識とTerraformのメリット4つを紹介 | テックマガジン from FEnetインフラ
必要なリソースをTerraform化>workspaceの活用>main.tfの共通部分をmodule化

moduleは構成に合わないようなリファクタリングが必要になった時にterraform state mv が必要になってとたんにつらい、moduleを細分化しすぎるとvariable と output が大量に必要になって書きづらい、moduleは再利用できる複数のリソースの単位(プログラミング言語でいうところの関数みたいなもの)で作るのがしっくり

リソースの差分を無視するlifecycleブロックを使う
resource "aws_autoscaling_group" "app_1" {
  name = "app-asg-1"
  lifecycle {
    ignore_changes = ["load_balancers"]
    create_before_destroy = true//新しいのを作ってから古いのを削除
  }
}
外部ファイルを文字列として読み込む
resource "aws_iam_role" "ec2_role" {
  name = "ec2-role"
  assume_role_policy = "${file("./ec2_assume_role_policy.json")}"
}
1つのディレクトリで複数のStateを扱うWorkspaceという機能もあるのですが、
個人的には普通にディレクトリを分けて管理する方が楽
production/stagingが完全に同じリソース構成で、設定のパラメータの差分がちょっとだけあるという理想的な世界ではWorkspaceでも運用できるかもしれませんが、現実的にはstagingだけリリース前の検証用の一時的なリソースが立ってたりとか、完全に同じ構成にならないことも多いので、モジュールの読み込みの有無や一部の環境だけ存在するリソースなどの差分を吸収できる場所があったほうが都合がよい

Terraform職人再入門2020 - Qiita
モジュールが公式から提供されている
Browse Modules | Terraform Registry

Terraform の terraform.tfvars とは | 30歳未経験からのITエンジニア (se-from30.com)
環境情報は外部ファイルが基本
prd/stg/dev環境はprd.tfvars, stg.tfvars, dev.tfvarsを用意
.tfvars 各環境の設定
aws_access_key    = "XXXXXXXXXXXXXXXXXXXX"
aws_secret_key    = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
aws_region        = "eu-west-1"
main.tf
terraform {
  required_version = "= 0.12.26"
}
provider "aws" {
  version    = "2.66.0"
  access_key = var.aws_access_key
  secret_key = var.aws_secret_key
  region     = var.aws_region
}
var.tf 空の受け皿
variable aws_access_key {}
variable aws_secret_key {}
variable aws_region {}

Terraform で変数を使う - Qiita
実行時に-var-fileで値ファイルを指定して環境などを切り替えると良いかもしれない
terrafrom plan -var-file=dev.tfvars
terrafrom plan -var-file=prod.tfvars
変数ファイル指定がないときは変数でdefaultに入れておく、descriptionで変数の説明もかける
variable "foo" {
  type = "string"
  default = "default-var"
  description = "Sample Variable"
}
変数ファイルを異なるバックエンド(フォルダ構成)で共有したいときはシンボリックリンクを貼る
 ln -s ../common/shared_var.tf shared_var.tf

credentials等の秘匿したい変数を外部のファイルやコマンドライン引数から読み込む
variable "credentials_file" {} @var.tf 変数を定義し空にしておく
credentials = file(var.credentials_file) @main.tf ファイルを読むがファイル名は変数
terraform plan -var 'project=' -var 'credentials_file=.json' @cmd プロジェクトとクレデンをコマンド時に指定
他にもvars.tfvars設定ファイル(行頭variableが不要)、TF_VAR_環境変数による指定

-var-fileで変数ファイルを明示してcmd、ファイル名は.tfvars/.tfvars.json
-varで変数を明示してcmd
順序があり後の読込でオーバーライド


HCLの変数は基本2種類のlocalとvariable
variableはグローバル変数、ファイル外やコマンドラインから使える
その他の変数参照方法としては(上から優先に適応)
 コマンド引数 一時的に使用
 変数ファイル terraform.tfvars git管理等で外部ファイルで?
 環境変数 TF_VAR_ 実行ログに残らない鍵情報等
workspaceは使わない、moduleを限定的に使う
設定をコード化>Gitレポジトリに置く>設定内容、作業履歴の明確化、チームでの運用性向上

■特性
TFの影響を反映するのはterraform applyの時だけ、tfファイルとtfstateの差分を実際にリソース作成する
 tfファイルで変更した場合、TFはリソースの再作成を行うので一度消えることになる(大体は単位が権限だったりで影響がないだけでplanで要注意)
terraform planはtfとtfstateと実体の差なので、実体があってもtfstateになければwill be createdでplan時は表示される
terraform importはtfファイルからtfstateへ記載だけを行う(実体からも情報を取得しtfstateに入れる)
 カレントdirの全.tfファイルor.tf.jsonを評価するのでtfファイルの名は何でもいい
各リソースに対してTF化するかは選択ができるが、TFする場合はそのリソースに必要な全記載をTFファイルに行う
terraform import tfResourceID.yourResourceName gcpIdentifier のコマンド
 terrafrom import google_bigquery_dataset.tf-1 bangboo-prj/test-dataset
 tfResourceID(リソースIDというようタイプ:リソース種別)はTF指定のもの、yourResourceName (リソース名)は任意のもの
 構成ファイル.tfはローカルのものが使われる、importするとtfstateに反映
 GCP identifierはTF公式サイトの各サービスの一番下import項目を見ると指定内容が分かるのでGCPを見て拾ってくる
 terraform state list TF化されているリソースを見る
 terrarorm apply時にもtfstateは更新される(オプション-refresh=falseで無効可)
  またapply時に-target=xxxでデプロイするリソースを特定できる(TFファイルだけでなくTFステートもターゲットになる)

Syntax - Configuration Language - Terraform by HashiCorp コメントは#が基本、//や/**/も使える
Terraform v0.12で変わるHCLの記述について - Qiita localsや変数、リストやマップ等
Terraform職人再入門2020 - Qiita yamldecodeやjsonencode等
Terraformの基本 - Foreverly (hatenablog.com)
変数
 variable(input var)はcmd実行時に変数を上書きできるが、localsはできない
 outputはapply時にterminalで値が確認できる、moduleから値を取得する

google_bigquery_connection | Resources | hashicorp/google | Terraform Registry
ドット繋ぎで値を扱える
resource "google_sql_database_instance" "instance" {
    provider         = google-beta
    name             = "my-database-instance"
}
resource "google_sql_database" "db" {
    instance = google_sql_database_instance.instance.name
    name     = "db"
}

ToSetは値設定をするが順不同で重複を省く
resource "xxx" "aaa" {
    for_each = toset(["foo", "bar", "bar"]) でbar, foo
    name = each.key
}

for_each/eachのループ
locals {
    sg = {
        foo = "FOO"
        bar = "BAR"
    }
}
resource "xxx" "aaa" {
    for_each = local.sg
    name = each.key
    description = each.value
}

mapをリストしたものをfor_each
locals {
  images = [
    { name = "foo", image = "alpine" },
    { name = "bar", image = "debian" },
  ]
}
resource "docker_container" "this" {
  for_each = { for i in local.images : i.name => i } # こう書くのが正しい
  name     = each.value.name
  image    = each.value.image
}

terraform importはリソース単位、更新はできず削除してから追加 terraform state rm google_bigquery_dataset.tf-1
 実設定とimportの内容が違う場合は実設定の情報でtfstate化されるようだ(importは項目を入れ込む感じ?)
  なので実環境に変更を加えるにはterrafrom apply、tfstate化もされtfファイル/tfstate/実設定の3者で同じになる
 apply時にtfstateと実設定が違う場合、例えば既存設定がある場合は重複エラーになりapplyできず、importしtfstateと実設定を同じにしてから、tfファイルの内容をapplyすることが必要
terraform importで対象プロジェクトを間違えるとハマる
 通常のterraform applyではproviderの情報を使用してプロジェクトを決めるが、importはハードコードするのでimportを間違えばなぜ変な変更がでるのかわからなくなる(プロジェクトが変なものはstateを調べ、terraform state rmするしか)

for_eachで書いた.tfをterraform importする | DevelopersIO (classmethod.jp)
 ユーザ指定は user:aaa@xxx.com だったりメールグループなら group:aaa@xxx.com

■セットアップ
 作業ディレクトリの作成(プロジェクトに対するローカルのフォルダ)
 プロバイダを指定したtfファイルの作成(gcsにstateを置く設定が良い
  provider "google" {
    project = "bangboo-kuso"
  }
  terraform {
    backend "gcs" {
      bucket = "bangboo-kuso-terraform"
    }
  }
 terraform init ローカルに対して初期化
 プロジェクトレベルownerのサービスアカウントを持っておく
 セットアップする際にtfsateのbackend保存場所のbucket部分をコメントアウト
 bucketを作るterraformを実施しbucketを作成しつつlocalにtfstateファイルを作成
 再度terraformをするとtfstateファイルがbucketにコピーされる
 bucket部分のコメントアウトを外すと次回tfからはバケットにtfstate更新する
  このときローカルtfstateの内容をバケットに写すか聞かれるが写す
  (写さないと差分しかバケットに行かないのでimport等が必要になる)

■既存リソースのTF化のおおよその作業
 リソースタイプと名前を定義したtfファイルを作成する(任意のリソース名、基本ユニーク、纏められるものは重複してもいい)
  resource "google_cloudfunctions_function" "fuckin" { ... をtfファイルに記載
   tfResourceID(リソースIDというようタイプ:リソース種別)とyourResourceName (リソース名) だけで
 リソースタイプや個別パラメータは公式ドキュメントを参照しながら定義
 https://registry.terraform.io/providers/hashicorp/google/latest/docs
  (簡単)tfファイル内で1行目以外は空で、terraform planをするとエラーで必要なものが分かるので、それを埋める
  planが通ると自動的に値をサーバから拾ってくる(importすればtfstate.tfに入っている or コピーしてTFに入れる)
  planでダメならterraform state show tfResourceID.yourResourceName でstateを見てtfファイルにパラメータを定義していく
   暫定に空でリソースをTFファイルに記載しterraform import、次にtfstateを調査する
    terraform state list tfstateファイルにあるアセットを一覧
    terraform import google_bigquery_table.xxx project/dataset/table インポート
    terraform state show google_bigquery_table.xxx tfstateの該当部を表示
    terraform state rm  google_bigquery_table.xxx インポート取り消し
  TF定義は複数の方法がある、最終GCP公式のRestAPIで確認するしか
 terraform importする(公式ドキュメントの一番下にimportコマンドの指定がある)
 terraform planして差分がなくなるまでtfファイルを修正する
  import(tfstate)の修正は一度stateから削除する terraform state rm google_bigquery_dataset.tf-1
  (既存リソースがあってもあくまでtfファイルとtfstateの差分なのでinitした状態でplanしてもup-to-dateと表示されるだけ)
 tfstateファイルにおかしなものが無いか確認、keyとか含まれないか

■個別
リファレンスでoptionalとなっていてもtfファイルでは必要な場合もある
 tfstateファイルからは必要ないとして自動的に削除されるが
スプシをBQでみれるFederatedQueryはテーブルだけ定義しimportしstate show調査
 urlをTFファイルに記載する
シャーディング(日付別)テーブルは定義できないのでは
 生成するクエリの方をTF化したい
Authorized viewはモジュールがあるがconflictがあり全消えする場合がありTF化にまだ向かない

google_bigquery_dataset_iam_memberでもAuthorized viewをはがしてしまう。
Authorized viewを使っている個所は google_bigquery_dataset_access あるいは google_bigquery_dataset の access フィールドを使う。
google_bigquer_dataset_iam_policy と google_bigquery_iam_binding は Authoritative で権限追加でなく権限強制設定でコンソール付与分を引き剝がすので、使わない方が安全。
なお、Authorized view と Routines はTerraform化できない事が分かっている(2022/4時点)
ScheduledQuery は Terraform化できるが実行者の設定ができない(Terraform実行者がSQ実行者?誰?)

BQ関連ではデータセット定義、テーブル定義、ビュー定義、フェデレテッドクエリ定義、ScheduledQuery定義をTerraformで行い
BQ権限定義、AuthorizedView定義、Routines定義は行わない

 BQ権限を定義するならデータセットレベルはgoogle_bigquery_dataset_access 
  プロジェクトレベルはgoogle_project_iam_memberで実施すると別なので安全らしい?

■TF公式ドキュメント
google_organization_iam_custom_role | Resources | hashicorp/google | Terraform Registry
google_organization_iam | Resources | hashicorp/google | Terraform Registry
カスタムロールを設定して、組織レベルのIAMでそれを使いたい
 TFのorg_iamページのArgument referenceのrole項目を見ると
  Note that custom roles must be of the format organizations/{{org_id}}/roles/{{role_id}}
 TFのorg_iam_custom_roleページのAttributes  referenceのrole項目を見ると
  id - an identifier for the resource with the format organizations/{{org_id}}/roles/{{role_id}}
 で下記と分かる、使用側と被使用側のTFマニュアルを両方確認する
resource "google_organization_iam_custom_role" "my-custom-role" {
  role_id     = "myCustomRole"
  org_id      = "123456789"
  title       = "My Custom Role"
  description = "A description"
  permissions = ["iam.roles.list", "iam.roles.create", "iam.roles.delete"]
}
resource "google_organization_iam_member" "my-organization" {
  org_id  = "123456789"
  role    = google_organization_iam_custom_role.my-custom-role.id
  #あるいは通常"roles/bigquery.dataEditor"のようにいれるがorganizations/0123456789/roles/chinkoといれる
  member  = "user:jane@example.com"
}

resourceの2番目リソース名を定義しますが任意の名前を指定します
 ここが同じ項目はユニーク制限がない場合は追加としてまとめられます
 通常はユニークにしterraformで管理するリソース名(yourResourceName)を宣言します
  ※1番目のリソースタイプ内でユニークにするのが基本(全体でもユニークの方が分かり易い)

TFファイルに定義をしたい →定義したいリソースのArgument referenceの項目を設定
TFファイルに定義した内容を変数で使いたい →使いたいリソースのAttributes referenceを見る
terraform importしたい →インポしたいリソースのページ一番下のimportコマンドの指定を見る

■他に一般的なTF(既存がimportされると以下で変更をapplyして運用)
 terraform -v 稼働確認
 terraform fmt ファイルの記述フォーマットを整える
 terraform validate ファイルの検証
 terraform plan アクションを計画
 terraform apply 最後に変更を適応
 terraform show ステータスを確認、一覧
 terraform destroy で簡単にインフラの吐き、initができないとき必要そう

■特定のリソースだけ適応したい
 terraform plan -target="tfResourceID.yourResourceName"
 terraform apply -target="tfResourceID.yourResourceName"
 TFファイルだけでなくTFステートもターゲットに含まれる
 これでTFファイルにコードがなくTFステートだけにあるものを指定して削除等もできる

■TFのcount
数を指定してその個数のリソースを作る。なのだが
 enable_lien = true モジュール側/変数側でこう設定し
 count = var.enable_lien ? 1 : 0 リソース側で3項演算子を使えばIFのように使える
  ※for loopのようなインクリのcount"+="でなく"="の1発実行なので3項演算子でIFになる

■エラー
bigquery access denied:
gcloud auth login --enable-gdrive-access
gcloud auth application-default login --scopes="https://www.googleapis.com/auth/drive","https://www.googleapis.com/auth/cloud-platform"
BigQueryでGoogleドライブデータへのクエリでエラーが出るときの対処 (zenn.dev)

排他処理でロックが残る:
他の作業者がいなければ、terraform apply -lock=false で一時的に無視をして続行
エラーIDに対して terraform force-unlock id_num963103164
Terraform で state のロックを解除する方法、ロックを手動で行う方法 | ゲンゾウ用ポストイット (genzouw.com)
TerraformでState Lockエラーが発生したら | DevelopersIO (classmethod.jp)


■terraformのバージョン管理
.terraform.lock.hclファイルでGCP provider等のライブラリのバージョン管理をしている、pyenvのPipfile.lockみたいなHash差分が記載されている、terraform init等で生成されapply時の設定が担保される、通常tfファイルでproviderのバージョンを記載すればよいので不要と思われる

.terraform-versionファイルでterraform自体の要求バージョンを担保できる
tfenvの.terraform-versionファイルにはバージョンベタ書きしなくてもOK | DevelopersIO (classmethod.jp)
通常はtfenvを使えばよい、tfファイルでrequired_versionを記載すればよいので不要と思われる

■tfenvを使う場合
tfenv install 1.0.0
tfenv list
tfenv use 1.0.0
 terraform init
 terraform workspace list
 terraform workspace select ore_space
main.tf作成し記載
 terraform fmt tfファイルのフォーマット(書式は適当で書けばいい)
  gcloud auth login ローカル操作のための認証
  gcloud auth application-default login SDKを実行のための認証
   API&Servicesでクレデンシャルは取得できそう、key=xxxx
既存のリソースを調査
terrafrom import google_storage_bucket.pri-bucket project-abc123/asia-northeast1/pri-bucket でimportとか
 terraform refresh tfstateの最新化、どのタイミングで使う?

■既存のリソースを調査
Terraform と gcloud CLI を使用した完璧な Google Cloud インフラストラクチャの構築 | Google Cloud Blog
gcloud beta resource-config bulk-export --help
gcloud beta resource-config bulk-export --project=kuso12345 --resource-format=terraform --path=/path/to/dir/
 対応を見ると数が少ないgcloud beta resource-config list-resource-types --format=json --project=kuso12345

terraformer import google list --projects=xxxx-123 で対象のリソース確認
terraformer import google --resources=instances,forwardingRules --regions=us-west1 --projects=xxxx-123 とか

既存リソースimport
https://www.apps-gcp.com/terraformit-gcp/
https://qiita.com/uu4k/items/48d3ecfefe57dba1d7e1

■Terraform applyで意図しない権限削除で障害が発生する
Terraform x GCP で、IAM権限を全削除してしまった - Qiita
resource "google_project_iam_policy" "unko" {
  project = "my-project"
  role = "roles/noguso"
  members = [
    "serviceAccount:${google_service_account.baka.email}"
  ]
}
google_project_iam_policy:書き換えるので他は無くなる(他を消したいときに使う)
google_project_iam_binding:付与、Authritativeだが他は現状維持?
google_project_iam_member:付与、Non-authoritativeで安全、まとめ難いか
 ※_iam_policyと_iam_bindingとt_iam_memberは一緒に使えない
 ※_iam_bindingと_iam_memberは一緒に使える

google_bigquery_dataset_iam_binding:(承認済みビューの権限はなくなる>google_bigquery_dataset_accessを使え)
google_bigquery_dataset_iam_member:roleとmemberを1対1でresourceを作りまくる、Non-authoritative
 ※_iam_policyや_bindingはまとめ易そうだが権限消しそう

google_bigquery_dataset_iam_memberでもAuthorized viewをはがしてしまう。
Authorized viewを使っている個所は google_bigquery_dataset_access あるいは google_bigquery_dataset の access フィールドを使う。

Terraform で GCP のサービスアカウントを管理する - Eng (なりたい) (hatenablog.com)
Terraform で GCP IAM 設定どれ使うのがいいのか - pokutuna (scrapbox.io)
google_project_iam | Resources | hashicorp/google | Terraform Registry
Authoritative: TFに明示していないものをApply時に削除しますという意、TFの権威
Non-authoritative: TFは権威を示さず、TFに明示していないものは現状維持ですという意

■勝手に公開
terraform vpc auto_create_subnetworks = falseにせなサブネットを公開して作りよる
Cloud sqlのtfファイルに記述がなくてもtf stateにはPWが出てしまう>tf化したくない

■Applyの依存関係はdepends_on(プロジェクト作成の前に権限を付与しようとしてエラー等の順序)
[Terraform]Module間の値の受け渡しについて | DevelopersIO (classmethod.jp)
 これより先にあれをTFしてくれという記述

■データセット
google_bigquery_dataset | Resources | hashicorp/google | Terraform Registry
スキーマ取得: bq show --schema --format=prettyjson bangboo-prj:test-dataset.tbl001
ビューはコンソール>BQ>該当ビュー>detailからコピー

■組織ポリシー
google_organization_policy | Resources | hashicorp/google | Terraform Registry
制約について  |  Resource Manager のドキュメント  |  Google Cloud

■parallelismで早くなるかもしれない
あなたのterraform planを手軽に高速化する(かもしれない)魔法の言葉 - Qiita
シェル変数を設定、確認cmdは printenv
export TF_CLI_ARGS_plan="--parallelism=50"
export TF_CLI_ARGS_apply="$TF_CLI_ARGS_plan"

■テスト
TF Apply後には検証をしっかりしたい、最低Apply後にPlanを再実行したい、テストスクリプト的にチェックしたい
適応されていないことや、TF定義とtfstateと実設定の差分が想定と違うことがある感じがするからだ
moduleを含めて条件的な書き方だと、適応の順序の関係で適応が抜け2回以上TF applyしないといけなかったり

■TFファイルを分割し部分的に別環境へTFファイルを移行したい
tf stateファイルを新環境用にコピー
TFファイルを分割:現行の部分的に削除したTFファイル、と新環境用のTFファイルを準備
tf stateから不要部分を削除
 terrafrom state rm {{asset}}
terrafrom planで差分がないことを確認
新環境用にコピーしたtf stateファイルを編集し準備
 下の terraform state push xxx.tfstate で変更された状態をtf stateファイルに書き戻すことができる?
 このコマンドを実行する前に必要に応じて terraform state pull で最新の状態を取得?
 ダメなら terraform state rm で不要分を削る
新環境用にtfファイルを準備
新環境で下記を実行
 terraform init
 terraform state push xxx.tfstate
 terraform planで差分がないことを確認

■GCP権限(メールの変名時)
GCPはGWS gmailメールの変名に追従して権限も付与状態も変化がない
しかしterraformは追従しないためtfファイルで使っている場合は変更する

■gcloud cmd
https://www.devsamurai.com/ja/gcp-terraform-101/
 gcloud projects list 権限あるプロジェクトを表示
 gcloud config set project [prjID] ワーキングプロジェクトの設定
 gcloud services enable iam.googleapis.com サービスの有効化
 gcloud iam service-accounts create terraform-serviceaccount \
  --display-name "Account for Terraform" サービスアカウント作成
 gcloud projects add-iam-policy-binding [PROJECT_ID]
  --member serviceAccount:terraform-serviceaccount@[PROJECT_ID].iam.gserviceaccount.com --role roles/editor 権限付与
 gcloud iam service-accounts keys create path_to_save/account.json
  --iam-account terraform-serviceaccount@[PROJECT_ID].iam.gserviceaccount.com クレデン発行
 export GOOGLE_CLOUD_KEYFILE_JSON=path_to/account.json クレデン設定
↑サービスアカウントで認証 環境変数にファイルパスを渡す
 gcloud auth application-default login だと個人
 これにクレデンシャルファイルのパスを渡すとサービスアカウントでgcloudコマンド打てるはず

Terraformで複数リージョンをまたいだリソース制御する (mosuke.tech)
Terraform workspaceを利用して環境毎のリソース名の変更を行う (mosuke.tech)


End

Posted by funa : 10:14 PM | Web | Comment (0) | Trackback (0)


April 2, 2021

Linux cmd2
■プロキシを入れないとアクセスできない、が同セグメントは不要なためno proxy設定する
Linuxの場合
export http_proxy=http://proxy:3128
export https_proxy=http://proxy:3128
export no_proxy=localhost,127.0.0.1,.in-xxx.com
コマンドプロンプト
set http_proxy=http://proxy:3128
set https_proxy=http://proxy:3128
set no_proxy=localhost,127.0.0.1,in-xxx.com
PowerShell
$env:http_proxy="http://proxy:3128"
$env:https_proxy="http://proxy:3128"
$env:no_proxy="localhost,127.0.0.1,in-xxx.com"

■ncコマンドでプロキシ確認
 自分の環境から環境用のproxy に接続できるかどうか?
apt install netcat-openbsd
nc-vz. proxy 3128
でプロキシ確認
nc-vz 127.0.0.1 20-100
自分自身に対してTCP20~100番ポートをスキャンし成功するとsucceed!!
 cnc-likすると簡易的に好きなポートでサーバーを起動できる
特定のボートの疎通確認などに
nc-lk 8000
-l オプション:サーバーモードで指定したポートで接続を待ち受ける
特権ポート (0-1023)までは、名前の通り特権が無いと、コマンドが通らない
-kオプション:接続が終了してもプロセスを終了せず継続し新しい接続を待ち受ける
レスポンスのデータを見たいなら、python モジュール等で
python3-mhttp.server 8080

■LDAP mgrとLDAP
LDAP managerは製品名で個人ユーザと所属グループが管理される。
製品概要 | 国産統合ID管理パッケージソフト「LDAP Manager」
OpenLdapはLinuxでよくつかわれているディレクトリサービス (ID管理)
OpenLDAP で理解するディレクトリサービス入門 | ほげほげテクノロジー

■sudoers について
どのユーザやグループがどのsudo コマンドを利用することができるのかの定義の記載があり、ユーザとグループの設定で権限を制御
どのユーザがどのsudo コマンドを利用することができるのか $sudo -l
idコマンドで自分の所属サブグループを確認 $id

元のページ
/// BANGBOO BLOG /// - Linux cmd

Posted by funa : 01:00 AM | Web | Comment (0) | Trackback (0)


April 2, 2021

Linux cmd
■Linux terminal
tabで入力補完
↑↓で入力履歴呼び出し
^qはCtrl+qを押すという意味
半角/全角キー 日本語を切り替える(画面右上にもIMEがある、win+spaceの場合も)
ls -la ディレクトリ内を表示
ls -a 隠しファイルを含み表示
 (GUI)ctl+h 隠しファイルを表示(メニューでもチェックで可)
pwd 現ワーク中のディレクトリを表示
cd ../ 上に上がる
clear 表示内容を消す
mv beforeName.text afterName.txt ファイル名変更
rm -R ディレクトリ名 削除、ファイルはrm a.txt
ls -l > hoge.txt >結果を上書き
ls -l >> hoge.txt >>結果を追記
printenv 環境変数表示 printenv xで特定表示
grep aaa -rl ./ カレントディレクトリ以下からファイル内にaaaが含まれるファイルを検索
grep -R $keyword *.py .pyファイルからkeywordを検索
sudo - 一般ユーザが特権操作する sudo省略
sudo -i rootに切り替える
sudo -iu <username> 特権ユーザ切り替え

テキスト選択
 Shift↑or↓ で行全体
 home(+fn)で行頭、end(+fn)で行末移動

nano text.txt 作成あるいは開く、nano簡単かも、画面下コマンドでctrl+?すればいい
 コマンドM-UはEsc+u
 ctrl+k で1行削除

$()
ドル記号と括弧で囲んだコマンドは実行結果を出力し展開
echo "現在のディレクトリは、$(basename $(pwd))です"

パッククォートは囲った中身をコマンドとして実行しその結果を出力
echo "今日は、`date +%m月%d日`です。"

変数と$()とバッククォートを使ってワンライナー
【shell/bash】変数代入で``や$()の使う場面を忘れた時に見る記法まとめ (zenn.dev)

■viエディタ
sudo apt install vim
vi text.txt ファイル作成あるいは開く
 viは2つ+αのモード
 ┣コマンドモード
 ┃┗コロンモード(exモード:祖先のラインエディタ)
 ┗入力モード
 https://docs.oracle.com/cd/E19253-01/816-3946/editorvi-5/index.html
 viのコロンモードコロンモードのコマンドは、このw、q、q!、x、$5... - Yahoo!知恵袋
Escでコマンドへ抜ける
 ┗挿入 i (入力モード)
ファイル名を指定し保存 :w new_file_name.txt
強制保存のコマンド :w!
保存せず終了 :q 強制終了 :q!
:10 10行目に移動
:set number 行数を表示
:num 現在のカーソル位置行数を表示
クリップボードをペースト iで挿入モードに入り Shift+Insert
vi内でコピペ:yコマンドのコピー、pコマンドのペーストなので下記の様にする
 2yw ならカーソルから2単語コピーされます
 3yl ならカーソルから3文字コピーされます
 y$ ならカーソルから行末までコピーされます
 p ならカーソルの後ろにペーストされます
$ カーソルを行末へ
G カーソルを最終行行頭へ
- 前行の行頭へ
Enter 次行の行頭へ
w カーソルを1語進める
b カーソルを1語戻す
Ctrl-d 1/2画面下へ(down)
Ctrl-u 1/2画面上へ(up)
Ctrl-f 1画面下へ(foward)
Ctrl-b 1画面上へ(back)
/文字列(Enter要) 文字列検索(スラッシュ)
 ┣n 次の検索文字列へ
 ┗N 前の検索文字列へ 保存して終了 :wq 保存して強制終了 :wq!
コマンド集 viコマンド集 (ritsumei.ac.jp)
カーソル移動 viでのカーソル移動方法を一通りまとめました (eng-entrance.com)
検索 【初心者向け】viでの文字列の検索方法を一通り (eng-entrance.com)

■環境変数は下記の順で探す、なので必要なら下位のものを上にコピー
~/.bash_profile
~/.bash_login
~/.profile
source ~/.bash_profile 編集したbashrcをbash_profileに反映させる
 bashrcはbash起動毎、bash_profileはログイン毎

■SSHの設定
Linuxコマンド【 ssh-keygen 】認証用の鍵を生成 - Linux入門 - Webkaru
$ ssh-keygen
パスフレーズは空でも設定上は問題ないが塩っ気が足らん気が
秘密鍵(id_rsa)と公開鍵(id_rsa.pub)が生成され、ホームディレクトリに作成される
 /home/yourID/.ssh/id_rsa
 /home/yourID/.ssh/id_rsa.pub.
公開鍵をSSHサーバや外部サービスに登録する等して使う、秘密鍵は明かさないこと

SSHクライアントのproxy越えの設定方法 (mydns.jp)
プロキシbinのインスコ
$ sudo apt-get install connect-proxy
ホームにsshキーができているので
$ vi ~/.ssh/config
Host oketsu
HostName 1.XXX.XXX.XXX
User hoge
IdentityFile ~/.ssh/id_rsa.pub
        LocalForward 5912 localhost:5902
ProxyCommand connect-proxy -H proxy.syanai.in:8022 %h %p
Host github.com
HostName ssh.github.com
Port 443
IdentityFile ~/.ssh/id_rsa.pub
ProxyCommand connect-proxy -H proxy.syanai.in:3128 %h %p
User githoge
$ chmod 600 .ssh/config
下記のように実行すると、ログイン/GITできます。
$ ssh oketsu
$ git clone githoge@github.com:kusogitry.git
$ id 所属グループ等を表示
$ uname -n;id;date

■NW設定
/etc/resolve.conf
 nameserver 88.88.88.88
~/.profile とか .bashrc とか
  export http_proxy=http://proxy/3128
/etc/apt/apt.conf
ip addr

  OSI参照モデル
レイヤー名称(日本語)主な役割主なプロトコル・規格
レイヤー7アプリケーション層アプリケーションごとの固有の通信規定HTTP / SMTP
レイヤー6プレゼンテーション層文字コードやデータ形式など、情報の表現方法を規定MIME / SSL
レイヤー5セッション層通信の開始・維持・終了など、通信セッションの管理ソケット
レイヤー4トランスポート層データ転送の信頼性や誤り訂正などを規定TCP / UDP
レイヤー3ネットワーク層異なるネットワーク間の通信方法を規定IP / ICMP
レイヤー2データリンク層同一ネットワーク内での通信規定Ethernet / PPP
レイヤー1物理層ビット列を電気信号など物理的な信号に変換する規定1000BASE-T / 802.11

プライベートIPアドレスのクラス分け
クラスアドレス範囲CIDR表記
クラスA10.0.0.0 ~ 10.255.255.25510.0.0.0/8
クラスB172.16.0.0 ~ 172.31.255.255172.16.0.0/12
クラスC192.168.0.0 ~ 192.168.255.255192.168.0.0/16

■スクリプト実行
nohup python3 main.py & ユーザディレクトリにnohup.outログが実行完了時に一度に保存される(重いと思われる)
nohup python3 main.py > /dev/null 2>&1 & ログなし
 nohupはバックグラウンド実行、ログアウトしても実行続ける
jobs ジョブリストを出す
fg ジョブ番号 フォアグラウンド実行に変える
bg ジョブ番号 バックグラウンド実行に変える
ctrl c キャンセル
ctrl z 中断(再開できる)
crontab -e 編集
crontab -l 確認
sudo service cron restart 再起動
systemctl status cron 稼働の確認
30 12 * * 0 python3 /home/app_hoge/main.py
 cronはバックグラウンド実行でnohup &を含めると実行されない、多分
top プロセス/CPU/メモリ等の情報、こちらで動いていればpsのstatがsでも問題ない、多分
ps aux
ps f -A プロセスをツリーで表示し便利
kill -l
kill -SIGCONT プロセス番号
sudo less /var/log/cron.log
sudo tail -f /var/log/cron.log
sudo less /var/log/syslog
sudo tail -f /var/log/syslog

■ディスク系
ext4 一般的なデスクトップやファイルサーバ向け、16TBまで、ファイルシステムチェックで遅い
xfs 高負荷IOで大容量データ処理向け、ジャーナルなし、ファイルシステムチェックを短縮
論理ディスク=パーティション
/dev/sda1, /dev/sda2, /dev/sdb, /dev/sdf等、数字はパーティション番号、数字がないとパーティション1つだけ

ディスク拡張
lsblk
df -Th
du -sk * | sort -nr

#xfsの場合
pvdisplay
pvresize /dev/nvm
vgdisplay
lvdisplay
lvextend -l +100%FREE /dev/vg001/lv001
xfs_growfs /opt

#ext4の場合
apt autoclean キャッシュあるがインストールされていないdebファイル削除
apt autoremove 必要なくなったパッケージ削除
disk -l /dev/nvm パーティション情報
growpart /dev/nvm 1 指定パーティションの容量拡張
resize2fs /dev/nvm ファイルシステム拡張

容量調整
/var/cache はapt-get clean, yum cleanで消す程度で

■swapをrootからvarに移動
free
swapon -a
swapを無効化
swapoff -v /swap.extended
swapをvarに移動
mv /swap.extended /var
/etc/fstabからswapのエントリを/varに書き換え
cat /etc/fstab
swapを有効化
swapon -a
確認
free -h

■ライブラリアップデート
sudo apt update
apt list --upgradable | grep mysql
sudo apt install mysql-client=6.6.6-0ubuntu2.1~99.99.9
sudo apt install mysql-client-core=6.6.6-0ubuntu2.1~99.99.9

dpkg-l | grep mysql

■WSL2
https://qiita.com/zakoken/items/61141df6aeae9e3f8e36
https://qiita.com/SAITO_Keita/items/148f794a5b358e5cb87b
WSLインストール後はネットワークの設定が必要なら
例) apt updateが出来ない
WSL のバージョンはユーザの設定依存のため、version 2 (WSL2) が必要ならコマ ンドプロンプトで以下のコマンドを実行
wsl --set-default-version 2
アプリからWSL起動、CMDやPowershellならwslで起動 wsl --shutdown で停止 設定したユーザディレクトリにアクセスする(それぞれ別の場所)
• WSLからは /mnt/c -> /mnt/c/Users/ore/Desktop/github
• WINからは \\ws/$ -> \\wsl.localhost\Ubuntu-22.04\home\ore
NW設定: WSL2のデフォルトでは起動するたびにWindowsホストのDNS設定を基にして自動的に/etc/resolv.conf を生成するが、サーチリストはWindows側から引き継がれないうえ、意図しないタイミングで勝手に再生成されてしまうので停止する
nano/etc/wsl.conf
下記追記
[network]
generate ResolvConf = false
DNS設定
sudo unlink /etc/resolv.conf
sudo nano /etc/resolv.conf
以下のように設定
nameserver 172.27.117.yy
nameserver 172.27.117.xx
search in-xxx.com dns search list.xxx.com
proxy設定
nano-/profile
以下の設定を既存プロキシの下に追加
export http_proxy="http://proxy:3128"
export https_proxy="http://proxy:3128"
apt の proxy 設定
sudo /etc/apt/apt.conf
以下のように設定
Acquire: http: Proxy "http://proxy:3128",
Acquire: https: Proxy "http://proxy:3128";
WSL2を抜け、WindowsコマンドプロンプトでUbuntu を再起動
ore@unco-017:/mnt/c/Users/ore$ exit

rootでキーを作成するとgithub上でユーザがrootとなる
sudo adduser aaa
sudo usermod -aG sudo aaa
sudo nano /etc/wsl.conf 下記を追記しwsl再起動
whoami
[user]
default-aaa
echo $HOME
cd-
mkdir.ssh
ssh-keygen sudoだとgithubログイン時に名前がrootになってしまう
/home/aaa/.ssh/id_rsa
cd- /home/aaa
nano/home/aaa/.ssh/config
Host github.com
HostName ssh.github.com
Port 443
ProxyCommand connect-proxy -H proxy:3128 %h %p
user git
chmod 600 config
eval "$(ssh-agent-s) sshエージェント起動
ssh-add/home/aaa/.ssh/id_rsa sshエージェントに鍵を登録
ssh-add確認
初回は接続yesをして Warning: Permanently added (ssh.github.com): 443 (ED25519) to the list of known hosts.

wal-d Ubuntu-22.04 -u root パワシェルでrootユーザに切り替える場合
wal.exe-shutdown パワシェルでシャットダウンや再起動の場合

パッケージの更新
sudo apt update && sudo apt upgrade -y
WSL環境設定
cd /home/ore
は/rootを表す(/homeでない)
sudo apt install connect-proxy
/rootにキーを生成
ssh-keygen
passphrase xxXX
cat /root/.ssh/id_rsa
nano/root/.ssh/config
Host github.com
HostName ssh.github.com
Port 443
ProxyCommand connect-proxy -H proxy: 3128 %h %p
user omeco
chmod 600 config
シンボリックリンクを生成する
cd /home/ore
In-s-/ssh
Githubサイトのユーザ設定でpub keyを登録し、承認する
cd /mnt/c/Users/ore/Desktop/github
git clone git@github.com:oreore/xxx.git
ping github.com で通信確認ができる

curl https://sdk.cloud.google.com | bash
exec -1 $SHELL
gcloud auth application-default login
URLコピペ
gcloud config configurations list
gcloud config configurations create kuso
gcloud config set account xxx@xxx.com
gcloud config set project project-x
gcloud config configurations activate kuso
gcloud auth login
pyenv install 3.13.0
pipenv-python 3.13.0
gcloud components update
gcloud components install cbt(BigTable例)
(パスフレーズを省略できる) eval $(ssh-agent); ssh-add-/.ssh/id_rsa
tfenvをマニュアルインストール https://github.com/tfutils/tfenv
tfeny install 1.00.0
tfenv list
tfenv use 1.00.0
export TF_CLI_ARGS_plan="-parallelism=50"
export TF_CLI_ARGS_apply="$TF_CLI_ARGS_plan"
環境変数を変更した場合は source ~/.bash_profile を反映

■SPF
spfレコードはメールを送信する際、送信元サーバとDNS上のIPアドレスを比較
自社から取引先に送信したメールにSPFレコードを設定していなければ、相手側のメールサーバで迷惑メールとされ届かない場合も

送信元のDNSに送信元IPをSPFレコードに登録する(ドメインをSMTPのIPに変える?
ドメイン IN TXT v=spf1 ip4:172.16.0.1 -all
(+が省略されているがIP許可、allを認証しないという意味)
送信側SMTPサーバではSPFをチェックせず何でも送信

受信側MTAにて設定され(SMTPにはトランスファのMTA、デリバリのMDA
spfを使えば先方がspfレコードを登録していなければメールが受け取れない
postfixやeximのSPFをonにする設定がある

spfレコードが設定されているかを確認
nsookup -type=TXT 調べたいドメイン

■lsofはオープンファイルの略だがネットワークソケットの調査
lsofでファイルを開いているプログラムを特定する | 晴耕雨読 (tex2e.github.io)
lsofコマンド入門 #Linux - Qiita

=============
■VS code
マルチカーソル:ctrl+shift+↓
[Alt]+クリックカーソルを追加
[Ctrl]+[Alt]+[↑]/[↓]カーソルを上下に追加
[Ctrl]+[U]カーソル操作を元に戻す
[Shift]+[Alt]+[I]カーソルを行末に追加
[Ctrl]+[L]行を選択
[Ctrl]+[Shift]+[L]選択中の文字列と同じものをすべて選択
[Ctrl]+[F2]カーソル位置の単語と同じものををすべて選択
[Shift]+[Alt]+[→]選択範囲の拡大
[Shift]+[Alt]+[←]選択範囲の縮小
[Shift]+[Alt]+ドラッグ矩形選択
[Ctrl]+[Alt]+[Shift]+[カーソル]矩形選択
[Ctrl]+[Alt]+[Shift]+[PgUp]/[PgDn]矩形選択 ページ上下
VSCodeのマルチカーソル練習帳 - Qiita
マルチカーソルを使わないVSCodeはただのVSCodeだ!〜解説編〜 - memo_md (hateblo.jp)

続き
/// BANGBOO BLOG /// - Linux cmd2

Posted by funa : 12:00 AM | Web | Comment (0) | Trackback (0)


March 9, 2021

Treachery

:||

2021/4/25に気づいた、ハニーちゃんおめでとうとありがとう、エピソードは今度どこかで

Posted by funa : 11:39 PM | Column | Comment (0) | Trackback (0)


March 6, 2021

ZERO

値段と糖質とプリン体と度数、モノによっては明らかに太る感じがしない、ゆって0じゃ無い安酒でも糖質15g位らしいので良いのがなければいつものでいいかも。それより現像ができない!!→LightRoom再インスコ→LRよりSony謹製の方が色が良かった→元画像が暗すぎが理由→LRでノイズを追加調整(元画像に注意、14mmf1.8の使い道がなく勿体ない、マクロとして物撮りしたい感じがあるがマクロは70-200の方がええし、14は人物用だな)

極ZERO: 138/0/0/5 ちょい高、不味い、5%で軽いが酔えなくはない、太る感じ×
Asahi Off: 118/0/0/3-4 酔えない、ノンアルの亜種かフルーティで旨い〇
のどごしZERO: 118/0/0/4 フルーティで旨い、軽いが酔えなくはない〇
贅沢ZERO: 118/0/x/6 プリン有 6%で嬉しいが雑味がすごくある気が▲
バーリアル糖質50%off緑: 85/5-10/?/4 かるくない、そもそもZEROでないが旨い◯+
氷結ZEROレモン: 108/0/0/5  レモンが強く旨い、飲みやすい◎
鏡月焼酎ハイ: 98/0/0/7 スッキリ高アルコール度で満足感、ドライが好きかも◯+
いいちんこ下町のハイボール: 168/0/0/7 高ぇ、重い感じがする▲
パーフェクトサントリービール: 168/0/x/5.5 高ぇ、旨い〇
 →氷結Zeroレモン>鏡月ドライのコンボが強い

イオン麻婆豆腐辛口(肉付)vs丸美屋辛口(花椒なし):丸は味穏やか、Aは塩と肉多い
 →Aeonのとろみ入れるの減らす、甘口は邪魔甘さで、中辛が一番いい
イオン四川式(肉無)vs丸美屋大辛(花椒付):Aは高いし辛い、お口は甘め好きda
 冷食が新しくなった、Palmボックスは忘れて何度か買ったが小さい
バターよりマーガリンの方が健康的になったらしい
 小岩井ヘルシー仕立てか、明治コーンソフトは近くで買えるが




ノンアルはどうなのか?飲み比べる、ジンジャエールよりいいか

キリンGreen's free 旨い、ノンアルならビールが良さそうで、ノンアルビールならこれでは?
Suntoryのんある酒場レモンサワー 酸っぱい、旨い(メシが進む感じはしない
Takara辛口ゼロボール スッキリしているが何か不味いので逆に酒感あり旨い
AsahiStyleBalanceハイボール まじウィスキー、旨い(メシが進む感じはしない
トップバリューホワイトサワー カルピスソーダでノンアルの意味なし
トップバリューBeerTaste スッキリ旨いが軽くハレ感が少ない

Suntoryノンアル気分カシスオレンジ 旨い、大人のジュース感
ワイン チェリオ
ジントニック ジントニック
檸檬堂

「カルト」はすぐ隣に: オウムに引き寄せられた若者たち (岩波ジュニア新書) | 紹子, 江川 |本 | 通販 | Amazon
霊的体験は飲み物にLSDを入れていたとなっている、まぁ殆どコレで教祖になれる

Posted by funa : 01:43 PM | Column | Comment (0) | Trackback (0)


February 22, 2021

BigQuery part2
■BQタイムアウトは6時間
クエリそのままパフォーマンスを改善 BigQuery パフォーマンス向上テクニック

■BQ transfer(クエリが不要なBQ連携、3rd partyもあり)
データセットコピー、GCSファイル
Ama S3, Azure storage, Oracle, Salesforce, Ads系等々

■Cloud SQLにBQからクエリ
SELECT * FROM EXTERNAL_QUERY("connection_name", "SELECT * FROM db.tbl")
https://zenn.dev/ykdev/articles/4a4d2fbc6b4fe1

■BQ DMLクォータ超過
割とSQLだとすぐに壁にあたる
上限がテーブル単位のためテーブル名を分けると回避できるらしい
BQ streaming insert->BQ storage read/write APIの上限はDMLと別で、閾値が大きい

APIだとProtocol buffersが必要で、Date/Timestampが対応しておらず
Unixエポックからの日数/秒数への変換が必要、、、

■マテリアライズドビュー
実体データを保持しリフレッシュ更新で早いため集計等に向く
ベーステーブルは一つ、カウントができない、使用できない関数がある等の制約がある
またマテビューはビューを元に作成できずテーブルからである必要がある
ストレージコストは掛かるが、通常ビューで時間掛かる計算を頻繁にする場合は早く安くなる可能性がある
BigQueryのMaterialized Viewを使う #データ分析 - Qiita

■BQ同時実行数
オンデマンドでは使用可能なスロット数に基づき自動的に同時実行数が決定され超えるとスロットに 空きがでるまでキューに保管される
プロジェクトごとにクエリの最大同時実行数は動的に決まる
同時実行数の最大値は指定できるが、大きくしても実行数が増えることはなく、あくまで自動決定 内の方が優先される
Editionsが割り当てられているプロジェクトでは最大同時実行数を明示的に設定できる
他に、インタラクティブクエリ、バッチクエリ、クエリ順序や上限など

■BigQueryの列レベル・行レベルのセキュリティ
個人情報や機微情報を隠す
BigQuery の行レベルのセキュリティの概要  |  Google Cloud
行レベルなら同じテーブルを使うので同じダッシュボード/Appが使える(AuthorizedViewの方が柔軟だが)
データ マスキングの概要  |  BigQuery  |  Google Cloud
列レベルアクセス権以外にもマスクの種類があり、ハッシュだったり先頭4文字や末尾4文字等で共通文字化としてマスク化できる
BQ画面>左ナビのポリシータグ
 ポリシータグを作成(組織単位で一括一覧表示)
  タグは階層化できるので、全ユーザタグ>管理者タグ>社長タグ
 スキーマ>Addポリシータグ
  タグが付いていればプレビューで見れない
  select * except(tag_column)にする必要がある
  メタデータは見れる(カラム名、型
 ポリシータグ画面>対象ポリシー選択>情報パネルで権限者一覧
  fine-grained readerを付与するとselect *ができるようになる
   社長タグに社長だけ権限付ける等
※APIを有効にし、ポリシーを有効にする必要がある

■承認済みビュー authorized view
authorized viewを設定するとそのviewを対象とする権限だけ必要で権限をさかのぼり付与しなくていい(通常のviewは参照元の権限も必要)
 この権限移譲は閲覧権限のみで編集権限等は含まない
被参照の元テーブル側に許可するview名を設定する
 参照権限は緩くなるが、編集権限は厳しくなる(設定するビューは変更しない前提で承認する形)
authorized viewを付与すると玄関となったビューはdataEditorではビュー更新ができなくなる
 ソーステーブルにもdataOwnerが必要(通常のビュー作成にはdataViewerがソースに必要)
 基本の安全策はauthorized view設定を外す>ビュー変更>AV再設定がいい
  対象のAVは管理者を立て一元管理するのが良さそう
  (テーブルやビューを作って権限付与してバッチだとdata ownerが必要なのは注意)

■Authorized系にはメリットとデメリット
1) Authorized viewを設定するメリット
一度設定してしまえばソース側への権限付与依頼が不要となりビューの権限管理が省力化できる
ビューにて閲覧対象を絞ることができソース全体は閲覧させないことができる、絞れる
 普通のビューは元データへの権限が必要で見せたくないデータへも権限が必要になる場合がある

2) Authorized viewを設定するデメリット
一度設定してしまえばソース側での権限付与依頼が不要となり被参照側で許可不許可の判断ができなくなる、誰にデータ閲覧権限を付与しているか把握できず管理が機能しなくなる一面がある
将来に置かれるソース側のデータの閲覧も許可することになり不用意に閲覧が可能となってしまう
terraformでAuthorized view設定が剥がれてしまう危険性
ビューを編集するにあたりAuthorized viewを外す必要がある、あるいはソースにもEditor権限
 すぐにビューを変更することができなくなる(ビューを一旦削除することはできる)
Authorized viewはビューを削除して、再度作り直すと生きている場合がある、ダメな場合も多いが
 これで漏洩させたくない情報を一時含められる危険性がある
3)authorized datasetを設定するデメリット
設定時は良いかもしれないが、将来的に意図しないデータがDS入った場合も閲覧を許してしまう

データセットは細かく作成してアクセスレベル設定し普通のビューを使う
ソース全体を閲覧させられない場合(直接権限を付与できない場合)にAVを使うメリットがでる
 情報漏洩リスクはどちらも多段ビューで同じ感じ、だがビュー作成でAV設定が生きているバグがデカい

■BQクリーンルーム
データ準備側でパブリックし、使う側でサブスクする (BQ exploreでペインでAddする)
スプシ保存できない、開覧数のレポートが見れる(使用者名は見えない) 実はパブ側でサブスクし公開すれば、閲覧とJobUserだけで使用できるようになる
GAでなく、またオンデマンドしか無理、コピペやデータコネクタは可能で残念

■ロール割り当て者の出力
カスタムロールのProject_Admin、Project_Managerが誰に割り当てられているか
Asset inventoryをBQにダンプしたデータからクエリする
WITH
  projects AS (
    SELECT
      resource.data AS rsc,
      ancestor_path
    FROM
      prj.cloud_asset_inventory.cloud_asset_inventory_org_resource_now
    WHERE
      asset_type = 'cloudresourcemanager.googleapis.com/Project'
  ),
  projects_info AS (
    SELECT
      JSON_EXTRACT_SCALAR(rsc, '$.projectId') AS projectid,
      JSON_EXTRACT_SCALAR(rsc, '$.lifecycleState') AS lifecycleState,
      ancestor_path
    FROM
      projects
  ),
  projects_efficient AS (
    SELECT
      *
    FROM
      projects_info
    WHERE
      NOT REGEXP_CONTAINS(ancestor_path, "folders/apps-script")
  ),
  projects_num_adm_mgr AS (
    SELECT
      REPLACE(name, '//cloudresourcemanager.googleapis.com/projects/', '') AS project_num,
      REPLACE(b.role, 'organizations/1234567/roles/', '') AS role_value,
      STRING_AGG(REPLACE(m, 'user:', ''), ', ') AS member_value
    FROM
      prj.cloud_asset_inventory.cloud_asset_inventory_org_iam_policy_now,
      UNNEST(iam_policy.bindings) AS b,
      UNNEST(b.members) AS m
    WHERE
      asset_type = 'cloudresourcemanager.googleapis.com/Project'
      AND (role LIKE '%Project_Admin%' OR role LIKE '%Project_Manager%')
    GROUP BY
      project_num,
      role_value
  ),
  projects_adm_mgr AS (
    SELECT
      JSON_EXTRACT_SCALAR(resource.data, '$.projectId') AS project,
      projects_num_adm_mgr.role_value,
      projects_num_adm_mgr.member_value
    FROM
      projects_num_adm_mgr
    LEFT JOIN
      prj.cloud_asset_inventory.cloud_asset_inventory_org_resource_now AS res
    ON
      projects_num_adm_mgr.project_num = REPLACE(res.name, '//cloudresourcemanager.googleapis.com/projects/', '')
  )
SELECT
  projects_efficient.projectid,
  projects_efficient.lifecycleState,
  CONCAT(projects_efficient.projectid, ', ', projects_adm_mgr.role_value) AS role_value,
  projects_adm_mgr.member_value
FROM
  projects_efficient
LEFT OUTER JOIN
  projects_adm_mgr
ON
  projects_efficient.projectid = projects_adm_mgr.project
ORDER BY
  lifecycleState DESC,
  projectid;

■BigQuery DataFrames + Geminiでデータ分析
from google.cloud import bigquery
from google.generativeai import GenerativeModel

bq_client = bigquery.Client()

# クエリ実行してDataFrame取得
query = "SELECT customer_review FROM `my_project.my_dataset.reviews` LIMIT 10"
df = bq_client.query(query).to_dataframe()

# Geminiモデルの準備
model = GenerativeModel("gemini-pro")

summaries = []
for review in df["customer_review"]:
    response = model.generate_content(f"次のレビューを要約してください: {review}")
    summaries.append(response.candidates[0].text)  # 修正: 正しくレスポンスを取得

# DataFrameに要約を追加
df["summary"] = summaries

table_id = "my_project.my_dataset.review_summaries"
job = bq_client.load_table_from_dataframe(df, table_id)
job.result()
print("データをBigQueryに保存しました!")


■BigQuery ML (bqml_llm_infer) + Geminiで感情分析
from google.cloud import bigquery
bq_client = bigquery.Client()

# クエリ実行してDataFrame取得
query = """
SELECT 
  bqml_llm_infer(
    model_name => 'my_project.my_dataset.gemini_model', 
    prompt => CONCAT('このレビューの感情分析をしてください: ', customer_review)
  ) AS sentiment_analysis
FROM `my_project.my_dataset.reviews`
LIMIT 10
"""
df = bq_client.query(query).to_dataframe()
print(df)


■IAM(Identity and Access Management)

前回
/// BANGBOO BLOG /// - BigQuery

Posted by funa : 12:00 AM | Web | Comment (0) | Trackback (0)


February 21, 2021

BigQuery
■Big queryリファレンス
標準SQLとレガシーSQLがある、違いは?
標準 SQL のクエリ構文  |  BigQuery  |  Google Cloud
標準 SQL への移行  |  BigQuery  |  Google Cloud
標準 SQL のデータ型  |  BigQuery  |  Google Cloud
レガシー SQL 関数と演算子  |  BigQuery  |  Google Cloud
レガシー SQL のデータ型  |  BigQuery  |  Google Cloud
BigQuery: クラウド データ ウェアハウス  |  Google Cloud(チュートリアルみたいな) 

BigQuery解説:https://beyondjapan.com/blog/2016/03/what-is-bigquery/
クエリ処理のツリーアーキテクチャによる分散並列処理
複数のサーバーに対してツリー状に拡がっていき、並列にサーバー上で同時に分散処理
 ルートサーバ>intermediateサーバ>leafサーバ
BigQuery MLという機能を利用すると、機械学習モデルをCloud AI PlatformのTensorFlowなどに連携させ、クエリ結果を素早くAIと連携
Lookerというデータ分析プラットフォームとの連携よりクエリ結果を、データ統合、変換、分析、可視化、レポーティングすることができ、非常に強力なBI

列指向型・カラム型データベース・カラムナストレージ(一般的なRDBMSでは行単位でデータが保存)
 必要なカラムのデータを取得するだけでよく、またデータは圧縮できる
https://dev.classmethod.jp/articles/google-bigquery-debut/

GCPプロジェクト>データセット>テーブル(行row列columnで普通のテーブル、ネイティブbigqueryテーブル/Googleドライブのような外部テーブル、SQLクエリによるビュー)
 アンスコ_で始まるデータセット名は隠しでコンソールで非表示
ジョブは非同期で実行され、ステータスをポーリング(データの読み込み、データのエクスポート、データのクエリ、データのコピーなど)

クエリ(ウェブ UI、bq コマンド、BigQuery REST APIの方法がある、SQLと同じ?
SELECT   title, answer_count, view_count
 FROM  `bigquery-public-data.stackoverflow.posts_questions`
 ORDER BY  view_count DESC LIMIT 10
BigQueryはSELECT tag, time FROM [dataset_name.table_name_20151206]のように必要な列だけを選択した場合にはスキャンの幅を狭めることは可能ですが、LIMITやWHERE句には何を書いてもテーブルをフルスキャンしてしまう
節約 Amaのs3に入れRedshift内でテーブルを分割した後にBigQuery

Hadoopでも使われていたGoogle開発のエンジンであるMapReduceは、非構造化データをプログラミングモデルを通して扱うが、巨大なテーブルの結合や巨大な出力結果のエクスポートも可能である半面、処理時間は数分間から数日に及んだ、だが、BigQueryは、あらかじめデータを構造化してBigQueryのテーブルに格納しておかねばならないが、ほとんどのクエリは数秒で完了する

サードパーティ ツール(データの読み込みや視覚化を行うツールなど)を使用して BigQuery のデータにアクセス可
Google Cloud SDKをインストールすればコマンドラインが使える
BQは同一リージョンでないとJoinができない、ゾーンはマルチで良い
 BQでは us と eu がマルチリージョン
  22/4現在のリージョンリスト:asia-east1-2、asia-northeast1-3、asia-south1-2、asia-southeast1-2、australia-southeast1-2、europe-central1-2、europe-north1、europe-west1-6、northamerica-norhteast1-2、southamerica-east1、sourthamerica-west1、us-central1、us-east1-4、us-west1-4

パブリックデータに直でアクセスできる
SELECT * FROM `bigquery-public-data.usa_names.usa_1910_2013`
BigQuery の一般公開データセット  |  Google Cloud
 →FROM句の書き方:他のプロジェクトを指す名前にハイフンがあるとバッククォートで囲む必要がある
  `other-prj`.dataset.table あるいは `other-prj.dataset.table`

■標準SQL
先頭行でレガシーか宣言 #standardSQL あるいは #legacySQL
バッククォートでエスケープ、プロジェクト区切りも.(ドット)、From句のカンマはCross joinで全組合せかと思われ通常通りjoinやunionを使う事
配列が使える、カラム一つに配列を入れて多元的に扱える
withで一時テーブルを作れる
exceptでカラムを除外、replaceでカラムの置き換え
 select * except(kuso) from a
分析関数over()とwindowで計算ができる
 rank() over (order by x)は下記moreのRFMに使用している
 ROW_NUMBER() over (order by timestamp) as id,で採番できる
地理関数とかJSON関数とか色々関数もありそう
スクリプトで変数やIfやLoopが使える 標準 SQL のスクリプト  |  BigQuery  |  Google Cloud
join on a.c=b.cはjoin on using (c)とできる

BigQuery 特集: データ操作(DML) | Google Cloud 公式ブログ
insert into tbl_dest select * from tbl_source とselect結果を挿入できる

■レガシーSQL(標準SQLを使うのが由)
予約語は角かっこを使ってエスケープ、プロジェクト区切りは:
集計関数で WITHIN キーワードを使用すると、レコード内の繰り返しの値が集計?
FROM句のカンマは標準SQLのCross joinとは異なりUNION ALL 演算子
通常のSQL処理システムとは異なり、BigQueryは繰り返しデータの処理を前提として設計。繰り返しレコードの構造を操作するクエリを記述。その方法の1つが、FLATTEN 演算子?
JOINは、INNER、[FULL|RIGHT|LEFT] OUTER、および CROSS JOIN 演算子をサポート、デフォルトINNER
除外できる select + from A OMIT RECORD IF COUNT(payload.pages.page_name) <= 80;
TOP を使用するには、SELECT 句に COUNT(*) を含める
分析関数over()とwindowで計算ができる?(標準SQLと同様?)
functionを作って使える(標準SQLと同様?)
JSON等のネストをフラット化

■DDL データ定義言語ステートメントの使用  |  BigQuery  |  Google Cloud
https://www.isoroot.jp/blog/1651/
auto_incrementもdefaultもprimary keyもindexもshow create tableないのでは?
CREATE TABLE IF NOT EXISTS bangboo_data.x_xxx (
  `no` INT64 NOT NULL,
  `user_no` INT64 NOT NULL,
  `name` STRING,
  `date` DATETIME,
)

同じスキーマで作ることもできる
CREATE TABLE ore_ds.test003
 LIKE prj.ds.test001
PARTITION BY _PATITIONDATE

■bqコマンドはコンソールで実行できる
ブラウザで該当プロジェクトに入りコンソールボタン、下記ではスキーマをJSONで取得できる
bq show --schema --format=prettyjson myProject:myDataset.tbl001
bq ls -n 3000 dataset_aho (データセット内のリスト3000件、デフォ50件?)

bq cp --force prj:ds.tbl prj:ds.tbl2
上書きコピー(削除しコピー)コンソールだと同名コピーや下記ができない
bq cp ds.tbl1,ds.tbl2 ds.newtbl
2つのテーブルをnewtable にまとめコピー
bq cp -a ds.tbl2 ds.tbl1
tbl2をtbl1に追加コピー --append_table でも同じ

bq load (csvとかgcsのファイルを読み込む)
bq extract (gcsに抽出)

■データアップロード時のスキーマ指定
自動検出はFirestore、Datastore、Avro、Parquet、ORCだけ?ほぼ手動のutf-8のcsvかjsonlかを使う形
コンソールで手動スキーマ指定可(jsonスキーマを張付ける)、modeは省略可でデフォはnullable、
JSONスキーマファイルupはaqコマンドのみ可、ローカルからup時のコマンドとスキーマ例↓
bq load --source_format=CSV mydataset.mytable ./myfile.csv ./myschema.json
[
  {
    "description": "quarter",
    "mode": "REQUIRED",
    "name": "qtr",
    "type": "STRING"
  },
  {
    "description": "total sales",
    "mode": "NULLABLE",
    "name": "sales",
    "type": "FLOAT"
  }
]
なお一旦Google Cloud Storageに放り込んでからやると高速 BigQueryにデータをバッチでインポートする - Qiita

COUNT DISTINCTだが、BigQueryでは概算値が返ってくる??。正確な値が必要な場合は、GROUP EACH BYとCOUNT(*)を組み合わせる
https://www.buildinsider.net/web/bigquery/01

■BQはUTC(Universal Time, Coordinatedの頭文字)
ScheduledQueryを終了日6/9 13:00JSTで即時設定→6/9 01:20UTCで実行された
(終了時間にJST/UTCの考慮が必要か→SQ実行時間設定についてはJSTかUTCに注意するだけ)
実行履歴はUTCのためJSTに読み替える必要がある(UTCはJSTの-9時間)

■BigQuery機能
///クエリ結果を別テーブルに書き込む
その他>クエリの設定>クエリ結果の宛先テーブルを設定する
BigQueryではSELECT結果を他テーブルにInsert / テーブル洗い替えなどができる - コード日進月歩 (hateblo.jp)
クエリ結果の書き込み  |  BigQuery  |  Google Cloud

///Saved query
プロジェクトに対して保存をして使いまわす等ができる
URLでクエリを共有できる

///Federated Query
スプレッドシートやGCSの外部ソースをBigQueryで
範囲の書き方:シート1!A1:B100
Auto detectにするとHeader skipを1にして1行目をカラム名として使うといい
注意)
 シートで構成を変えると滅茶苦茶になる
 空欄のセルはnullになる
 使う人はBQへもスプレッドシートへも両方権限が必要

///パラメータ(変数)を使う
--parameter=min_count:INT64:250
SELECT word FROM `prj.ds.t` WHERE AND count >= @min_count
パラメータ化されたクエリの実行  |  BigQuery  |  Google Cloud

こういう感じでも使えるのでは
WITH params AS (
 SELECT @sheetInput AS p
),
tmp_pre_processed_src AS (
 SELECT * FROM src
)
SELECT * FROM tmp_pre_processed_src
,params
WHERE
 tmp_pre_processed_src.a = p

///*を受ける_TABLE_SUFFIXを使う(複数テーブルだとunion allになる)
SELECT year FROM `bigquery-public-data.ds.gsod19*`
WHERE _TABLE_SUFFIX BETWEEN '29' and '35'
ワイルドカード テーブルを使用した複数テーブルに対するクエリ  |  BigQuery  |  Google Cloud
 BTWで絞らないと全結合で課金が厳しいかも

 ※ワイルドカード注意
 dataset.product_*と書くとdataset.product_20190425だけでなくdataset.product_special_20190425にもヒットしてしまう

betweenは小さいから大きいで、パーティションのないシャーディングテーブル日付きつきテーブルでも行ける(From句のテーブルに動的な名前を使うにはこれか、EXE IMEDIATEくらいか?)
SELECT year FROM `bigquery-public-data.ds.gsod20*`
where _TABLE_FUFFIX between format_date('%y%m%d', date_sub(current_date("Asia/Tokyo"), interval 3 day))
 and format_date('%y%m%d', current_date("Asia/Tokyo"))

///時間のパラメータを使う
select * from mytable_{run_time-1h|"%Y%m%d"}
実行時間run_time(UTC)から1時間引いた日→mytable_20180214
クエリのスケジューリング  |  BigQuery  |  Google Cloud

///動的にテーブル名を指定してcreate table
パラメータや変数や_TABLE_FUFFIXだけでは難しい。変数はテーブル名とは解釈されない、_table_fuffixはselect分のfrom句に入れwhere句で内容を指定するがcreate分は無理、execute immediateを用いる
DECLARE t STRING;
SET t = (SELECT CONCAT('x_emp_at', FORMAT_DATE("%Y%m%d", DATE_ADD(CURRENT_DATE(), INTERVAL 1 DAY))));
EXECUTE IMMEDIATE format('CREATE OR REPLACE TABLE `%s` AS SELECT * FROM `prj.bangboo_data.x_employee`', t);

ScheduledQueryでは出力テーブルの指定が可能でテーブル指定例:table001_{run_time-1h|"%Y%m%d"}でOK、なおSQL内にはrun_timeが使用できない

//動的にSQLを作成し実行(組織レベルのメタデータを取得
DECLARE all_meta STRING;
SET all meta = (
with projects AS(
SELECT DISTINCT project_id from region-us.INFORMATION_SCHEMA.TABLE_STORAGE_BY_ORGANIZATION
WHERE project_id NOT IN ('対象外プロジェクト)
),
sql AS(
SELECT
CONCAT('select from`', project_id, "`.`region-us`.INFORMATION_SCHEMA.SCHEMATA_OPTIONS", "\nUNION DISTINCT\n') AS s FROM projects
),
concat_sql AS(
SELECT REGEXP REPLACE(STRING AGG(s, ''), '(UNIION DISTINCT+)$', '') AS concat_s
FROM sql
)
SELECT SUBSTR(concat_s, 1, LENGTH(concat_s) - 16) AS all_meta
FROM concat_sql
);
--Scheduled query化ならcreate文にする
--EXECUTE IMMEDIATE format('CREATE OR REPLACE TABLE `bq_us_all_dataset` AS %s', all meta);
EXECUTE IMMEDIATE format('%s', all_meta);

///既存のテーブルをコピー(CREATE OR REPLACE TABLEもあり)
CREATE TABLE IF NOT EXISTS bangboo_data.x_employee_copy (
  `no` INT64 NOT NULL,
  `name` STRING,
) as
select * from `prj.bangboo_data.x_employee`
データ定義言語ステートメントの使用  |  BigQuery  |  Google Cloud

///timestampとdatetime
datetime型カラムにはCURRENT_DATETIME()、timestamp型カラムにはCURRENT_TIMESTAMP()を使う
 timestampはUTC、datetimeはローカル的で地域指定ができる
 直近3分
 SELECT * FROM `aaa.ds.tbl111`
 WHERE `date` > DATETIME_SUB(CURRENT_DATETIME(), INTERVAL 3 MINUTE)

//stringとdate
func_approved_routine_a('2021-10-31') 引数がstring型
func_approved_routine_a("2021-10-31") 引数がdate型

///日付のキャスト
CAST(date AS STRING)
TIMESTAMP(DATE_SUB(CURRENT_DATE(), INTERVAL 1 month))
BigQueryのStandardSQLで日付(date, datetime, timestamp)を変換する方法 - 寝ても覚めてもこんぴうた (hatenablog.com)
Bigqueryの日時に関係する関数全部試してみた ①Date編 - Qiita

///timeで入っているものを日でサマるSQL
select
count(table_id),
sum(size_bytes),
date(record_time) as record_day
from bq_metadata
where record_time > TIMESTAMP(DATE_SUB(CURRENT_DATE(), INTERVAL 3 month))
group by record_day
order by record_day DESC

///有効期限 table expiration
データセットに対して何日間かにするか設定できる
テーブルに対し特定の日付を設定できる
 何が起こる?>データセット自体は残るが中のテーブルが無くなる

///パーティション
パーティション分割テーブルの概要  |  BigQuery  |  Google Cloud
BigQueryのStandardSQLで日付(date, datetime, timestamp)を変換する方法 - 寝ても覚めてもこんぴうた (hatenablog.com)

パーティション分割テーブルは2種類:パーティショニングとシャーディング
●シャーディングテーブル
 カラムの増減OK、スキーマとメタデータを持ち権限検証され オーバヘッド有り、ワイルドカード誤操作しやすい→保存向き
●パーティションテーブル
 クエリが早い、カラムの増減に対応できない、上限4000位→利用向き
●シャーディングテーブルにパーティション設定
 各シャーディングtblでパーティションを持たせる、特殊用途で通常どちらかで

TIMESTAMP 列とDATETIME列では、パーティションを時間単位、日単位、月単位、年単 位のいずれで
 SQで自動的にtimestampでDAYになる、SQ実行頻度から自動設定される?
ワイルドカード誤操作 *だと_fuyou_20240401等の想定外も含むため_202*にする等の考 慮が必要
シャーディングの作り方、yyyymmではダメだった、create文でテーブル名にyyyymmddを 付ける あるいはSQのテーブル名に_{run_time-2h["%Y%m%d"}等
シャーディングはテーブルごとに権限を付与が必要で日付別なら実質無理でデータセットで権限管理が必要

クラスタリング も同時に考慮したい
事前にソートし、まとまりを作っておく仕組み。
インデックスのようにカーディナリティが高いカラムを指定してあげると列指向のため全スキャンしなくて良くなる。圧縮率も上がり 保存費用も削減できる。
WHERE で指定あるいは GROUP BY される複数列をクラスタ化列として指定するが、指定の順番が重要。
まずパーティションが考慮され、次に最初にクラスタ指定した列で行がソートされ、次にその中で2番めに指定した列でソート、次に3番目...となる
CREATE TABLE ds.tbl_cls (purchase_dt DATE, prod_id STRING, prod_name STRING)
PARTITION BY purchase dt
CLUSTER BY prod_id

1)パーティショニング
BigQueryでパーティション分割テーブルを作成する - goodbyegangsterのブログ (hatenablog.com) を見よ
パーティショニングは事前に作っておくこと
上限が4000のため最大日単位で11年、時間単位で5か月くらいでpartition_expiration_daysも指定しておく事
CREATE TABLE sample.n225 ( 
  trading_day DATE NOT NULL OPTIONS(description="取引日"),
  closing_quotation NUMERIC NOT NULL OPTIONS(description="終値"),
  opening_quotation NUMERIC NOT NULL OPTIONS(description="始値"),
  high NUMERIC NOT NULL OPTIONS(description="高値"),
  low NUMERIC NOT NULL OPTIONS(description="低値")
PARTITION BY
  DATE_TRUNC(trading_day, MONTH)
OPTIONS (
  partition_expiration_days=1825,
  require_partition_filter=true,
  friendly_name="日経225時系列データ",
  description="月別パーティションされた、201901から202107までの日経225時系列データ",
  labels=[("environ", "dev")]
)

クエリはpartitioned byのヤツで絞れば良い
select * from aaa_history wehre
#ParticionIDで絞る(つーかpartitioned byのヤツで日付をキャストしてUTCをJST日付に
date(rec_time) = date(datetime_add(datetime "2000-10-10 00:00:00" interval -9 hour))
AND
#実際の時間で絞る、パーティションが日付区切りなので時間検索だけなら全件検索になる
datetime(rec_time) between datetime_add(datetime "2000-10-10 00:00:00" interval -9 hour)
 and datetime_add(datetime "2000-10-10 00:59:59" interval -9 hour)

2)シャーディング
シャーディングは_TABLE_SUFFIXを使ったり、テーブル名にハードコーディングする。
日付のキャスト select * from `task_*` where _TABLE_SUFFIX = REPLACE(CAST(date AS STRING), '-', '')

DROP TABLE `task_*`のようにワイルドカードは削除時は使えない
大量削除は下記のようにbq cmdリストを作りBashで。(Terminal貼りつけでも可)
 シャーディングはデータセット別にしてデータセットごと消すようにしたいが
Delete BigQuery tables with wildcard - Stack Overflow
select concat("bq rm --project_id prj -f -t ",table_schema,".",   table_name, ";" )
from INSERT_YOUR_DATASET_NAME.INFORMATION_SCHEMA.TABLES
where table_name like "INSERT_YOUR_TABLE_NAME_%"
order by table_name desc

シャーディングテーブルのビュー化 (Authorized view/routineの設定も必要)
■ その1(_TABLE_SUFFIXカラムが付くが、全期間取得できる)
CREATE OR REPLACE VIEW ds.tablen_snapshot_all AS
SELECT *,
_TABLE_SUFFIX AS table_suffix
FROM gcp-prj-name.ds.tablen_snapshot_**
WHERE_TABLE_SUFFIX BETWEEN '20200101' AND FORMAT_DATE('%Y%m%d',
CURRENT_DATE())
↓下記のように使用する
SELECT FROM `ds.tablen_snapshot_all
WHERE table_suffix BETWEEN '20250530' AND '20250601'
あるいは
SELECT FROM tablen_snapshot_all
WHERE table suffix = '20250601'

■その2 (テーブル関数のため単一日付のみ取得)
CREATE OR REPLACE TABLE FUNCTION ds.fn_tablen_snapshot_by_date(date_str STRING)
AS
SELECT
FROM gcp-prj-name.ds.tablen_snapshot_**
WHERE TABLE_SUFFIX = date_str;
↓下記のように使用する
SELECT FROM `ds.fn_tablen_snapshot_by_date("20250601");


削除されたテーブルは7日以内なら復元することも可能
テーブルの管理  |  BigQuery  |  Google Cloud
BQタイムトラベルで2-7日前のデータを見れる
タイムトラベルを使用した履歴データへのアクセス  |  BigQuery  |  Google Cloud

///UNNEST
UNNESTを知らないとBigQueryを使えない? | 4番は司令塔 (pep4.net)
BigqueryでUNNESTを使いこなせ!クエリ効率100% | by Eureka Engineering
ARRAY を一組の行にフラット化するには、UNNEST 演算子を使用
SELECT id, title FROM games, UNNEST(titles) AS title
idtitles
1[skyrim, fortnite]
2[atvvsmx, mario]
↓フラット化
idtitle
1skyrim
1fortnite
2atvvsmx
2mario

ただしUNNESTで指定したカラムが空の配列やNULLの場合、該当行は無くなってしまうので注意
 id=3 titles=[]やid=4 titles=NULLの時はid=3,4は引っ張れないということ

select * from unnest(['aaa', 'bbb']) as baka -> rowとして2行出る
select ['aaa', 'bbb'] as baka -> 1行目に配列として全て含まれ出る

sql - How to query multiple nested fields in Bigquery? - Stack Overflow
Unnestでもflattenができず空欄ができる場合、結局left join
 空を含むカラムはSelectに残し、repeatedのカラムはleft joinでくっつける
 VariantsをunnestしてるがPricesもrepeatedなのでleft joinのものを出している
  repeatedもarrayと同じらしいが、、、cross joinやarray_to_stringもやったが駄目だった
   なおrepeated以外はunnestが効かない
それでも駄目ならselect句の指定方法やwhere句で絞ると空欄が抜けたよ
select Productid,Variants.SKU,Variants.Size
,Prices.Currency,Prices.Country
from `ga-export-0000.feed.feed_dev`
,UNNEST (Variants) AS Variants
LEFT JOIN UNNEST(Variants.Prices) as Prices 

///ARRAY型とSTRUCT型
Arrayは上のUnnestを参照。
Structは構造体型。順序付きで親子の構造を持つ。各フィールドはデータ型(必須)とフィールド名(オプション)を持つ。

array型 unnestできる、[]なのでarray_length()で数が取れる
struct型 unnestできる、ネストを含みスキーマでrecord型と表記される、struct型の子へは.ドットで指定す
 stringでJSONはjson_extractを使う
 配列との絡みでjson_query_arrayを使う、2段階くらいは関数で対処できるがそれ以上はwith句がいい
 BigQueryでの複雑なJSON文字列の扱い方と注意点 - Qiita
 JSON functions  |  BigQuery  |  Google Cloud

CREATE TABLE IF NOT EXISTS `bangboo-prj.ds.x_list` (
  `record_time` TIMESTAMP,
  `name` ARRAY
)
INSERT INTO `bangboo-prj.ds.x_list` (`record_time`,`name`) VALUES (CURRENT_TIMESTAMP(),['a','b'])

struct型(record型)は子や孫でヒットすれば親を含めて表示されてしまう
見やすくするため*ではなく、カラムを特定すると空欄が表示されなくなり
親が出なくなり理解しやすくなる(必ずカラム指定したい)

Array=String Repeatedつまりリスト(配列)に値を入れる書式(下記で2つしか入らない)
insert into aaa (aaa) value ("['aaa','bbb']") value has STRING
insert into aaa (aaa) value (`['aaa','bbb']`) Unrecognized name: `['aaa','bbb']`
insert into aaa (aaa) value (['aaa','bbb']) OK
insert into aaa (aaa) value ('["aaa","bbb"]') value has STRING
insert into aaa (aaa) value (`["aaa","bbb"]`) Unecognized name
insert into aaa (aaa) value (["aaa","bbb"]) OK
insert into aaa (aaa) value ([`aaa`,`bbb`]) Unrecognized name
insert into aaa (aaa) value ([aaa,bbb]) Unrecognized name: aaa
insert into aaa (aaa) value ([123,456]) Value has type ARRAY

例)権限が変わっていないかの確認する等
降順で最新の日付のアイテムを見る、そして最終ページの古い日付のアイテムを見る
そしてそれらを比較する
select record_time, name, asset_type, m, b.role
from cai_iam_policy_history
,unnest(iam_policy.bindings) b
,unnest(b.members) m
where record_time between timestamp('2021-05-01') and timestamp('2021-06-30')
and b.role in ("roles/bigquery.dataViewer", "roles/bigquery/jobUser")
and m like '%ketsu@bangboo.com%'
and ancestor_path like '%ketsuproject%'
order by record_time desc
SQL解説)struct型が沢山入っていても全部unnestしfromに入れればいい
 from a, unnest(iam_policy.bindings) b, unnest(b.members) m
    unnest(iam_policy)はできないので2階層目から
  一つ階層上ではunnest時に別名を付けて下の階層はその別名でunnest
struct型の子へは.ドットで指定すればいい、フラットでなくてもbでも取得ができる

通常SQLは「表.カラム」だが「親カラム.子カラム」なので、出元がどこかテーブルを探すかスキーマ内を探すかで迷う

///json_extract, json_extract_scalar
2番目の引数はパス
BigQueryでの複雑なJSON文字列の扱い方と注意点 - Qiita
標準 SQL の JSON 関数  |  BigQuery  |  Google Cloud

with t as (
    SELECT unco_data AS col_1 FROM `kuso`
    WHERE date = "2021-08-04"
)
SELECT
    json_extract(col_1, '$.color') as unco_color,
    json_extract(col_1, '$.temperature') as temperature,
    json_extract(col_1, '$.fart.times[0].stink') as first_stink,
FROM t

///Pivot
BigQueryでPreviewになったPIVOTとUNPIVOTを試す | DevelopersIO (classmethod.jp)
【SQL】クロス集計を扱う。PIVOT句とUNPIVOT句についてコードを踏まえて解説。 | ポテパンスタイル (potepan.com)
集計をして行を列に変換(生ログをある単位でまとめカラムにする)

--toolのactiveがonなら1、nullなら0でユーザAとBの状況を見る
SELECT * FROM (
 SELECT user, tool, active FROM `tools`
)
PIVOT(
 MAX( IF (active IS NOT NULL, 1, 0))
 FOR user IN ("a", "b")
)

tool a b
------------
axe 1 0
sword 0 1

※参考にピボットテーブル
集計して行を列に変換、生ログをある単位でまとめる
 生ログが「日 店 金額」の場合
 ↓
 ピボットで「日 金額 (店1 店2 店3)」にする等で、各項目を行と列と値に配置し直す

BigQueryでPreviewになったPIVOTとUNPIVOTを試す | DevelopersIO (classmethod.jp)
PIVOTの中は定数でないとだめだが、
Execute Immediate なら動的にイケる、
がGoogleSheetのConnectedSheetではサポートされておらず無理という罠

///縦持ち横持ち
pivotは集計関数を用いる、単純の入れ替えならSQLならこちら
[SQL]データの縦持ち、横持ちを入れ替える | DevelopersIO (classmethod.jp)

///新旧の差分
比較したいデータの共通してい部分で外部結合をしてnull部分を探す
WITH
 old_e AS (
  SELECT * FROM status WHERE user IN ('a@old.com')
 ),
 new_e AS (
  SELECT * FROM status WHERE user IN ('a@new.com')
 )
SELECT * FROM old_e o
 FULL OUTER JOIN new_e n ON o.id = n.id AND o.date = n.date
 WHERE o.id is null OR n.id is null
 ORDER BY o.id, o.date

unionにexcept distinctをSQLを付けると差分になる
https://qiita.com/tatsuhiko_kawabe/items/2537c562c6d99f83e37b
SELECT * FROM item.item_table 
EXCEPT DISTINCT 
SELECT * FROM item.item_table WHERE user_id = 'A'
 1つ目の結果から2つ目を引いたものを出す

///REGEXP_REPLACE 正規表現で文字を削除
WITH markdown AS
  (SELECT "# Heading" as heading
  UNION ALL
  SELECT "# Another Heading" as heading)
SELECT
  REGEXP_REPLACE(heading, r"^# He", "") AS html
FROM markdown;
標準 SQL の文字列関数  |  BigQuery  |  Google Cloud

///スラッシュで分割するとarrayになるのでオフセットで取得
select SPLIT(path, "/")[OFFSET(3)] from www

スラッシュの最後を取る
ARRAY_REVERSE(SPLIT(aaa, "/"))[SAFE_OFFSET(0)]
引き当てが無い場合はSAFE_OFFSETはNullを返し、OFFSETはエラーを返す

BigQueryの標準SQLでGROUP_CONCATしたいときはSTRING_AGG - GAミント至上主義 (hatenablog.com)
逆にまとめるには
SELECT type, STRING_AGG(DISTINCT name) FROM testData GROUP BY type;
赤身 | ブリ,いわし,アジ,マグロ,カツオ,サバ
白身 | タイ,タラ,フグ,サケ

///Job kill
CALL BQ.JOBS.CANCEL('job_id')
CALL BQ.JOBS.CANCEL('project_id.job_id')

job idでエラー詳細を確認
bq show -j
bq show --project_id bangboo_sandbox --format json -j bqjobidxxxxxxxxxx | jp .
 job idはコンソールのBQのジョブ詳細やスクリプトキックならロギングから見つけてもいい
 クエリならjob/query historyでわかるがbq cmdでもエラーが返る
  bq query --nouse_legacy_sql 'select ketsu from `prj`.oshi.ri'
  unrecognized name: 'kusofuke@ketsu.com' at [1:149]

select * from prj.`region-us`.INFORMATION_SCHEMA.JOBS_BY_PROJECT
where job_id ="aaaaa" and creation_time > "2022-01-01"

ジョブIDの取得
SELECT
 project_id,
 job_id,
 user_email,
 creation_time,
 start_time,
 --query,
 total_slot_ms
FROM `region-us`.INFORMATION_SCHEMA.JOBS_BY_PROJECT
 --`region-us`.INFORMATION_SCHEMA.JOBS_BY_USER
 --`region-us`.INFORMATION_SCHEMA.JOBS_BY_FOLDER
 --`region-us`.INFORMATION_SCHEMA.JOBS_BY_ORGANIZATION
WHERE state != "DONE"
 --state = "RUNNING"
 --state = "PENDING"
AND user_email = 'my@email.com'
AND project_id = 'paa'
AND start_time < TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 3 MINUTE)
AND total_slot_ms > (1000 * 30)
AND PARTITIONDATE BETWEEN '2021-01-01' AND '2021-01-02'
 --PARTITIONTIME BETWEEN TIMESTAMP('2021-01-01') AND TIMESTAMP('2021-01-02')

///upsert(アップデートか新規インサート
https://swfz.hatenablog.com/entry/2021/02/08/195024
MERGE aaa target USING tmptbl src
 ON target.time = src.time
WHEN MATCHED AND src.satus = 'rejected' THEN
 DELETE
WHEN MATCHED THEN
 UPDATE SET ...
WHEN NOT MATCHED THEN
 INSERT ROW

///window関数
集約関数(GROUP BY)だと個別データは出力されず集計データだけでるが
window関数だと集計データが個別データにouter joinされた形で出力される

SELECT
  deptname,
  id,
  salary,
  AVG(salary) OVER (PARTITION BY deptname)
FROM emp;

  deptname  | id | salary |  avg_salary
-----------+-------+--------+-------------
 dev        | 11 |   5200 |        5020
 dev        |  7 |   4200 |        5020
 dev        |  9 |   4500 |        5020
 dev        |  8 |   6000 |        5020
 dev        | 10 |   5200 |        5020
 hr         |  5 |   3500 |        3700
 hr         |  2 |   3900 |        3700
 sales      |  3 |   4800 |        4866
 sales      |  1 |   5000 |        4866
 sales      |  4 |   4800 |        4866

deptnameでグループしそのsalaryの集計のAVGが出ている
下のようにover()が空でも良い、4900は大体

SELECT
  deptname,
  id,
  salary,
  AVG(salary) OVER () AS avg
FROM emp;

  deptname  | id | salary |  avg
-----------+-------+--------+-------------
 dev        | 11 |   5200 |        4900
 dev        |  7 |   4200 |        4900
 dev        |  9 |   4500 |        4900
 dev        |  8 |   6000 |        4900
 dev        | 10 |   5200 |        4900
 hr         |  5 |   3500 |        4900
 hr         |  2 |   3900 |        4900
 sales      |  3 |   4800 |        4900
 sales      |  1 |   5000 |        4900
 sales      |  4 |   4800 |        4900

関数としては集計関数がそのまま使えるようだ
OVERはwindow関数を使う宣言、OVERの後にどのようにwindowを作るのかを定義
PARTITIONでwindowでつまりどの範囲でグループを作るか指定
 AVG(salary) OVER (PARTITION BY deptname, sub_deptname) でサブデプト単位での平均となる

///誰が実行しているかをセッションユーザで出す
標準 SQL のセキュリティ関数  |  BigQuery  |  Google Cloud
SELECT SESSION_USER() as user;
+----------------------+
| user                 |
+----------------------+
| jdoe@example.com     |
+----------------------+

///エラーハンドリング
BQのクエリ内の条件によりerror()でエラーが吐ける
 select error('id is not unique.') from tbl having count(a) > 1
 ERROR関数を使ったBigQueryデータ異常検知例 #BigQuery - Qiita
 SQだとメール送信したり、ロギングやモニタリングでエラー検知できる

///プログラムで使う
from google.cloud import bigquery
client = bigquery.Client()
QUERY = ('SELECT name FROM `bigquery-public-data.usa_names.usa_1910_2013`')
query_job = client.query(QUERY)
rows = query_job.result()
for row in rows:
    print(row.name)

///Pythonも含めトランザクション
/// BANGBOO BLOG /// - GCP script

■saturationの場合、詰まっている、サチっている
対象にクエリを発行 select 1
同プロジェクトの他のテーブルにクエリを発行 select 1
別プロジェクトから対象にクエリを発行 select 1
reservationsのoverviewを見る
対象のSQLを発行
別のプロジェクトで同SQLを発行
 時間を比べる
Google側の問題と思われるときはGoogleのサポートへGo
Google Could Status Google Cloud Status Dashboard

INFORMATION_SCHEMA < Audit log で調査
メタデータ(データに対するデータ)
 システムメタデータ(作成更新日時、サイズ、誰いつ参照
 ビジネスメタデータ(オーナ、更新頻度、カラムの意味
select * from prj.ds.INFORMATON_SCHEMA.TABLES
select * from prj.ds.INFORMATON_SCHEMA.PARTITIONS
 longterm storageでサイズが100000b以上で、更新日が1か月以上とか出せる
select * from prj.ds.INFORMATON_SCHEMA.COLUMNS where column_name like '%kuso%'
select * from prj.ds.INFORMATON_SCHEMA.VIEWS where view_definition like '%kuso_table%'
 view_definitionはSQL文が入っている
select * from prj.ds.INFORMATON_SCHEMA.JOBS_BY_(USER / PROJECT / ORGANIZATION)
 誰アクセス/誰作った/何Job等も分かる、180日しか出せないが
 roles.bigquery.resourceViewerが必要
 カラム例:user_email、query、referenced_tables
Auditlogは プロジェクト間で使用されるBQでも情報が取れる
 info_schemaのjobs_byとほぼ同じ内容が取れるがよりリッチ
  利用ユーザ数、旧データを見ている人、権限変更操作ログ等

SELECT `b-sandbox`.test_ds.count_row(1); で実行できる
UDFやテーブル関数のルーティンを承認しておくと誰からでも使える(ビューと違い権限管理できずセキュリティがズブズブになると思われ)
 target_prj.trg_dsに受け入れる関数を共有指定する形
 UDFは戻り値がある、テーブル関数は副問い合わせとして使う形か

///ScheduledQueryの実行者
コンソールの場合:コンソール操作者
Terraformの場合:Terraform実行者
bqコマンドの場合:任意に設定ができる
サービスアカウントをbqコマンドでSQ実行者として登録する場合、通常は問題がないがスプレッドシートを使用するなら@プロジェクト名.iam.gserviceaccount.com等でアクセス権が必要なため、会社のポリシーによってはうまく行かない。batch@unco.comのような共通メールを作成し使用したい。(GWS側でOUを使いTrusted ruleによりSAにGoogleDriveへアクセス許可すると問題回避できるが:OUをつくりそのOU内で専用共有ドライブを作成し設定する)

サービスアカウントにScheduleQueryを実行させる設定に必要な権限
https://cloud.google.com/bigquery/docs/scheduling-queries?hl=ja
設定操作者
 BQ job user(クエリ作成ができない)
 BQ transfers.get/update
 BQ data viewer/editor
 iam ServiceAccountUser(対象SA、PRJレベルでも良いが広くimpersonateできてしまう)
 →対象SAのみならlistも含むがlistが不足しているとされ serviceAccountViewerをPRJレベル付与も必要
 保存先DSへBQ admin等へのsetiam系が2026/3から必要
サービスアカウント
 BQ job user
 BQ data viewer/editor
 ※BQ transferは不要だった

Scheduled queryからの保存先
コンソールだと同じプロジェクト内だが、create文を自由記載ならどこでもOK
job userは同じプロジェクトの権限が必要

設定者一覧を出したい場合
bq --format=json --project_id=bangboo-oketsu ls --transfer_config --transfer_location=us | jq.[].name
bq --format=json show --transfer_config project/1111111/locations/us/tranferConfigs/111111 | jq .ownerInfo.email

■SQLはカラム数の増加数で構成考える?
left outer joinはカラム数がカラム数の合計から共通のjoin onのカラム数を引いた数(行数はleftに同じ)
 full outer join はカラム数がカラム数の合計から共通のjoin onのカラム数を引いた数(行数はleftの要素数にrightの要素数を合計したもの)
unionは重複を除外し表を足し合わせるため行数が両表の合計行数(カラム数は合致必要でカラム数は変わらない)
unian allは重複を除外せず表を足し合わせるため行数が両表の合計行数(カラム数は合致必要でカラム数は変わらない)
cross joinはカラム数が両表のカラム数の合計、行数は両表の行数の掛け算
 再帰的にSQL処理はcross joinし条件を付けるか?
  標準SQLのFrom句のカンマはcross joinとなる
with句は副問い合わせを見やすくしたもの
distinctで(組み合わせで)一意になる行のみにし重複を省く
UNION とUNION ALLの違い - Qiita
CROSS JOIN (クロス結合)を使ってデータを取得する - JOIN (結合)を使いこなそう - SQL Server 入門 (sql55.com)
SQLのDISTINCTとは?(OracleやMySQLで使用する方法) | IT職種コラム (it-kyujin.jp)

デカい表をいくつか持ちJOINすると再帰的にWhere句で条件検索しなくてよい

■課金
クエリ課金:使用しているプロジェクトで課金される、データの置き場所ではない
 定額フラット:$2000/100slot/m(全プロジェクトでスロットを共有)、オンデマンド:$5/T=2Gスキャンで1円位
  flat rateでもflex slotsとして時間帯によりスロットを増やす等ができる
   Editionsに変更になった:組織に5プロジェクト等しかreservationを置けない、その中で限りなく設定ができる
 課金を減らすには:カラムを減らす、パーティショニング
  プレビューを活用:しかしビューだとプレビュー機能はない。列が501列以上あったら501列以降はプレビュー出ない
データ保管課金:データ量
 $1/50G/m
 active storageからlong term storageへの移行は自動(90日変更がない、50%off)
6,000スロットを使うBigQueryのリソース配分最適化への挑戦 (plaid.co.jp)

■定額制Editions
スキャンサイズが大きくてコンピューティングが少ないならリザベーション (Editions)が向いている、スキャンサイズが小さくてコンピューティングが多いならオンデマンドが向いている
スロット消費量=データ量とコンピューティング
1)データ量: Read量/スキャン量 (スキャン量が多くても単純クエリならスロット消費が少なく単純な比例ではない)
2)コンピューティング負荷: CPU/メモリ消費 (結合/集合/フィルタ/ソート/大量JOIN/複雑なウィンドウ関数等で重いクエリ)

■オンデマンド
必要なクエリ以外は別の定額制のプロジェクトで実行するよう変更
オンデマンドはスキャンしたデータ量で料金が決まる
 実行しているクエリのスキャン量で料金を見積もる
パーティション、クラスタリングでスキャン量を減らす
SELECTはNG。必ず必要な列だけを明示する。
スキャン量のモニタリングとアラート設定を実施する。
同じクエリならキャッシュが利くため定額のエディションが有利(24h)
 ソースの更新等でキャッシュが無効になるよ
 Bigquery キャッシュについて #GoogleCloud - Qiita (キャッシュ設定/有効無効

■権限
事前定義ロールと権限  |  BigQuery  |  Google Cloud
job user:select文クエリ実行だけでもジョブでjob userとdata viewerが要る(data viewerだけでは不足)
 課金プロジェクトでjob userを持ち、参照先プロジェクトでdata viewerを持つという権限構成だから
 例えばjob userがなくdata ownerだけの場合はデータセットやテーブルやビューの削除作成ができるが、データロードやselect文発行はできない
IAMかデータセット/tblに必要な権限を付与する
 data editorでも自分で作成したものは自分がOwnerになり削除や変更権限がある
meta data viewerならDSとテーブル一覧、テーブルのスキーマや容量等の情報が見れデータは見れない
 これを広く付けておくとデータ管理が楽

■サービスアカウントに対するBQ job user
コンソールであれば画面左上の請求先プロジェクトで切り替えができるが
スクリプトであればgcloud auth login時に切り替える
gceならインスタンスにSA設定するが
 請求先プロジェクトのデフォルトはインスタンスの置いている/SAが作成されたPrj
  ※同プロジェクトからしか選択ができない
 コード上で切り替えができる
  bq --project_id=xxx query 'select count(*) from ds.tbl'


Posted by funa : 01:00 AM | Web | Comment (0) | Trackback (0)


February 11, 2021

Python Python
■importとfrom
Pythonのモジュールとimportとfrom入門 - Qiita
Python, importの使い方(from, as, PEP8の推奨スタイル, 注意点など) | note.nkmk.me
Pythonインポート周り徹底理解への道 - Qiita
Pythonの相対インポートで上位ディレクトリ・サブディレクトリを指定 | note.nkmk.me

標準ライブラリならimport文を本体に書いていれば良い
 標準ライブラリ以外はPyPI(Python Package Index)と呼ばれる3rdパーティライブラリから
 pip(The Python Package Installer)インスコ

import文を使って下記の3つなどをインポートし使う
 標準ライブラリ
 pipでインスコしたパッケージ
 自作のパッケージ
自作は大体わかるがそれ以外はどこにあるのか?
 $ python
 >>> import sys
 >>> sys.path
 でパス一覧が出るので探すと分かる >>> exit()でpythonコマンド終了
例えば Cloud functionsなら requrements.txtに google-api-python-client==3.3.2と記載し
 PyPI · The Python Package Index でバージョンを探す
コードに from google.cloud import bigqueryと宣言する
 requirementがpipインスコ

import フォルダ.ファイル名
from フォルダ.ファイル名 import *
 上下同じだが、fromは一部を指定し直接使うという意、*は非推奨
 つまり
import hello なら下記とする必要があるが
 print(hello.hello)
from hello import hello なら省略ができ下記で良い
 print(hello)
from フォルダ名 の場合
 そのフォルダ名の中に __init__.pyがあれば其れ
from .xxx import aaa の.の意味は?
 mainに対するモジュールから見て相対で隣

モジュール検索パスを出す
from pprint import pprint
import sys
pprint(sys.path)

■pipインスコ
pipの使い方 (2014/1バージョン) — そこはかとなく書くよん。 ドキュメント (tdoc.info)
Python:pip における管理者権限と user install - pyてよn日記 (hatenablog.com)
Python でパッケージを開発して配布する標準的な方法 - Qiita
pythonのsetup.pyについてまとめる - Qiita
PyPIでサードパーティライブラリを管理していてインスコ可
setup.pyが含まれたローカルディレクトリも指定しインスコ可
eオプションで編集可能な状態でインスコ
--userで~/.local下の管理権限不要なユーザディレクトリ以下でシステムが汚れない
--userなしで/usr下にインスコ
pip install --user -e unko
pip3 install pipenv
pip list インスコ済みのものを確認

pip install -r requirements.txt reqirements.txtで一括インスコ
pip freeze > r.txt pip listをファイルに書き出す
pip uninstall -y -r r.txt -yで確認なしで一括アンインストール
Python, pipでrequirements.txtを使ってパッケージ一括インストール | note.nkmk.me

パッケージとバージョンを指定してアップデート
pip install -U google-cloud-bigquery==3.4.0

下記にもろもろ
pipでパッケージをupdate|pip自体のアップデートについても解説 (itc.tokyo)

■envツール
 pyenv install --list インストールできるもの
 pyenv install 3.8.8 指定verをインスコ
 pyenv global 3.8.8 デフォルトに指定
 .python-versionファイルをGITに載せ管理したい?
 pipenvはPipfileとPipfile.lockを利用しpipでrequrements.txtを用いるよりも強力
  PipfileとPipfile.lockとrequirementsをGITに載せ管理したい?
 pipenv --python 3.8.8 など最初にpyバージョンをpipfileに記載
 pipenv install "google-cloud-tasks==1.5.0" バージョン無しでも有りでも入れられる
 Pipfileを書き換える方法
  [packages]
  google-cloud-tasks = "==1.5.0"
  protobuf = "*"
  そして下記cmdでインスコ
  pipenv install PipefileからインストールしPipefile.lockを更新
 pipenv sync Pipfile.lockの最新を取得し環境更新(Pipefileは使わない)
 pipenv shell 仮想環境を起動
 pipenv run python main.py
 他に
 pipenv uninstall google-cloud-tasks アンインスコ
 Pipfile, Pipfile.lockがあれば pip syncでOKだがrequirements.txtも使える
 pipenv lock -r > requirements.txt 生成
 pipenv install -r requirements.txt
pipenvのバージョンが古いと依存関係、Ver整合性で問題が起きやすい
 pipenv --version
 pip install pipenv
 pipenv update
 pipenv upgrade <パケ>でやり直す

■assertでテスト
assert文は組み込み定数__debug__がTrueの時のみ実行されます
実行コマンドにオプションに-Oをつけると__debug__がFalseになりassert文が無効に
def func_so(a, b):
c = a * b
return 
def test():
assert(func_so(1,2) == 2)
if __name__ == "__main__":
test()
main()

■テスト駆動
PyTest を LLMに書いてもらいたい。下記のようなプロンプトで準備できるのでは?
https://aaaa にアクセスし名前欄にaaaと入力すると名前欄に英数が入っていますとエラーが出る

■PyTest
assert
成立すべき式(Trueになるべき式) をassert文で記述

テストの準備と後処理
@pytest.fixtureデコレータをつける

実行(ディレクトリのtest、testファイル、test 関数が対象)
pytest

テストカバレッジを確認:tests/ディレクトリ内の全テストを実行し現在のディレクトリ内のコードについてどれだけテストでカバーされているかを測定
pytest -covs=. tests/

■test app.pyでエラー表示を拾ってテスト
import pytest
from app import app

@pytest.fixture
def client():
    app.config['TESTING'] = True
    with app.test_client() as client:
        yield client

def test_valid_input(client):
    response = client.post(
        '/', 
        data={'name': 'TestUser', 'email': 'Test@example.com'}, 
        follow_redirects=True
    )
    assert b'OKでっせ' in response.data

def test_invalid_name(client):
    response = client.post(
        '/', 
        data={'name': 'ThisNameIsTooLong', 'email': 'test@example.com'}, 
        follow_redirects=True
    )
    assert b'name At most 10 characters long' in response.data

def test_invalid_email(client):
    response = client.post(
        '/', 
        data={'name': 'ValidName', 'email': 'Invalid email'}, 
        follow_redirects=True
    )
    assert b'emailがinvalid email addressなんだけど' in response.data


■パラメータを複数種類
import pytest
@pytest.mark.parametrize(
"x, y", [
("aaa", "bbb"),
("aaa", "aaa"),
("bbb", "bbb")
]
)
def test_1(x, y):
assert x == y

■fixture: fixture@yieldまでの処理> テスト本体> fixtureのyield後からreturnまでの処理
import pytest
from pathlib import Path
import shutil

def create_file(path):
    # 指定されたパスにファイルを作成する関数
    path.touch()

# 一時ディレクトリを作成するフィクスチャ
@pytest.fixture()
def create_tmp_dir():
    # 一時ディレクトリを作成
    tmp_dir = Path("/tmp/test")
    if not tmp_dir.exists():
        tmp_dir.mkdir()
    yield tmp_dir
    # 一時ディレクトリを削除
    shutil.rmtree(tmp_dir)

def test_create_file(create_tmp_dir):
    target_file = create_tmp_dir / "test.txt"
    create_file(target_file)
    assert target_file.exists()


■個別
import dataclasses
[詳解] Pythonのdataclasses (zenn.dev)
 データ格納するオブジェクトを作れば使い回しが楽
import datetime
pip install pyyaml > import yaml
pip install requests > import requests

Python + VSCode の環境構築 20240604 (zenn.dev)


↓本家
/// BANGBOO BLOG /// - Python

Posted by funa : 12:00 AM | Web | Comment (0) | Trackback (0)


February 10, 2021

Python
おッPythonやるのか?

ファイル拡張子oppython.py デフォUTF-8、全部オブジェクト(list,dict,set等のミュータブルなら参照になる点に注意、必要ならcopy())
#コメント、ドキュメントストリング(三連引用符):"""そのまま表示""" print mymod.__doc__で見れる
変数型不要:p = 500 * num、でもキャストは必要、定数はない
文字繰り返し、キャスト:"文字列" * 4 + str(p) + "Hi\nお元気ですか?\nSee u"
raw文字列でescしない:print(r"インストール先は c:\\code\python\bin です")
 正規表現のrも同意 re_result = re.match('hel', r'hellow python, 123, end.' )
  if re_result: #None以外という意味で、Noneはいわゆるnull、Pythonにnullはない
文字数:len("東京都")→3
文字列[開始:終了]→→ str = "Flower" print(str[1:4]) → low
文字列 % (値1, 値2, ...)→→ num= "10進数では %d 、16進数では %x " % (num, num)
"xxxx{index:書式指定子}xxxx".format(値)→→ "名は{:<8s}で年は{:>3d}で".format(name, age)
f"xxxx{値:書式指定子}xxxx"→→ f"名は{name:<8s}で年は{age:>3d}で" 
0/空の文字列''/値なしはfalse、Noneは? x = None x is None→→true?
//→除算切り捨てし整数、**→べき乗
関数宣言はdef kansu(): で中で宣言する変数はローカル変数
 関数外で宣言された変数はグローバル変数でどの関数の中でも扱えるようになる
 なお関数内でもglobal henでグローバル変数を宣言できる Pythonでのグローバル(global)変数の宣言方法 | UX MILK
返り値複数はcsvでタプルになる、リストが楽か? return a,b → (a, b) あるいは return [a, b] → [a, b]
def func(a, b):
return a, b
result = func()
 result[0]がa、result[1]がb
try/exceptを関数内で設定することも、逆に関数呼び出し時にも使用ができる、else, finally, raiseも使う、エラーが出ても止めたくない場合は try-except Exceptions as e、逆にexceptを入れなければ止まるので安全
try:
get_all_transfer(project_id)
excerpt Exception as e:
print(e)
置換は左辺が要る?要る a = a.replace('x','')
とほほのPython入門 - リスト・タプル・辞書 - とほほのWWW入門 (tohoho-web.com)
Pythonの辞書とリストとクラス 複数情報の受け渡し|みはみ|note
リストa=[1,2,3]はmap(), filter(), reduce()等が使える
 a=a.append()とかa=a.extend()は値がないんで駄目、単純にappend(b)やextend(b)で左辺不要
 取得:a[0]、for v in a:
 リストの合体:list_a += list_b
セット型set={1,2,3}は重複や順序や添字の無いリスト、set(list)でキャストし重複を無くせる、ミュータブルは格納できない
 取得 for v in a:
tuple→タプルは定数リスト、更新無しならリストより速い a = 1,2,3 a = (1, 2, 3)
 取得:a[0]、for num in a:
dict→辞書は連想配列みたいな{a:1,b:2}はitems(), keys(), valus(), iteritems(), get()を使える
 Python | 辞書に含まれるすべてのキーと値を取得する (javadrive.jp)
 取得:dict_a['key1']、for k in dict_a.keys(): for v in dict_a.values(): for k, v in dict_a.items():
 dictの合体:dict_a.update(dict_b)
クラス→例えば●●クラスを宣言しsampleインスタンスを生成し、getter/setterで変数に入れて置く
 取得:sample.key
BigQuery→別名を付ければ名前で取得できるが、インデックスでも取得できる(これ何?)
 取得:for row in query_job: →row[0], row["t"]
lambdaは無名関数?
str_w = input('何か入力してください-->') #入力させた値を取れるが数字もstr
__iter__()はnext()を持つオブジェクトを返し、next()は次の要素を返し、最後に達するとStopIteration例外を返す?
yield はイテレータを返すジェネレータを定義?
@デコレータは関数を実行する前後に特殊な処理を実行したい場合?
withで終了処理を指定できる、ファイル読込とその後の処理とか
assertや__debug__はテストで機体通りかを確認する?
passは中身の無い関数やクラスを作成しkara.p=1で粋なり属性追加等ができる
execは引数の文字列をPythonとして実行 exec "print 'Hello'"
delはオブジェクトを削除 del x, y, z
継承やオーバーライド class MyClass2(MyClass):
多重継承class MyClassC(MyClassA, MyClassB): で纏めて使えるようになる
class MyClass:
    """A simple example class"""  # 三重クォートによるコメント
    def __init__(self):  # コンストラクタ
        self.name = ""
    def __del__(self): #インスタンスが消滅する際に呼出でコンストラクタ
        print "DEL!"
    def __str__(self): #文字列化
        return "My name is " + self.name
    def getName(self):  # getName()メソッド
        return self.name
    def setName(self, name):  # setName()メソッド
        self.name = name
class MyClass2(MyClass):
    def world(self):
        print "World"
class MyClass3(MyClass):
    def hello(self):  # 親クラスのhello()メソッドをオーバーライド
        print "HELLO"
a = MyClass()  # クラスのインスタンスを生成
a.setName("Tanaka")  # setName()メソッドをコール
print a.getName()    # getName()メソッドをコール
print a  #=> My name is Tanaka 文字列化
b = MyClass2()  #継承
b.hello()    #=> Hello
b.world()    #=> World
c = MyClass3()  #オーバーライド
c.hello()    #=> HELLO
super()を使ってオーバーライドする
 super()は基底クラスのメソッドを継承した上で処理を拡張
 super().__init__(x、y)が使える
if __name__ == "__main__":
 モジュール時の勝手実行を抑える
  import helloの時hello.py 内部での __name__ は "hello" 
  python hello.pyのような実行時hello.py の内部の __name__ は "__main__"
from math import pi, radians→mathモジュールから特定のオブジェクト(関数/変数/クラス)をimpo(math.piみたいに書かず省略できる)
import urllib.error→urllibパッケージからerrorモジュールをimpo、パッケージはフォルダ
import numpy as np→別名でしか使えなくなるnp.array()とかで
 モジュール=ファイル名.pyでファイルをimpoしている
from {another_file} import {ClassName}
 another_file.pyがファイル名
 class ClassNameがクラス名
from {パッケージ:ディレクトリ} import {モジュール:ファイル}
 ちゅー書き方もできるらしいが、どっち?
impo順:標準ライブラリ>サードパーティライブラリ>ローカルライブラリ(自作のライブラリ)

関数や変数:小文字スネークケース(sample_func)
クラス名、例外、型変数:キャピタルパスカルケース(SampleClass)
定数名:大文字アンダースコア区切り(SAMPLE_CONST)
モジュール名:小文字(samplemodule, sample_module)
パッケージ(フォルダ)名:小文字。アンダースコア非推奨(samplepackage)

インデントは半角スペース4つ
1行半角で79文字以内
トップレベルの関数やクラスは2行開ける
クラス内部では1行ずつ開けてメソッド定義
ドックストリングでクラスや関数についてコメントする(慣習的にダブルクォート)
 コード中は処理についてのコメントをなくし関数化とdocstringで参照するように
 「コメント(#)とdocstring(""")の違いは?」コメントとdocstringについて
 [Python]可読性を上げるための、docstringの書き方を学ぶ(NumPyスタイル) - Qiita

デバッグの方法案
print(type(v)) でどんなメソッドを持っているか等を探る
print(v) をコマンド前後や流れで沢山仕込みでどこでエラーが出ているか探す
print("creds:")
print(creds)
print("type(creds:")
print(type(creds))
print("vars(creds:")
print(vars(creds))
print("creds.keys():")
print(creds.keys())
print("dir(creds):")
print(dir(creds))
print("creds._dict_:")
print(creds.__dict__)

is not subscriptableのエラー 添字不可エラーでリストでないのにリストとして入れようとしている

※参照になりコピーされない、必要ならコピー(値を入れた時点で参照が外れるので実際問題少ない?)
a = []
b = a
b.append(1)
print(a) #[1]
https://qiita.com/ponnhide/items/cda0f3f7ac88262eb31e
https://nishiohirokazu.hatenadiary.org/entry/20120125/1327461670

環境変数を扱う
 import os
 print(os.environ["HOME"]) ホームディレクトリ、LANGでja_JP.UTF-8とか
 os.environ["PHASE"] = "staging" 環境変数に代入できるのは文字列だけ
 del os.environ["PHASE"] 削除
コマンドラインの引数を扱う
 python3 sys_arg_test.py a 100
  dst_prj = sys.argv[1] (aが入っている)
  sys.argv (['sys_arg_test.py','a','100']

Pythonのリストと文字列を相互に変換する方法まとめ | HEADBOOST
→リストをStrに変換してSQLにする場合For文が良い(Pythonの書式とSQL書式のコンビなので丁寧に対処するため)
i = 0
v = "["
for s in list_v:
    i += 1
    if i > 1:
        v += ","
    v += "'" + s + "'"
v += "]"
SQL = "insert into aaa (aaa) value ({v})"

※テキスト選択
 Shift↑or↓ で行全体
 home(+fn)で行頭、end(+fn)で行末移動

【基礎一覧】Pythonの基本文法を全て解説してみた!【初心者】 (suwaru.tokyo)
Python基本文法まとめ - Qiita
とほほのPython入門 - とほほのWWW入門 (tohoho-web.com)
Python入門 ~Pythonのインストール方法やPythonを使ったプログラミングの方法について解説します~ | Let'sプログラミング (javadrive.jp)
Welcome to Python.org

HTMLの中に少し埋め込めず、基本的にプログラムの中にHTMLを埋め込む:CGI(Perl然)
 さくらインターネットでPython CGI (mwsoft.jp)
WSGI Python で WSGI (Web Server Gateway Interface) に従ったシンプルな Web サーバで Hello World - Qiita
Python用Webサイト用途フレームワーク:Flask(軽量)、Django
 WSGI について — Webアプリケーションフレームワークの作り方 in Python (c-bata.link)
 GCPでどう使うかは不明だがホスティングは↓
 ウェブ ホスティング | Google Cloud 静的ウェブサイトのホスティング  |  Cloud Storage  |  Google Cloud

str.split() 区切り文字で分割しリスト等に入れる Pythonで文字列を分割(区切り文字、改行、正規表現、文字数) | note.nkmk.me
print('Sam' in 'I am Sam') # True 任意の文字列を含むか判定: in演算子 Pythonで文字列を検索(〜を含むか判定、位置取得、カウント) | note.nkmk.me
==============
ここで動かせるgoogle colaboratory→ Colaboratory へようこそ - Colaboratory (google.com)

コラボラトリはマークダウン Qiita マークダウン記法 一覧表・チートシート - Qiita
半角スペース2個で改行
#の数で見出し
*で箇条書き
数字と.で番号を振る、- でリスト
* or - or _ を3つ以上で水平線
[ ]でチェックボックス、[x]でチェック
| td | td | td |でテーブル
**aaa**で太字、*aaa*で斜体
~~aaa~~で打消し線
[タイトル](URL)でリンク
```でコードの挿入、`でインライン挿入
> or >> で引用
 [^1]で注釈
\バックスラッシュでマークダウンのエスケープ

==============
宗教論争(事実は同じでも他人の認知は違うので意味なし
if self.flag_ok == 1 and self.mode == '1'
↓一見で分からんなら変数名を工夫してこうやんな
if self.file_verify_completed and self.mode == GRANT_PERMISSION:

マジックナンバーを使わない(数字の方が曖昧性が無い場合も)
STATUS_ERROR = -1
STATUS_SUCCESS = 0
self.status_error = STATUS_SUCCESS

with構文で処理の前後でコンテキストマネジャ__enter__、__exit__が使われる
 __enter__メソッドで事前処理
 __exit__メソッドで事後処理
with ファイル操作や通信などの開始時の前処理と終了時の後処理など必須となる処理を自動で実行
try/finallyみたいなもの、最初と最後に何かしてくれる
class a(object):
def_enter_(self):
print 'sss'
return 'sss111'
def_exit__(self, type, value, traceback):
print 'ok'
return False
with a() as s:
print s
sss
sss111
ok

初期値をエラー値にし、業務判定エラーでステータスを設定したらreturnで抜ける
def exFunction(self):
self.status_error = STATUS_ERROR
try:
if XX = AAA:
self.status_error = STATUS_XX_ERROR
retrun
self.status_error = STATUS_SUCCESS
retrun
except:
~エラー処理、ステータスは変更しない

エラーメッセのハードコーディングを避ける方法(ハードが場所と内容が分かり易いかも)
MSG_ERROR_OLD_EMAIL = "Error: 旧メール%sです\n"
e_message_list.append(MSG_ERROR_OLD_EMAIL % (old_email))
self.error_message = '\n'.join(e_message_list)


ケチって分厚い本1冊にしたが全然進まぬ、薄い奴星e、?チッPython、誰がJSONじゃ~い、チェーンソー魔わすっぞ

続編、、モジュールとかmportとか、
/// BANGBOO BLOG /// - Python Python

Posted by funa : 07:30 PM | Web | Comment (0) | Trackback (0)


January 27, 2021

Framework
群雄割拠か弱肉強食か政治解決か遣りたい放題の中、当事者なら自然に身につくだろうが時代に参加していない貴殿には到底分からない、シルバーブレットはなく結局は愚直しかない、どう愚直になるか/どう立ち回るかを発見するのがフレームワークだ、もしトレンドを感じればそれに乗ればよい、他にシーズがあればプロダクトアウト、ニーズがあればマーケットインだ

■フレームワーク
3C(Customer/Competitor/Company:自社)
SWOT(Strength-Weakness x Opportunity-Threat)
PEST分析(Politics/Economy/Society/Technology)
3M(人物金、Men/Material/Money)
3M(ムリ:負荷が人に掛かる/ムダ:資源が余り浪費しコスト高/ムラ:負荷と浪費が交互)
7S(<3sはハード>Structure/Strategy/System、<4sはソフト>Shared value:価値観/Skill/Staff/Style:文化)
VRIO(Value/Rarity/Inimitability:模範困難性/Organization)
MVV(Mission:使命why/Vision:将来像what/Value:価値観how)
マーケ4P4C(4p:product/price/place/promotion, 4c:customer cost/customer cost/convenience/communication)
QCD(Quarity品質/Costコスト/Delivery納期)

ポーターの5forces(Competitive Rivalry:競争企業間の敵対関係/Supplier Power:売り手の交渉力/Buyer Power:買い手=顧客の交渉力/Threat of Substitution:代替品の脅威/Threat of New Entry:新規参入業者の脅威)
コトラーのSTP(segmentation:顧客やニーズや特性等で細分化/targeting:セグメ選択/positioning:勝てる位置取り)
競争戦略ポジショニング (コストや差別化や集中戦略等で業界ポジを練る)
PPM:product portfolio mgt(市場成長率xシェア->問題児:花形に育てる/花形:継続投資/金のなる木:投資無し/負け犬:撤退検討)
製品ライフサイクル:PLC(導入期:認知度と需要up/成長期:製品多角化販路拡大/成熟期:差別化とコストダウン/衰退期:選択と集中効率化)
イノベータ理論(Innovators/Early Adopters/Early Majority/Late Majority/Laggards:16%キャズム:段階で戦略を変えていく)
RFM(recency/frequency/monetary->優良顧客を見つけよりマーケ)
ポーターのバリューチェーン(企画/開発/購買/製造/物流/販売/サービス/人事の各々での価値->VRIOで分析)
アンゾフの成長マトリクス(既存市場浸透:既存市場x既存商品/新市場開拓:新規市場x既存商品/新商品開発:既存市場x新規商品/多角化:新規市場x新規商品)
TOWS(クロスSWOT分析:SWOTをSWOTする->SWOTで現状分析、さらにSWOTで戦略化)
SCAMPER(アイデアの展開->substitute代用/combine結合/adapt応用/modify修正-magnify拡大/put to other uses転用/elininate削除-minify削減/reverse逆転-rearrange再編集)
ECRS:イクルス(改善策->排除/統合/交換/簡素)

ギャップ分析(As Is/To Be<-間にaction)
特性要因図:フィッシュボーンチャート(要因を網羅的に調べる、他にも親和図法やマインドマップ)
意思決定マトリックス(縦軸に候補、評価基準を横軸、評価基準に重みをつけて点を出し、合計の総合点で判断)
CS/CE分析(Customer satisfaction/Customer expectation->各機能のcsをceに合わせる、ce高cs低の改善)
リスク評価マップ(インパクトx不確実性、インパクト大に対処し小は静観、不確実性が高いと注意が必要<-pest/5f)
AIDMA...etc...

ユダヤの商法:78対22の法則で上手くいく、契約主義で約束を守る
ケイパビリティ戦略:ビジネスプロセスを能力化、スピード/整合性/明瞭性/俊敏性/革新性が上がる、CEOがツールや組織を検討
ポジショニング戦略:競合との位置付け、STP分析をしどうポジションを取り差別化するか
タイムベース競争戦略:時間こそが希少資源、スピードが一番顧客満足が高い、数稼ぐ
アダプティブ型戦略:多くの新しいアプローチを試し最も有望なものを拡大展開、PDCA、やらな分からん時代

ランチェスターの法則:
奇襲/武器/集中、逆にシェアトップで武器も兵数あると模倣し広域戦
 自分を知る、競合を知る、シェア1位を知る
 地域限定、顧客志向営業、販路、陽動奇襲の企画、強みに集中

■逆転の競争戦略
競合の弱みを攻撃するのがセオリーだったが、イノベーションのジレンマでひっくり返す(客の意見を聞きすぎると安い慣れた商品を求められるが自ら革新を進め避けるべき、サンクコストや業界しがらみを乗り越えるべき)
業界破壊者(枠を壊す)/侵入者(他業種からの参入)/挑戦者(競合が攻撃)がトップシェア企業を脅かす
1)企業資産の負債化=リーダーが持つ競争優位の源泉を攻めリーダーが蓄積してきた優位な経営資源を価値のないものにし負債にしてしまう戦略:モスは店内で調理しマックより優位に、あるいは逆にセントラルキッチン
2)市場資産の負債化=リーダー企業に有利に働いていた競争のルールを変更し、顧客が持つ資産(ソフトウェア、交換部品など)を使えなくする戦略:VISAよりQRのPaypay
3)論理の自縛化=安易に追随するとリーダー企業が発信してきたメッセージと矛盾することになり、企業イメージを低下させてしまう戦略:手作り丁寧より100均
4)事業の共喰化=リーダー企業が強みとしてきた製品・サービスと共喰い関係にあるような製品・サービスを市場に出すことで、リーダー企業内に追随するか否かの不協和音を引き起こす戦略:カーシェア
ランチェスター戦略、マイケルポーター競争優位の戦略

ーーーーーーーーーーーーーーーーーーーーーーーーーー
■現代思想
ニーチェ:ルサンチマン、奴隷道徳<>快と力の高揚感が生を肯定、ニヒリズム
マルクス:神格化、砂漠の水を都市で売ろう、紙一枚が命より大事…社会的関係の錯覚
フロイト:無意識<>理性、理性は単なるハリボテであり無意識が主人で自律神経も管理
 エス(快楽主義)>自我:Ego(調整役)>超自我:Super ego(親/社会/会社の価値観の同一化)
  親や社会等から裏切られると同一化できずトラウマ、葛藤を無意識化に隠したい
ユング:Collective unconscious(人類は人種に限らず同じ記憶を持っている)

ーーーーーーーーーーーーーーーーーーーーーーーーーー
■リーダーシップで面白いほど結果が出る本
(仕事の種類)リーダシップ分類:指示/率先/構想/合意/育成/関係構築
  リーダシップ→変化、コントロール→維持(基本どちらもPDCA)
  若手に新しい変化のリーダシップが期待されている
(担当)鷹の眼と蟻の眼(大きな視点の戦略+現場の改善)
(頭脳)1)構想力、2)推進力、3)育成力
  →アイデア発表、ダメ出し、頼りにされる
1)構想力:戦略をゲームとして導入する、仕事の意味を伝える、今を楽しむフロー没入
2)推進力:手段の目的化を防ぐダメ出し、メンバーに寄り添う:会話の時間が足りない、現場のアイデアや成功事例を吸い出し
3)育成力:個々人の心のベクトルを少しプラスに、共通言語の定着(これがないと心の障壁や違和感)
(発想は言葉から、リーダは言葉が大事)

ーーーーーーーーーーーーーーーーーーーーーーーーーー
JCOM回線不安定:
インターネット回線の信号レベルはタブレットで通信でモデムに入って測れる
宅外でモデムを繋いででも宅外で調査しろ
同時接続数等々でスロットリングしているだろうが

Posted by funa : 03:00 AM | Column | Comment (0) | Trackback (0)


Navi: <  1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19  >
PhotoGallery


TWITTER
Search

Mobile
QR for cellphone  QR for smart phone
For mobile click here
For smart phone click here
Popular Page
#1Web
#2Hiace 200
#3Gadget
#4The beginning of CSSレイアウト
#5Column
#6Web font test
#7Ora Ora Ora Ora Ora
#8Wifi cam
#9みたらし団子
#10Arcade Controller
#11G Suite
#12PC SPEC 2012.8
#13Javascript
#14REMIX DTM DAW - Acid
#15RSS Radio
#16Optimost
#17通話SIM
#18Attachment
#19Summer time blues
#20Enigma
#21Git
#22Warning!! Page Expired.
#23Speaker
#24Darwinian Theory Of Evolution
#25AV首相
#26htaccess mod_rewite
#27/// BANGBOO BLOG /// From 2016-01-01 To 2016-01-31
#28竹書房
#29F☆ck CSS
#30Automobile Inspection
#31No ID
#32Win7 / Win10 Insco
#33Speaker
#34Arcade Controller
#35Agile
#36G Suite
#37Personal Information Privacy Act
#38Europe
#39Warning!! Page Expired.
#40GoogleMap Moblile
#41CSS Selectors
#42MySQL DB Database
#43Ant
#44☆od damnit
#45Teeth Teeth
#46Itinerary with a eurail pass
#47PHP Developer
#48Affiliate
#49/// BANGBOO BLOG /// From 2019-01-01 To 2019-01-31
#50/// BANGBOO BLOG /// From 2019-09-01 To 2019-09-30
#51/// BANGBOO BLOG /// On 2020-03-01
#52/// BANGBOO BLOG /// On 2020-04-01
#53Windows env tips
#54恐慌からの脱出方法
#55MARUTAI
#56A Rainbow Between Clouds‏
#57ER
#58PDF in cellphone with microSD
#59DJ
#60ICOCA
#61Departures
#62Update your home page
#63CSS Grid
#64恐慌からの脱出方法
#65ハチロクカフェ
#66/// BANGBOO BLOG /// On 2016-03-31
#67/// BANGBOO BLOG /// From 2017-02-01 To 2017-02-28
#68/// BANGBOO BLOG /// From 2019-07-01 To 2019-07-31
#69/// BANGBOO BLOG /// From 2019-10-01 To 2019-10-31
#70/// BANGBOO BLOG /// On 2020-01-21
#71Bike
#72Where Hiphop lives!!
#73The team that always wins
#74Tora Tora Tora
#75Blog Ping
#76無料ストレージ
#77jQuery - write less, do more.
#78Adobe Premire6.0 (Guru R.I.P.)
#79PC SPEC 2007.7
#80Google Sitemap
#81Information privacy & antispam law
#82Wifi security camera with solar panel & small battery
#83Hope get back to normal
#84Vice versa
#85ハイエースのメンテ
#86Camoufla
#87α7Ⅱ
#88Jack up Hiace
#89Fucking tire
#90Big D
#914 Pole Plug
#925-year-old shit
#93Emancipation Proclamation
#94Windows env tips
#95Meritocracy
#96Focus zone
#97Raspberry Pi
#98Mind Control
#99Interview
#100Branding Excellent
Category
Recent Entry
Trackback
Comment
Archive
<     November 2025     >
Sun Mon Tue Wed Thi Fri Sat
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30
Link