【Django】too many SQL variablesのエラーが発生

はじめに

こんにちは、SHOJIです。

本記事はDjangoで発生したエラー対応の備忘録です。 今回のエラーはプログラムの作りに問題があるゆえに発生したしょうもないエラーですが、こんな制限があるんだなーと面白く感じたので記事にしています。

Model.objects.filter() 実行でエラーが発生

DjangoのQuerySetでModel.objects.filter()を実行したところ、django.db.utils.OperationalError: too many SQL variables というエラーが発生しました。

エラーが発生した箇所のプログラムは、テーブルAのカラムaとカラムbが特定の組合せであれば取得するというもので、さらにその組合せのパターンが多数存在するものでした。 SQLで表すと、SELECT * FROM tableA WHERE (col_a = 'X1' AND col_b ='Y1') OR (col_a = 'X2' AND col_b ='Y2') ... のような形です。

エラーメッセージから予想がつくと思うのですが、上記のSQLを実現するため、プログラムでは必要な全ての条件をQオブジェクトにaddしfilterメソッドに渡していました。

conditions = Q()
conditions.add(Q(col_a ='X1', col_b ='Y1'), Q.OR)
conditions.add(Q(col_a ='X2', col_b ='Y2'), Q.OR)
#(以下、省略)
tableA.objects.filter(conditions)

実際には、conditions.add() のところは条件数分ループを回しているので書き方は違うのですが、処理としてはこのようなことを行っています。 この場合、conditionsの条件数が500を超えると too many SQL variables のエラーが発生します。 はい、エラーメッセージがおっしゃる通りです。SQLの変数が多すぎますね……。

おわりに

というわけで、Model.objects.filter() のちょっと珍しいエラーについてでした。 普通はこんな雑なプログラムはソースレビューで弾かれるでしょうから、Djangoを使っていてもまず見ることはないかと思います。

そして、ここまで書いてふと思ったのですが、これって本当にDjango側で出しているエラーなんでしょうか。 もしかしたら上限はDBMSによって変わるかもしれないですね。手元にDjango環境がないので確認できていませんが、接続先のデータベースをSQLite3からPostgreSQLに変えてどうなるか試してみたいと思いました。

なお、そもそものプログラムが汚すぎる点については、テスト用の書き捨てプログラムであったということでお目こぼし願います笑

【Windows】Hyper-V上のCentOSにSSH接続する

はじめに

こんにちは、SHOJIです。

今回は、前回Hyper-Vに追加したCentOS7にSSHの設定を入れてリモート操作できるようにします。

前回の記事はこちら。

deadline-driven-developer.hatenablog.com

OpenSSHの設定

こちらを参考に実施しました。

kajuhome.com

  1. yum list installed | grep ssh コマンドで openssh-serverが存在するか確認する。 存在しない場合は、sudo yum -y install openssh-server コマンドでインストールする。

  2. systemctl start sshd.service コマンドで openssh-serverを起動する。

  3. ssh-keygen -t rsa コマンドで秘密鍵・公開鍵を作成する。

  4. mv /home/[user_name]/.ssh/id_rsa.pub /home/linux/.ssh/authorized_keys コマンドで公開鍵を移動する。

  5. chmod 700 /home/[user_name]/.ssh コマンド、chmod 600 /home/[user_name]/.ssh/authorized_keys コマンドでパーミッションを変更する。

秘密鍵の受け渡し

Windowsへの受け渡し

「OpenSSHの設定」で作成した秘密鍵Hyper-Vのホスト(Windows10)へ受け渡す。 受け渡し方法はいくつかあるが、ここではHyper-Vのホスト(Windows10)に共有フォルダを作成し、CentOSからCIFSでファイルを送る。

Windows側の設定

  1. 任意の場所にフォルダを作成し、プロパティの共有タブから共有フォルダに設定する。

CentOS側の設定

  1. sudo yum install -y samba-client cifs-utils コマンドを実行し、必要な機能をインストールする。

  2. sudo mkdir /mnt/windows コマンドでマウント先ディレクトリを作成する。

  3. smbclient -L //[ip_address] -U [windows_user_name] コマンドでディレクトリが見えるか確認する。

    do_connect: Connection to [ip_address] failed のメッセージが出る場合、Windowsファイアウォールがブロックしている可能性あり。

    Unable to connect with SMB1 -- no workgroup available のメッセージが出るのはSMB1でアクセスしているため。次のコマンドで vers=2.0 と指定するとSMB2が使用されるため無視してよい。

  4. sudo mount.cifs [share_directory_path(ex.//192.168.1.10/share/)] /mnt/windows -o vers=2.0,username=[windows_user_name] コマンドでディレクトリをマウントする。

  5. df -h コマンドでマウントできていることを確認する。

  6. sudo cp /home/[user_name]/.ssh/id_rsa /mnt/windows コマンドで秘密鍵をコピーする。

Ubuntuへの受け渡し

こちらを参考に実施しました。

www.digitalocean.com

qiita.com

新たにUbuntu端末を用意してSSH接続する場合の操作です。 Ubuntu側をNFSサーバ、CentOSNFSクライアントにして、秘密鍵を受け渡しています。 今回はLinux間のファイル共有の要素を取り入れたい&プライベートなネットワークでのファイル授受のため、NFSでやり取りしていますが、NFSは暗号化されたセキュアな授受方法ではないことはご承知おきください。

Ubuntu側の設定

  1. sudo apt install nfs-kernel-server コマンドを実行し、必要な機能をインストールする。

  2. 任意の場所にディレクトリを作成し、sudo chown nobody:nogroup /home/[user_name]/share コマンドで所有者をnobodyに変更する。

  3. /etc/exportsファイルに[directory_path] *(rw, sync, no_subtree_check) と追記する。

  4. sudo exports -ar コマンドでディレクトリをエクスポートする。

  5. sudo exportfs -v コマンドでディレクトリがエクスポートされていることを確認する。

CentOS側の設定

  1. sudo yum install showmount コマンドを実行し、必要な機能をインストールする。
  2. mkdir /mnt/ubuntu コマンドを実行し、マウント先ディレクトリを作成する。
  3. showmount -e [ubuntu_ip_address] コマンドを実行し、Ubuntu側で設定したディレクトリが見えることを確認する。
  4. sudo mount -t nfs [ubuntu_ip_address]:[directory_path] /mnt/ubuntu コマンドでディレクトリをマウントする。
  5. df -h コマンドでマウントできていることを確認する。
  6. sudo cp /home/[user_name]/.ssh/id_rsa /mnt/ubuntu コマンドで秘密鍵をコピーする。

秘密鍵を用いたSSH接続

  1. ssh -l [centos_user_name] -i [private_key_path] [centos_ip_address] コマンドでSSH接続を行う。

    (Windows10、Ubuntuともに同じコマンドで接続できる)

  2. exit コマンドでSSH接続を終了する。

おわりに

これでCentOSSSH接続でリモート操作を行えるようになりました。 次回はこの上にWebサービスを載せていきたいと思います。

【Windows】Hyper-VにCentOSを追加する

はじめに

こんにちは、SHOJIです。

今回はWindows 10 HomeのHyper-V上でCentOS7を使用するまでの手順を記載します。 CentOSはサポート終了が告知されていますが、色々な事情からまだ使いたいシーンがありますね。

今回はいつにも増して参考にさせていただいたサイトが多く、ほぼツギハギ記事です。 そのため、本記事はリンクを貼って参考サイトを紹介するにとどめるべきかとも思いましたが、参考サイトが消失してしまうリスクや自分の備忘録になることから記事としてまとめています。

本記事がお役に立った場合は、参考サイト様にいいねやスターをつけていただけますと幸いです。

Window 10 HomeでHyper-Vを有効にする

こちらを参考に実施しました。

HomeでHyper-Vを使う裏技!!【Windows10/Windows11両方対応】 - YouTube

スクリプトはこちらから。

Installation of Hyper V on windows 10 home · opustecnica/public Wiki · GitHub

f:id:deadline-driven-developer:20220311092342p:plain

(コマンドは参考サイトから取得していただきたく、画像にしています)

Hyper-VにCentOS7の仮想環境を追加する

こちらを参考に実施しました。

Hyper-VのゲストOSをネットワークに接続する(通常版) | ばったんの技術系ブログ

Hyper-VでLinux CentOS-7の構築やってみよう!(初心者向け)|アイシーティーリンク株式会社 公式ブログ|note

  1. 仮想スイッチマネージャーから「外部」仮想スイッチを「外部ネットワーク」を選択して作成する。

  2. 新規の仮想マシンを「第1世代」で作成する。

  3. ネットワークの構成で、「1」で作成した仮想スイッチを指定する。

  4. インストールオプションで、「イメージ ファイル」としてCentOSのisoファイルを指定する。

    ※isoファイルはCentOSのサイトからダウンロードする。

    ダウンロード先:https://www.centos.org/centos-linux/

    ダウンロード方法:「Architectures」-「x86_64」を選択し、適当なダウンロードサイトからMinimal版をダウンロード。

f:id:deadline-driven-developer:20220311093317p:plain

CentOS7を起動し、NICを追加する

  1. nmcli deviceコマンドでNICの状態を確認する。 f:id:deadline-driven-developer:20220311093354p:plain

  2. eth0がdisconnectedの場合、sudo vi /etc/sysconfig/network-scripts/ifcfg-eth0コマンドで設定ファイルを開き、ONBOOT=yesにする。これにより次回から起動時にeth0が自動起動する。

  3. sudo ifup eth0コマンドでNICを有効にする。

ネットワークの疎通確認を行う

  1. ping www.google.com コマンドで応答が返ってくるか確認する。

おわりに

ここまででHyper-V上に外部アクセス可能なCentOSを構築するところまではできました。 次回はCentOSSSH接続を行いたいと思います。

【Android】com.google.android.material:materialとandroidx.appcompat:appcompatをimplementationするとエラーが発生する

はじめに

こんにちは、SHOJIです。
Android開発にて、複数ライブラリをimplementationしたときにエラーが発生するという事象に遭遇しました。

implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.appcompat:appcompat:1.4.0'

エラーが発生

最初に出たエラーがこちらです。

/xxxxx/src/main/res/values/attrs.xml:12:1: Duplicate value for resource 'attr/backgroundColor' with config 'DEFAULT' and product ''. Resource was previously defined here: /root/.gradle/caches/transforms-2/files-2.1/97ed20c4805122cb37926be8f7f55040/material-1.4.0/res/values/values.xml:2976:4: .

これに対しては、Resource was previously defined hereという一文があったので、attrs.xmlとライブラリで二重に定義されている?と考え、attrs.xml:12:1の一行を削除しました。

すると今度はこちらのエラーが出てきました。

ERROR:/home/n/Android/common/build/intermediates/res/merged/release/values/values.xml:6183: AAPT: error: resource android:attr/lStar not found.

lStarが見つからないと言っていますね。

何をやったら直ったか

androidx.appcompat:appcompatのバージョンを1.0.0に変更しました。

implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.appcompat:appcompat:1.0.0'

単純に、androidx.appcompat:appcompat:1.4.0でlStarがなくなってそれで出ていたようです。

不思議なのが、このようにcom.google.android.material:materialだけにしてもエラーは解消されるんですよね。

implementation 'com.google.android.material:material:1.4.0'

一つ目のエラーが消えるのは二重定義だとすると納得なのですが、lStarがない方のエラーも出ないのは不思議です。

ここから考えられることは、僕のプロジェクトはlStarを必要としてなくて、androidx.appcompat:appcompat:1.4.0lStarを必要としているということなのですが、それだと致命的なエラーなので放置されているのはおかしく、何か理解が足りていないように思います。

こういう事象もあったので、記事のタイトルは二つのライブラリを参照するとエラーが発生するとしています。

最後に

まとめるとチョロいエラーに見えるのですが、実際は丸三日は悩みました。

ハマった理由としては、二つエラーがあったことで attrs.xml:12:1の一行を削除したからlStarのエラーが出てきたんじゃないか?という誤解が生まれ、attrs.xml:12:1の行を残しつつ Duplicate value for resource エラーを解消する方法を調査していたのが大きいですね。

そしてなぜそう考えたかと言えば、1.0.0にあったものがbeta版でもないのに1.4.0でなくなっているわけないだろうと考えたからです。 そもそも様々なエラーが出てあれこれ直した最中に出てきたので、絶対に自分の作業ミスだと思っていましたから、ライブラリの問題ではないという先入観がありました。

Androidのビルドってたまに本質でないエラーメッセージを出すことがあって、メッセージを信じられなかったことも敗因だと思います。
まとめると、思い込みは危険ってことですね。重々承知していたつもりなんですけれど……笑

以上です。

【Android】「Plugin [id: 'com.android.Library'] was not found in any of the following sources」が発生したときに実施したこと

はじめに

こんにちは、SHOJIです。

Android Studioで発生したエラーの対処方法を記載します。
正直、原因も直った理由も分からない状態です。
エラーの再現もできないので、この解消方法に再現性があるのかも定かではありません。

Sync Project With Gradle Filesでエラーが発生

古いAndroidプロジェクトを新しいAndroid studioで開いて、新しいSDKにNDKに指示されるままツール類をダウンロードし、古い参照を新しい参照(AndroidX)に置き換えて、ようやくエラーが無くなった頃に出てきたのが、「Plugin [id: 'com.android.Library'] was not found in any of the following sources」でした。
開発環境はこのような状態です。
OS:

Ubuntu 18.04.3 LTS

Android Studio:

Android Studio Arctic Fox | 2020.3.1 Patch 3 Build #AI-203.7717.56.2031.7784292, built on October 1, 2021 Runtime version: 11.0.10+0-b96-7249189 amd64 VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o. Linux 5.4.0-90-generic GC: G1 Young Generation, G1 Old Generation Memory: 1280M Cores: 4 Registry: external.system.auto.import.disabled=true Non-Bundled Plugins: org.jetbrains.kotlin Current Desktop: ubuntu:GNOME

SDK Version:

compileSdkVersion 29 defaultConfig { minSdkVersion 16 targetSdkVersion 29 }


で、色々やったんですが、上手く行かず、サンクコストによって諦めるタイミングも見失ったところでエラーが消えました。

何をやったら直ったか

Project Structureを開いて、Android Gradle Plugin Version をこのときの一番低いバージョンの2.3.0に変更し、Gradle VersionもAndroid Gradle Plugin Versionに対応するもので最も低い3.3に変更しました。
その上で再度、Sync Project With Gradle Files を行ったところ、このようなメッセージが表示され、

Unable to start the daemon process.

The project uses Gradle 3.3 which is incompatible with Java 11 or newer.

Possible solution:

  • Upgrade Gradle wrapper to 4.8 version and re-import the project

Upgrade Gradle wrapper to 4.8 version and re-import the project がリンクになっていたので、お好きにどうぞと思ってクリックしてダウンロードと再インポートを行ったら、「Plugin [id: 'com.android.Library'] was not found in any of the following sources」のエラーが消えました。

その後、Gradleのバージョンを元々設定していたバージョンに戻したのですが、エラーは消えたままでした。

戻したバージョン

Android Gradle Plugin Version: 3.5.4 Gradle Version: 5.4.1


と、ここまで書いて思ったのですが、Gradleのバージョンを戻してもエラーが消えるということは、re-import the project の部分が効いてる気がしますね。 再インポートすることで開発環境の持つ設定か何かがリセットされて、それで直ったとか。


このあたり分かる方いらっしゃったらぜひ教えてください。

最後に

Android開発は楽しいんですが、開発環境周りのあれこれは本当にしんどいです。
個人的に開発環境に関してはMicrosoftが好きですね。

【Windows】Windows server 2016でgit pushするとcurl_global_init failedが発生する

はじめに

こんにちは、SHOJIです。
本記事は、Windows server 2016で git push した際に「fatal: curl_global_init failed」が発生する場合の備忘録です。

事象

Windows server 2016 環境にGitクライアントをインストールしたところ、git add や git commitはできるのに、git pushすると「fatal: curl_global_init failed」が発生するという状況に出会いました。

解決方法

調べたところ、Windows server 2016でCurlが動かない不具合があるようです。
こちらが当事象について議論しているCurlのIssueです。

github.com


読んで頂くと書いていますが、Windows UpdateKB4103723の更新プログラムをインストールすれば良いとのこと。

support.microsoft.com

早速試してみたところ、無事にエラーが解消されました。
なお、KB4103723以外にもインストールすべき更新プログラムの候補が挙がっていますが、僕の環境では上記の更新プログラムだけでエラー解消できています。

おわりに

今回のエラー、先駆者の方々が情報を残してくれてなければ完全に詰んでました。
情報を載せてくださる方々には本当に感謝です。


DLLが不足していたことによるエラーが更新プログラムの適用で直っているようですが、そもそもどうしてそういう状態なのか、Windows Updateのどの機能追加(あるいは修正)に伴う影響なのかはよく分からず。


こういうところは、Windows使ってて怖いなと思いますね。
まあ、Linuxだったら原因分かるまで中身追うのかといえば追わないでしょうけれど……笑

【読書感想文】アルゴリズム図鑑のススメ

はじめに

こんにちは、SHOJIです。

本記事ではアルゴリズム図鑑を読んだ感想を書いていきたいと思います。

http://www.amazon.co.jp/dp/4798149772

更新が滞っている理由にも繋がるのですが、昨年子どもが生まれてアプリ開発の時間が全然取れず、空き時間は本を読むことが増えました。

結構色々読んだので読書録代わりに感想書いていきたいですね。

 

アルゴリズム図鑑ってどんな本?

名前の通り、アルゴリズムが色々載ってる本です。

アルゴリズムとは、何らかの目的を達成するための計算方法や手順のことです。

 

有名かつ分かりやすいもので言うとソート(並び替え)のアルゴリズムがありますね。

10個の数値を小さい順に並べたい場合、一つずつ全部比較しても最終的には並べ替えられますが、アルゴリズムによっては大きく計算量を抑えて並べ替えることができます。

 

アルゴリズム図鑑では、ソート、探索、暗号方式等のアルゴリズムが、分かりやすい図付きで解説されています。説明書きを読むと、26のアルゴリズム+7つのデータ構造とのことです。

結構多く載っていますが、スラスラ読める内容でしたので、読んでいて苦になることはありませんでした。

逆に一つ一つの記載が薄くて不十分ということもなく(これは求めるレベルにもよりますが……)。

 

目次と感想

目次

各章、何が書いてあるかは目次の通りです。

1章のデータ構造はプログラミングをしている方ならすでに知っている内容かなと思います。

2章のソートはプログラマなら誰もが知っておくべきアルゴリズムですが、意外に知らない方もいる内容なので(恥ずかしながら僕も曖昧でした)、自信のない方は本書を読んで抑えておくことをオススメします。世間的にソートアルゴリズムくらいは知ってて当然みたいな風潮がありますし……。いや、これは僕の気のせいかもしれませんが、ただ基本情報技術者試験でも出題されるので知っておくに越したことはないと思います。

個人的に面白かったのは4章と5章ですね。特に5章の暗号方式のアルゴリズムは、勉強しなければいけないと思いつつ敷居が高そうで敬遠していた内容だったので、概要レベルでも知ることができたのはありがたかったです。4章のグラフ探索はあまり使う機会はなさそうですが、読み物として面白かったです。機会があればこういうアルゴリズムを使うシステムに関わってみたいですね。

 

全編に言えるのですが、図が非常に分かりやすいです。カラーかつ手順ごとの変化が示されるので、アルゴリズムの勉強が初めてでも抵抗はないと思います。

これを読めば競技プログラミングで課せられるような課題を解けるかと言えばNOですが、その手前のこれからアルゴリズムの勉強を始めていきたい方にとっては役に立つはずです。逆に基本的なアルゴリズムは理解していて、もっと深い知識を得たいという方にはマッチしない内容です。

最後に

本の内容に触れると、そのままアルゴリズムの説明になってしまうので避けたのですが、いつも以上にぼんやりした記事になってますね。

ただの宣伝になってしまいますが、2,500円でこの内容は安いので、購入悩んでる方は買ってよいと思います。少なくとも損はしないです。