【mac】Django プロジェクトで PostgreSQL のデータベースを利用する(仮想環境内)

Python 仮想環境内で Django プロジェクト用データベースを PostgreSQL で作成し、Django プロジェクトと紐づける方法を書きます。

今回は例として「sample_db」というデータベース作成し、プロジェクトと紐づけます。

  1. PostgreSQL で新規のデータベースを作成
  2. Django プロジェクトとデータベースの紐付け
  3. 仮想環境で接続用モジュールをインストール
  4. ちなみに
  5. 参考書籍

1. PostgreSQL で新規のデータベースを作成

PostgreSQL を起動し「sample_db」という名前のデータベースを作成します。

% sudo brew services start postgresql
% createdb sample_db

「psql -l」でデータベースのリストを表示すると、「sample_db」が作成されたのが確認できます。

% psql -l
                                         List of databases
   Name    |      Owner       | Encoding | Collate | Ctype |           Access privileges           
-----------+------------------+----------+---------+-------+---------------------------------------
 postgres  | ユーザー名         | UTF8     | C       | C     | 
 sample_db | ユーザー名         | UTF8     | C       | C     | 
 template0 | ユーザー名         | UTF8     | C       | C     | =c/ユーザー名                  +
           |                  |          |         |       | ユーザー名=CTc/ユーザー名
 template1 | ユーザー名         | UTF8     | C       | C     | =c/ユーザー名                  +
           |                  |          |         |       | ユーザー名=CTc/ユーザー名
(4 rows)

ちなみにデータベースを削除したい場合は「dropdb sample_db」と入力します。

2. Django プロジェクトとデータベースの紐付け

Django プロジェクトの settings.py を変更し、先ほど新規作成したデータベースを紐付けます。

プロジェクト作成時に自動作成された settings.py の内容は下記の通り。

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}

これを下記の様に変更します。

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'sample_db',
        'USER': os.environ.get('DB_USER'),
        'PASSWORD': os.environ.get('DB_PASSWORD'),
        'HOST': '',
        'PORT': '',
    }
}

またその際にファイル上部に下記を追記し os モジュールをインポートします。

import os

3. 仮想環境で接続用モジュールをインストール

Python で PostgreSQL データベースに接続するために、接続用ドライバのモジュールが必要となります。もっとも多く使われている psycopg2 というモジュールをインストールします。

仮想環境に入った状態で「pip install psycopg2-binary」を実行します。

(sample_venv) % pip install psycopg2-binary
Collecting psycopg2-binary
  Downloading https://files.pythonhosted.org/packages/2c/85/c26507efb110f5a91f503e517f1db55f12ebecb001ff224b2cea234a07ef/psycopg2_binary-2.8.6-cp38-cp38-macosx_10_9_x86_64.macosx_10_9_intel.macosx_10_10_intel.macosx_10_10_x86_64.whl (1.5MB)
     |████████████████████████████████| 1.5MB 7.1MB/s 
Installing collected packages: psycopg2-binary
Successfully installed psycopg2-binary-2.8.6
WARNING: You are using pip version 19.2.3, however version 21.0.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
(sample_venv) % 

4. ちなみに

PyCharm の runserver を実行した時に下記のエラーが出て一瞬焦りましたが、PostgreSQL を起動したら治りました。

django.db.utils.OperationalError: could not connect to server: No such file or directory

ちなみのちなみに、settings.py の「DATABASES」の部分をコメントアウトなどするとデータベースを起動していなくても問題なく runserver を実行できます。

5. 参考書籍

僕は始め下記の書籍に沿って Django の全体像を勉強しました。書籍は PostgreSQL を使用した開発になっているので参考にしてみてください。

動かして学ぶ! Python Django開発入門 (NEXT ONE)

Mac に PostgreSQL をインストールする

Homebrew を使って PostgreSQL の最新バーションをインストールします。

実行環境:maxOS Big Sur バージョン 11.2.2

  1. PostgreSQL をインストールする
  2. PostgreSQL を起動・終了する

PostgreSQL をインストールする

下記のコマンドを実行します。

% brew install postgresql

ログが表示されます。(下記のログには Homebrew 自体の自動アップデートなど余分なものも含まれてます。)

% brew install postgresql            
Updating Homebrew...
==> Auto-updated Homebrew!
Updated 1 tap (homebrew/core).
==> New Formulae
aerc                       hblock                     php@7.4
aida-header                heppdt2                    pickle
aliddns                    hexo                       pkger
ansible@2.9                htmltest                   projectm
arturo                     iconsur                    ptpython
as-tree                    indicators                 pyqt-3d
atkmm@2.28                 inframap                   pyqt-builder
attr                       isl@0.18                   pyqt-networkauth
aws-console                isort                      pyqt@5
aws-rotate-key             jpeg-xl                    pyside@2
bandit                     jql                        python-tabulate
bas55                      json5                      qt-libiodbc
bit-git                    k3sup                      qt-mariadb
blaze                      kcgi                       qt-mysql
bpython                    keptn                      qt-percona-server
bpytop                     khiva                      qt-postgresql
cairomm@1.14               klee                       qt-unixodbc
cargo-audit                ko                         rain
cargo-edit                 kotlin-language-server     rdkit
cargo-watch                kube-linter                regipy
cfn-flip                   kubecm                     richmd
cfn-format                 kubergrunt                 rm-improved
chars                      kubevela                   rtl_433
checkov                    lab                        rttr
cherrytree                 latino                     ruby@2.7
clash                      libbsd                     saml2aws
cloudflare-wrangler        libcap                     showkey
coin3d                     libcap-ng                  snowpack
condure                    libfuse                    spack
counterfeiter              libmd                      sqlancer
cpplint                    libnsl                     sqlc
crane                      libpinyin                  strace
crcany                     libpipeline                t-rec
crispy-doom                libprelude                 taskwarrior-tui
curlie                     librttopo                  tctl
cyrus-sasl                 libslirp                   tendermint
dasel                      libtirpc                   terracognita
datalad                    libva                      terraform@0.13
delve                      libvdpau                   tgenv
device-mapper              libvnc                     thrax
dnsx                       libxml++@4                 tm
docui                      libxml++@5                 tomcat@9
dog                        libxp                      trec_eval
dotenv-linter              linux-headers              tree-sitter
dprint                     logswan                    truffle
driftctl                   lp_solve                   utf8cpp
dstask                     lua@5.3                    v2ray
duf                        luajit-openresty           vc
easy-rsa                   luv                        vint
efm-langserver             magic_enum                 vitess
enzyme                     markdownlint-cli           vsh
evernote2md                massdns                    vulture
f3d                        md4c                       waffle
fizz                       mermaid-cli                wangle
flow-cli                   mesa-glu                   wayland
flux                       mockery                    wayland-protocols
fnm                        mpdecimal                  wllvm
forge                      msc-generator              xbitmaps
gallery-dl                 muffet                     xcb-util
gcalcli                    name-that-hash             xcb-util-cursor
gdu                        ncspot                     xcb-util-image
geph4                      nicotine-plus              xcb-util-keysyms
ghc@9                      node@14                    xcb-util-renderutil
gitlint                    nuclei                     xcb-util-wm
giza                       oakc                       xcbeautify
glab                       ocaml-zarith               xcinfo
glibc                      open-adventure             xcprojectlint
go@1.15                    openalpr                   xinput
gofumpt                    openjdk@8                  xkeyboardconfig
gojq                       openmama                   xorgrgb
googletest                 openmodelica               xray
gopass-jsonapi             or-tools                   xterm
gopls                      oras                       yh
goredo                     osmcoastline               ykdl
gosec                      overdrive                  youtube-dlc
gost                       ox                         youtubedr
gping                      parliament                 yq@3
grokj2k                    pcalc                      yubikey-agent
grokmirror                 pdftilecut                 zsh-async
gtkmm4                     pdm
h2spec                     phive
==> Updated Formulae
Updated 5020 formulae.
==> Renamed Formulae
glibmm@2.64 -> glibmm@2.66               pangomm@2.42 -> pangomm@2.46
gtk+4 -> gtk4                            prest -> prestd
ht-rust -> xh                            qt5 -> qt@5
now-cli -> vercel-cli
==> Deleted Formulae
avian                      gobby                      scw@1
boost@1.55                 godep                      stlviewer
boost@1.59                 llvm@6                     unp64
confluent-platform         meson-internal             unrar
curl-openssl               mysql-connector-c++@1.1    woboq_codebrowser
dtrx                       ori                        xspin
fmsx                       pgplot
geant4                     rmtrash

==> Downloading https://homebrew.bintray.com/bottles/icu4c-68.2.big_sur.bottle.t
==> Downloading from https://d29vzk4ow07wi7.cloudfront.net/ba2fd8c7d37025c93db6b
######################################################################## 100.0%
==> Downloading https://homebrew.bintray.com/bottles/openssl%401.1-1.1.1j.big_su
==> Downloading from https://d29vzk4ow07wi7.cloudfront.net/5725361adcd088a5b4fb2
######################################################################## 100.0%
==> Downloading https://homebrew.bintray.com/bottles/krb5-1.19.1.big_sur.bottle.
==> Downloading from https://d29vzk4ow07wi7.cloudfront.net/d544c1111503eb27b253e
######################################################################## 100.0%
==> Downloading https://homebrew.bintray.com/bottles/readline-8.1.big_sur.bottle
==> Downloading from https://d29vzk4ow07wi7.cloudfront.net/2cc3a9582e3c7e21eb3c2
######################################################################## 100.0%
==> Downloading https://homebrew.bintray.com/bottles/postgresql-13.2_1.big_sur.b
==> Downloading from https://d29vzk4ow07wi7.cloudfront.net/67a547842ae49911d301d
######################################################################## 100.0%
==> Installing dependencies for postgresql: icu4c, openssl@1.1, krb5 and readline
==> Installing postgresql dependency: icu4c
==> Pouring icu4c-68.2.big_sur.bottle.tar.gz
==> Caveats
icu4c is keg-only, which means it was not symlinked into /usr/local,
because macOS provides libicucore.dylib (but nothing else).

If you need to have icu4c first in your PATH, run:
  echo 'export PATH="/usr/local/opt/icu4c/bin:$PATH"' >> ~/.zshrc
  echo 'export PATH="/usr/local/opt/icu4c/sbin:$PATH"' >> ~/.zshrc

For compilers to find icu4c you may need to set:
  export LDFLAGS="-L/usr/local/opt/icu4c/lib"
  export CPPFLAGS="-I/usr/local/opt/icu4c/include"

==> Summary
🍺  /usr/local/Cellar/icu4c/68.2: 259 files, 72.5MB
==> Installing postgresql dependency: openssl@1.1
==> Pouring openssl@1.1-1.1.1j.big_sur.bottle.tar.gz
==> Caveats
A CA file has been bootstrapped using certificates from the system
keychain. To add additional certificates, place .pem files in
  /usr/local/etc/openssl@1.1/certs

and run
  /usr/local/opt/openssl@1.1/bin/c_rehash

openssl@1.1 is keg-only, which means it was not symlinked into /usr/local,
because macOS provides LibreSSL.

If you need to have openssl@1.1 first in your PATH, run:
  echo 'export PATH="/usr/local/opt/openssl@1.1/bin:$PATH"' >> ~/.zshrc

For compilers to find openssl@1.1 you may need to set:
  export LDFLAGS="-L/usr/local/opt/openssl@1.1/lib"
  export CPPFLAGS="-I/usr/local/opt/openssl@1.1/include"

==> Summary
🍺  /usr/local/Cellar/openssl@1.1/1.1.1j: 8,071 files, 18.5MB
==> Installing postgresql dependency: krb5
==> Pouring krb5-1.19.1.big_sur.bottle.tar.gz
==> Caveats
krb5 is keg-only, which means it was not symlinked into /usr/local,
because macOS already provides this software and installing another version in
parallel can cause all kinds of trouble.

If you need to have krb5 first in your PATH, run:
  echo 'export PATH="/usr/local/opt/krb5/bin:$PATH"' >> ~/.zshrc
  echo 'export PATH="/usr/local/opt/krb5/sbin:$PATH"' >> ~/.zshrc

For compilers to find krb5 you may need to set:
  export LDFLAGS="-L/usr/local/opt/krb5/lib"
  export CPPFLAGS="-I/usr/local/opt/krb5/include"

==> Summary
🍺  /usr/local/Cellar/krb5/1.19.1: 162 files, 5.2MB
==> Installing postgresql dependency: readline
==> Pouring readline-8.1.big_sur.bottle.tar.gz
==> Caveats
readline is keg-only, which means it was not symlinked into /usr/local,
because macOS provides BSD libedit.

For compilers to find readline you may need to set:
  export LDFLAGS="-L/usr/local/opt/readline/lib"
  export CPPFLAGS="-I/usr/local/opt/readline/include"

==> Summary
🍺  /usr/local/Cellar/readline/8.1: 48 files, 1.6MB
==> Installing postgresql
==> Pouring postgresql-13.2_1.big_sur.bottle.tar.gz
==> /usr/local/Cellar/postgresql/13.2_1/bin/initdb --locale=C -E UTF-8 /usr/loca
==> Caveats
To migrate existing data from a previous major version of PostgreSQL run:
  brew postgresql-upgrade-database

This formula has created a default database cluster with:
  initdb --locale=C -E UTF-8 /usr/local/var/postgres
For more details, read:
  https://www.postgresql.org/docs/13/app-initdb.html

To have launchd start postgresql now and restart at login:
  brew services start postgresql
Or, if you don't want/need a background service you can just run:
  pg_ctl -D /usr/local/var/postgres start
==> Summary
🍺  /usr/local/Cellar/postgresql/13.2_1: 3,218 files, 42.6MB
==> `brew cleanup` has not been run in 30 days, running now...
Removing: /Users/ユーザー名/Library/Caches/Homebrew/mysql--8.0.21_1.catalina.bottle.tar.gz... (80.4MB)
Removing: /usr/local/Cellar/openssl@1.1/1.1.1h... (8,067 files, 18.5MB)
Removing: /Users/ユーザー名/Library/Caches/Homebrew/openssl@1.1--1.1.1h.catalina.bottle.tar.gz... (5.4MB)
Removing: /Users/ユーザー名/Library/Caches/Homebrew/protobuf--3.13.0.catalina.bottle.tar.gz... (4.8MB)
Removing: /Users/ユーザー名/Library/Logs/Homebrew/mysql... (1.1KB)
Removing: /Users/ユーザー名/Library/Logs/Homebrew/protobuf... (64B)
Pruned 1 symbolic links and 2 directories from /usr/local
==> Upgrading 2 dependents:
mysql 8.0.21_1 -> 8.0.23_1, wget 1.20.3_2 -> 1.21.1
==> Upgrading mysql 8.0.21_1 -> 8.0.23_1 
==> Downloading https://homebrew.bintray.com/bottles/protobuf-3.15.5.big_sur.bot
==> Downloading from https://d29vzk4ow07wi7.cloudfront.net/872baaeb92aaaaa8d2634
######################################################################## 100.0%
==> Downloading https://homebrew.bintray.com/bottles/mysql-8.0.23_1.big_sur.bott
==> Downloading from https://d29vzk4ow07wi7.cloudfront.net/9e9e4b5bfcad47adfbf7f
######################################################################## 100.0%
==> Installing dependencies for mysql: protobuf
==> Installing mysql dependency: protobuf
==> Pouring protobuf-3.15.5.big_sur.bottle.tar.gz
==> Caveats
Emacs Lisp files have been installed to:
  /usr/local/share/emacs/site-lisp/protobuf
==> Summary
🍺  /usr/local/Cellar/protobuf/3.15.5: 211 files, 17.7MB
==> Installing mysql
==> Pouring mysql-8.0.23_1.big_sur.bottle.tar.gz
==> Caveats
We've installed your MySQL database without a root password. To secure it run:
    mysql_secure_installation

MySQL is configured to only allow connections from localhost by default

To connect run:
    mysql -uroot

To have launchd start mysql now and restart at login:
  brew services start mysql
Or, if you don't want/need a background service you can just run:
  mysql.server start
==> Summary
🍺  /usr/local/Cellar/mysql/8.0.23_1: 298 files, 297.7MB
Removing: /usr/local/Cellar/mysql/8.0.21_1... (290 files, 291.2MB)
==> Upgrading wget 1.20.3_2 -> 1.21.1 
==> Downloading https://homebrew.bintray.com/bottles/gettext-0.21.big_sur.bottle
==> Downloading from https://d29vzk4ow07wi7.cloudfront.net/a025e143fe3f5f7e24a93
######################################################################## 100.0%
==> Downloading https://homebrew.bintray.com/bottles/wget-1.21.1.big_sur.bottle.
==> Downloading from https://d29vzk4ow07wi7.cloudfront.net/e6ea2a50b8196206f7072
######################################################################## 100.0%
==> Installing dependencies for wget: gettext
==> Installing wget dependency: gettext
==> Pouring gettext-0.21.big_sur.bottle.tar.gz
🍺  /usr/local/Cellar/gettext/0.21: 1,953 files, 19.8MB
==> Installing wget
==> Pouring wget-1.21.1.big_sur.bottle.tar.gz
🍺  /usr/local/Cellar/wget/1.21.1: 88 files, 4MB
Removing: /usr/local/Cellar/wget/1.20.3_2... (50 files, 4.0MB)
==> Checking for dependents of upgraded formulae...
==> No broken dependents found!
==> Caveats
==> icu4c
icu4c is keg-only, which means it was not symlinked into /usr/local,
because macOS provides libicucore.dylib (but nothing else).

If you need to have icu4c first in your PATH, run:
  echo 'export PATH="/usr/local/opt/icu4c/bin:$PATH"' >> ~/.zshrc
  echo 'export PATH="/usr/local/opt/icu4c/sbin:$PATH"' >> ~/.zshrc

For compilers to find icu4c you may need to set:
  export LDFLAGS="-L/usr/local/opt/icu4c/lib"
  export CPPFLAGS="-I/usr/local/opt/icu4c/include"

==> openssl@1.1
A CA file has been bootstrapped using certificates from the system
keychain. To add additional certificates, place .pem files in
  /usr/local/etc/openssl@1.1/certs

and run
  /usr/local/opt/openssl@1.1/bin/c_rehash

openssl@1.1 is keg-only, which means it was not symlinked into /usr/local,
because macOS provides LibreSSL.

If you need to have openssl@1.1 first in your PATH, run:
  echo 'export PATH="/usr/local/opt/openssl@1.1/bin:$PATH"' >> ~/.zshrc

For compilers to find openssl@1.1 you may need to set:
  export LDFLAGS="-L/usr/local/opt/openssl@1.1/lib"
  export CPPFLAGS="-I/usr/local/opt/openssl@1.1/include"

==> krb5
krb5 is keg-only, which means it was not symlinked into /usr/local,
because macOS already provides this software and installing another version in
parallel can cause all kinds of trouble.

If you need to have krb5 first in your PATH, run:
  echo 'export PATH="/usr/local/opt/krb5/bin:$PATH"' >> ~/.zshrc
  echo 'export PATH="/usr/local/opt/krb5/sbin:$PATH"' >> ~/.zshrc

For compilers to find krb5 you may need to set:
  export LDFLAGS="-L/usr/local/opt/krb5/lib"
  export CPPFLAGS="-I/usr/local/opt/krb5/include"

==> readline
readline is keg-only, which means it was not symlinked into /usr/local,
because macOS provides BSD libedit.

For compilers to find readline you may need to set:
  export LDFLAGS="-L/usr/local/opt/readline/lib"
  export CPPFLAGS="-I/usr/local/opt/readline/include"

==> postgresql
To migrate existing data from a previous major version of PostgreSQL run:
  brew postgresql-upgrade-database

This formula has created a default database cluster with:
  initdb --locale=C -E UTF-8 /usr/local/var/postgres
For more details, read:
  https://www.postgresql.org/docs/13/app-initdb.html

To have launchd start postgresql now and restart at login:
  brew services start postgresql
Or, if you don't want/need a background service you can just run:
  pg_ctl -D /usr/local/var/postgres start
==> protobuf
Emacs Lisp files have been installed to:
  /usr/local/share/emacs/site-lisp/protobuf
==> mysql
We've installed your MySQL database without a root password. To secure it run:
    mysql_secure_installation

MySQL is configured to only allow connections from localhost by default

To connect run:
    mysql -uroot

To have launchd start mysql now and restart at login:
  brew services start mysql
Or, if you don't want/need a background service you can just run:
  mysql.server start
% 

コマンド「psql –version」を実行し、PostgreSQL のバージョンが正常に表示されれば問題ありません。

% psql --version
psql (PostgreSQL) 13.2

PostgreSQL を起動・終了する

「brew services start postgresql」で起動します。初回起動時のみ下記の様なログが表示されますが、2回目以降は表示されません。

% brew services start postgresql
==> Tapping homebrew/services
Cloning into '/usr/local/Homebrew/Library/Taps/homebrew/homebrew-services'...
remote: Enumerating objects: 20, done.
remote: Counting objects: 100% (20/20), done.
remote: Compressing objects: 100% (20/20), done.
remote: Total 1141 (delta 8), reused 0 (delta 0), pack-reused 1121
Receiving objects: 100% (1141/1141), 331.40 KiB | 5.18 MiB/s, done.
Resolving deltas: 100% (485/485), done.
Tapped 1 command (41 files, 420.9KB).
==> Successfully started `postgresql` (label: homebrew.mxcl.postgresql)
%

コマンド「psql -l」を実行するとデータベースの一覧が参照できます。

% psql -l
                                         List of databases
   Name    |      Owner       | Encoding | Collate | Ctype |           Access privileges           
-----------+------------------+----------+---------+-------+---------------------------------------
 postgres  | ユーザー名         | UTF8     | C       | C     | 
 template0 | ユーザー名         | UTF8     | C       | C     | =c/ユーザー名                  +
           |                  |          |         |       | ユーザー名=CTc/ユーザー名
 template1 | ユーザー名         | UTF8     | C       | C     | =c/ユーザー名                  +
           |                  |          |         |       | ユーザー名=CTc/ユーザー名
(3 rows)
%

「brew services stop postgresql」で終了

% brew services stop postgresql
Stopping `postgresql`... (might take a while)
==> Successfully stopped `postgresql` (label: homebrew.mxcl.postgresql)
% 

【mac】Python 仮想環境に Django プロジェクトを作成する方法

  1. Python 仮想環境の作成
  2. Django のインストール
  3. Django プロジェクトの作成
  4. Django アプリケーションの作成
  5. アプリケーションをプロジェクトに登録
  6. 動作確認
  7. 初期マイグレーション
  8. 管理ユーザーの作成

1. Python 仮想環境の作成

仮想環境を作成したいディレクトリへ行き、下記のコマンドを実行します。例として「sample_venv」という仮想環境を作ります。

 python3 -m venv sample_venv

すると下記の様に Python の実行に必要なファイルやフォルダが一式作成されます。

これで仮想環境の作成は完了です。実際に仮想環境「sample_venv」を起動するには下記を実行します。

% cd sample_venv
% source bin/activate

下記の様にカッコの中に仮想環境の名前が表示されると思います。

(sample_venv) %

仮想環境から出たい場合は「deactivate」を実行します。

(sample_venv) % deactivate
%

2. Django のインストール

仮想環境で Django をインストールするには、仮想環境を activate した状態で下記を実行します。

(sample_venv) % pip install django

下記のようなログが表示されて最後の方に「Successfully installed」と出ていれば成功です。

(sample_venv) % pip install django
Collecting django
  Downloading https://files.pythonhosted.org/packages/b8/6f/9a4415cc4fe9228e26ea53cf2005961799b2abb8da0411e519fdb74754fa/Django-3.1.7-py3-none-any.whl (7.8MB)
     |████████████████████████████████| 7.8MB 337kB/s 
Collecting asgiref<4,>=3.2.10 (from django)
  Downloading https://files.pythonhosted.org/packages/89/49/5531992efc62f9c6d08a7199dc31176c8c60f7b2548c6ef245f96f29d0d9/asgiref-3.3.1-py3-none-any.whl
Collecting sqlparse>=0.2.2 (from django)
  Downloading https://files.pythonhosted.org/packages/14/05/6e8eb62ca685b10e34051a80d7ea94b7137369d8c0be5c3b9d9b6e3f5dae/sqlparse-0.4.1-py3-none-any.whl (42kB)
     |████████████████████████████████| 51kB 9.6MB/s 
Collecting pytz (from django)
  Downloading https://files.pythonhosted.org/packages/70/94/784178ca5dd892a98f113cdd923372024dc04b8d40abe77ca76b5fb90ca6/pytz-2021.1-py2.py3-none-any.whl (510kB)
     |████████████████████████████████| 512kB 8.1MB/s 
Installing collected packages: asgiref, sqlparse, pytz, django
Successfully installed asgiref-3.3.1 django-3.1.7 pytz-2021.1 sqlparse-0.4.1
WARNING: You are using pip version 19.2.3, however version 21.0.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
(sample_virtual_environment) %

これで Python の仮想環境に Django がインストールされたので、この後 Django のプロジェクト、アプリケーションを作っていきます。

3. Django プロジェクトの作成

仮想環境に入った状態で下記を実行します。今回は例として仮想環境内に「Django_Project」フォルダを作り、その中に「sample_django_project」という名前の Django プロジェクトを作成します。

(sample_venv) % mkdir Django_Project
(sample_venv) % cd Django_Project
(sample_venv) Django_Project % django-admin startproject sample_django_project

すると下記の様に「Django_Project」フォルダの配下に「sample_django_project」フォルダとファイルが一式作成されます。

4. Django アプリケーションの作成

上の画像「manage.py」がある階層へ移動します。

(sample_venv) % cd sample_django_project

そして下記を実行して「sample_django_app」という名前で Django アプリケーションを作成します。

(sample_venv) sample_django_project % python manage.py startapp sample_django_app

すると、「sample_django_project」というプロジェクトの配下に「sample_django_app」が作成されました。

5. アプリケーションをプロジェクトに登録

アプリケーションフォルダの apps.py を開くと下記の通り「SampleDjangoAppConfig」というクラスがあるので、このクラス名をプロジェクトの settings.py に登録します。

# apps.py
from django.apps import AppConfig


class SampleDjangoAppConfig(AppConfig):
    name = 'sample_django_app'

settings.py の INSTALLED_APPS のリストに下記の通り「アプリケーション名.apps.クラス名」の形で追記します。

# settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    'sample_django_app.apps.SampleDjangoAppConfig'
]

これで Django プロジェクトと Django アプリケーションの作成は完了です。

6. 動作確認

ターミナルでコマンド「python manage.py runserver」を実行し、動作確認をします。

% python manage.py runserver
Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).

You have 18 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.
April 23, 2021 - 21:27:24
Django version 3.2, using settings 'sample_django_project.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

特に問題がなければ上記の様なログが表示されるはずです。

そしてブラウザの URL バーに「http://127.0.0.1:8000/」と入力して下記の画面が表示されたら OK です。

停止したい場合は CONTROL-C を押下します。

7. 初期マイグレーション

Django の設定内容やモデルの構造をデータベースへ反映することをマイグレーションと呼びます。

Django ではデフォルトのデータベースとして SQLite が設定されているので他のデータベースを使用する場合は先にデータベースの変更をしてください。例として PostgreSQL を使用する場合の例を下記に貼っておきます。

Django プロジェクトで PostgreSQL のデータベースを利用する(仮想環境内)

Django プロジェクト・アプリケーションの作成時点ではマイグレーションされていない設定内容がいくつかありますのでコマンド「python manage.py migrate」を実行してマイグレーションをおこないます。

% python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying auth.0010_alter_group_name_max_length... OK
  Applying auth.0011_update_proxy_permissions... OK
  Applying auth.0012_alter_user_first_name_max_length... OK
  Applying sessions.0001_initial... OK

8. 管理ユーザーの作成

仮想環境内、「manage.py」のある階層でコマンド「python manage.py createsuperuser」を実行します。

% python manage.py createsuperuser

するとユーザー名、メールアドレスをパスワードを設定する様促されるので設定を行います。

Username : adminuser #任意のユーザー名
Email address: xxxxxxxx@gmail.com
Password: 
Password (again): 
Superuser created successfully.
% python manage.py runserver

ブラウザで「http://127.0.0.1:8000/admin/」にアクセスすると、管理ユーザーのログイン画面が表示されます。

ログインすると下記の通り管理ユーザー用画面が表示されます。

Mac で Python 仮想環境に Django をインストールしたい

Python の仮想環境を作る

仮想環境を作成したいディレクトリへ行き、下記のコマンドを実行します。例として「sample_virtual_environment」という仮想環境を作ります。

 python3 -m venv sample_virtual_environment

すると下記の様に Python の実行に必要なファイルやフォルダが一式作成されます。

これで仮想環境の作成は完了です。実際に仮想環境「sample_virtual_environment」を起動するには下記を実行します。

% cd sample_virtual_environment/bin
% source activate

下記の様にカッコの中に仮想環境の名前が表示されると思います。

(sample_virtual_environment) %

仮想環境から出たい場合は「deactivate」を実行します。

(sample_virtual_environment) % deactivate
%

Django をインストールする

仮想環境で Django をインストールするには、仮想環境を activate した状態で下記を実行します。

(sample_virtual_environment) % pip install django

下記のようなログが表示されて最後の方に「Successfully installed」と出ていれば成功です。

(sample_virtual_environment) % pip install django
Collecting django
  Downloading https://files.pythonhosted.org/packages/b8/6f/9a4415cc4fe9228e26ea53cf2005961799b2abb8da0411e519fdb74754fa/Django-3.1.7-py3-none-any.whl (7.8MB)
     |████████████████████████████████| 7.8MB 337kB/s 
Collecting asgiref<4,>=3.2.10 (from django)
  Downloading https://files.pythonhosted.org/packages/89/49/5531992efc62f9c6d08a7199dc31176c8c60f7b2548c6ef245f96f29d0d9/asgiref-3.3.1-py3-none-any.whl
Collecting sqlparse>=0.2.2 (from django)
  Downloading https://files.pythonhosted.org/packages/14/05/6e8eb62ca685b10e34051a80d7ea94b7137369d8c0be5c3b9d9b6e3f5dae/sqlparse-0.4.1-py3-none-any.whl (42kB)
     |████████████████████████████████| 51kB 9.6MB/s 
Collecting pytz (from django)
  Downloading https://files.pythonhosted.org/packages/70/94/784178ca5dd892a98f113cdd923372024dc04b8d40abe77ca76b5fb90ca6/pytz-2021.1-py2.py3-none-any.whl (510kB)
     |████████████████████████████████| 512kB 8.1MB/s 
Installing collected packages: asgiref, sqlparse, pytz, django
Successfully installed asgiref-3.3.1 django-3.1.7 pytz-2021.1 sqlparse-0.4.1
WARNING: You are using pip version 19.2.3, however version 21.0.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
(sample_virtual_environment) %

以上で Django のインストールは完了です。続けて Django プロジェクトそして Django アプリケーションの作成はこちらの記事へ。

Google Foobar Challenge を終えて

Google Foobar Challenge を知っていますか?

この記事に来た方は実際に発動したりどこかで見聞きしたかで調べているかと思います。僕はある土曜日の朝、突然 Google 検索の画面がおかしな動きをして初めてその存在を知りました。

Google Foobar Challenge とは

Google Foobar Challenge は Google がプログラミング関連の調べごとをしている人に「ちょっと遊ぼうよ」的な感じで発動するプログラミング問題(ゲーム?)のことです。

「宇宙空間に浮かぶラムダ司令官の悪の組織から、囚われの身になっているウサギちゃんたちを救う」という、どこのAIが考えたのか分からないストーリーを題材に、黒バックのコマンド入力画面の様なUIでプログラミングの問題を解いていきます。

途中まで解くと Google 社に自分の連絡先を送れたりもするので、本気で取り組む価値はあると思いますし、何より面白いです!好奇心旺盛な人にはたまらない時間になると思います。

そして僕はこの度めでたく全問クリア出来たので、記録として記事を書いてます。というか Foobar Challenge は全編英語というのもあって日本語の記事が全然見当たらなかったので書いてます。

問題とコードは GitHub に置いています

下記リポジトリに各問題と自分が作成したコードを載せていますので参考にしてみてください。*参考にしたくない方も Star 等いただけると助かります。。笑

https://github.com/kttyo/google-foobar-challenge

挑戦するには?

URL はこれですが、ページに飛んだところで誰でも挑戦できるわけではなく、Google 検索をしている時に自然発生するのをただただ心待ちにするか、知り合いが頑張って取得した招待用リンクをもらうかの2つしかありません。

必要なスキル

必要なスキルとしては、まずプログラミングの基本的な知識と英語力。そして途中からはアルゴリズムの知識、そして終盤は数学の知識も必要になります。ちなみに言語は Java と Python が使えます。僕は Python で解いていきました。

もちろん初めから全部揃っていたら最高だとは思いますが、後述の通り回答に結構時間をかけられるので必要に応じて調べていくのでも問題ないと思います。

プログラミングの知識よりも発想力&想像力

プログラミングに関しては特に言語に精通している必要はないです。僕は Python 初心者で、そもそも今回 Google Foobar Challenge が発動した時も try-catch 文の書き方をググってたぐらいです。

それよりも問題を解決する方法を思いつく発想力や、色々な処理パターンを思い浮かべる想像力の方が大切だと思います。あとはそれを元に考えたロジックをコードに落とし込めれば大丈夫で、オブジェクト指向的な知識も全く必要ないです。

各レベルの内容

今後変更があるかもしれませんが、2021年1月時点ではレベル1〜5の全9問で構成されています。レベル1は本当に基本的な内容ですが、徐々に難易度が上がりレベル5はもう訳がわかりませんでした。問題自体は多分いくつかパターンがあると思うので、使うアルゴリズムの種類などは人によって変わると思います!

各レベルの主な内容を紹介します。

レベル1

まずは肩慣らしのような感じ。変数やループ等、プログラミングの基礎の基礎がわかっていれば大丈夫です。

  • 問題数:1 問
  • 制限時間:48 時間

こんな感じで進捗を確認できます。

レベル2

レベル 1 はプログラミング経験者なら誰でも解けますが、レベル 2 からはちゃんと頭を使う問題になります。このレベルをクリアすると友達に送る用のリンクを一つもらえます。

  • 問題数:2 問
  • 制限時間:各問題 168 時間(1 週間)
  • クリアすると:招待用リンクがもらえる(1 度目)

レベル3

経験者の書き込みをいくつか見ると、Google の採用面接で出されるコーディング問題はこの辺りのレベルだとのこと。このレベルをクリアすると Google に連絡先を送ることもできるので、ここまではがんばりたいですね!

  • 問題数:3 問
  • 制限時間:各問題 168 時間(1 週間)
  • クリアすると:Google に連絡先を送れる

迷路の最短距離の問題など、後になって考えてみればアルゴリズムの知識があればよかったなーと思いますが、想像力一本勝負でがんばりました。この辺りからは処理速度を気にしたプログラムを書かないと普通にタイムアウトでテストケースが Fail になります。

小休止(お勉強タイム)

このタイミングでアルゴリズムの知識を身に付けないとまずいと思い、下記の二冊をポチりました。

まず一つ目

アルゴリズム図鑑 絵で見てわかる26のアルゴリズム

こちらはプログラミング言語関係なくメジャーなアルゴリズムの概要をイラストでひたすら分かりやすく教えてくれます。「アルゴリズムとはそもそもなんぞや」だった僕にとっては最高の入り口でした。

そして二つ目

Pythonではじめるアルゴリズム入門 伝統的なアルゴリズムで学ぶ定石と計算量

こちらは、一冊目の「アルゴリズム図鑑」とほぼ同じアルゴリズムを、Python のコードではどう表現するのかを教えてくれます。最高です。

問題と問題の間はいくら時間を開けても良いので、心の準備ができるまで備えると良いと思います!

レベル4

ここからはいよいよ発想力だけではどうにもならなくなり、アルゴリズムが必須になります。そして流石の Google 先生。アルゴリズムを当てはめて終わりではなく、さらに一捻り二捻りする必要があります。

  • 問題数:2 問
  • 制限時間:各問題 360 時間(15 日間)
  • クリアすると:招待用のリンクがもらえる(2 度目)

1 問目は「せっかく学んだし」と思って幅優先探索を使ってみたんですけど処理に時間がかかりすぎたので結局別の方法に切り替えました。2 問目は最短経路を求めるベルマンフォード法を応用したイメージでした。

レベル5

いよいよ最終問題。そして流石の最終問題。もはやただの数学でした。

数学の知識はほぼゼロでしたが調べた内容を書くとするなら、バーンサイドの補題(Burnside’s Lemma)、ポリアの数え上げ問題(Polya’s Enumeration Theorem)、ユークリッドの互除法、順列と組み合わせ(Permutations & Combinations)、などなど。。。

  • 問題数:1 問
  • 制限時間:528時間(22 日間)

この記事(15.5 Applications of Pólya’s Enumeration Formula)を読んでみたり、後述の動画をみたり。とりあえず何か掴めないか模索しました。

人によってはレベル4が一番難しいと感じる人もいるみたいですが、僕にとっては圧倒的にレベル5が一番難しかったです。途中ちょっと心が折れそうになりましたが、12日間かかってやっとクリア。

最終問題で参考にした動画

ポイント

  • 「verify solution」が数秒で終わらない場合はパフォーマンス的なところで Fail してる可能性があります。書いたコードの計算数をイメージすることが大事です。
  • 問題の細かい条件は読み取るのが難しいので、早めにコードを書いて「verify solution」でテストしながら察していくことが大事だと思います。
  • とはいえ問題はなるべく正確に理解する様注意した方がいいです(当然ですが)。自分の場合レベル 4 でコードをしばらく書いた後でどうにも上手くいかないのでよーく問題を読み直してみたら自分で理解していた条件と実際が異なることが分かり、ほぼ丸ごとロジックを考え直しました…。
  • ちっちゃいホワイトボードとかあると便利です。iPadとかでも良いのかな?その場で書いて消してを繰り返せるので。
  • 参考までに、僕の回答は大体数十行で一番多くても 200 行未満で済んだので(あくまで Python の場合)、もしもやたらと処理が多くなっている場合は考えすぎているかもしれません。

まとめ

コロナでのステイホーム中に突然始まった Google Foobar Challenge。思いの外夢中になってとてもエキサイティングな数週間になりました。初めは全てクリアできるとも思っていなかったので、最終的には自信を得られたことが一番良かったことかもしれません。

皆さんももし挑戦する機会があったら週末など出来るだけ時間を取れる期間を見つけて、思い切り没頭してみてください。きっと素敵なおうち時間になると思います。

繰り返しになりますが、下記リポジトリに各問題と自分が作成したコードを載せていますので、参考にしたくない方も Star 等いただけると助かります。。笑

https://github.com/kttyo/google-foobar-challenge

import MySQLdb で実際にクエリを実行できるか確認する

mysqlclient をインストールしたので、実際にクエリを実行できるか簡単に確認します。

今回は WordPress で自動作成されたテーブルで、現在公開されている記事のタイトルを select しました。

% python3
Python 3.9.0 (default, Jan  3 2021, 10:29:59) 
[GCC 4.2.1 20070831 patched [FreeBSD]] on freebsd9
Type "help", "copyright", "credits" or "license" for more information.

>>> import MySQLdb
>>> conn = MySQLdb.connect(host='mysqlXXX.db.sakura.ne.jp', db='abcabc_notemite',user='abcabc',passwd='xxxxxxxxxxxx',charset='utf8mb4')
>>> c = conn.cursor()
>>> c.execute('select post_title from nm_posts where post_status = "publish"')
20
>>> c.fetchall()
(('サンプルページ',), ('【Wordpress】ショートコードを別ファイル管理でリスク低減',), ('【WordPress】ショートコードの表示・非表示を一発で切り替えたい',), ('【ターミナル】Mac のログインシェルを zsh に変える',), ('【Python】Macbook に Python3 をインストール',), ('【Python】「pip install requests」でエラー「pip3 install requests」で成功',), ('【Python】Mac に Beautifulsoup4 をインストール',), ('Homebrew を Macbook Pro へインストール',), ('Homebrew を使って Macbook に Wget をインストール',), ('【Wordpress】確かに「--」と書いたのに「–」と表示される件',), ('【8ステップでがんばる】さくらレンタルサーバーでWordPressサイト立ち上げ',), ('【ターミナル】さくらのレンタルサーバーにSSHでログインする方法',), ('さくらレンタルサーバに Python3 をインストールする方法',), ('【Python】さくらレンタルサーバーに requests モジュールをインストール',), ('【Python】Mac に MySQL モジュールをインストールする方法',), ('【2020年10月〜12月】YouTube 急上昇入りランキング',), ('さくらレンタルサーバーに libffi をインストールする',), ('【2020年1月〜】YouTube 急上昇入りランキング',), ('さくらレンタルサーバーで Python3 を再インストール',), ('【Python3】mysqlclient のために _ctypes と格闘した記録',))
>>> 

execute() の実行結果(上記「20」の部分)はクエリの結果として返されたレコード数を表示しています。fetchall() を実行しないとクエリの実行結果は見れないんですね。

さくらレンタルサーバーで Python3 を再インストール

さくらのレンタルサーバに一度 Python3 をインストールしたのですが、mysqlclient をインストールするために Python3 を入れ直す必要があったのでそのステップを書きます。

▶︎さくらのレンタルサーバ スタンダードのお申込みはこちら(公式ページ)

また、Python の利用には VPS の方が圧倒的におすすめなので下記の記事も参考にしてみてください。

▶︎レンタルサーバーで Python は茨の道!VPS が楽得でおすすめ

では再インストールのステップを書いていきます。

アンインストール(仮)

まずは既存の Python3 を一旦アンインストールします。インストール先のフォルダを削除する必要があると思いますが、削除は怖いので一旦フォルダ名だけ変えます。

下記の通りパスが通っている状態です。

% which python3
/home/abcabc/local/python/bin/python3
% which pip3
/home/abcabc/local/python/bin/pip3

フォルダ名が変わったため、パスが通っていない状態になりました。

% which python3
python3: Command not found.
% which pip3
pip3: Command not found.

ダウンロード〜インストール

ここから先は基本的に下記の記事でやった内容をなぞるだけですが、進めていきます。

ダウンロード

% mkdir -p ~/work/python3
% cd ~/work/python3
% wget --no-check-certificate https://www.python.org/ftp/python/3.9.0/Python-3.9.0.tgz

解凍

% tar zxf Python-3.9.0.tgz

インストール

% cd ./Python-3.9.0
% ./configure --prefix=$HOME/local/python/ --with-system-ffi LDFLAGS="-L $HOME/local/lib/" CPPFLAGS="-I $HOME/local/include/"
%  make
%  make install

ここまで完了したら、以前通したパスが生きているので下記の通り which コマンドで既に確認できる状態です。

% which python3
/home/abcabc/local/python/bin/python3
% which pip3
/home/abcabc/local/python/bin/pip3

使い終わったフォルダとファイルの削除

最後にファイルダウンロード用に作ったフォルダと、既存の Python3 が入っていたフォルダ(の名前を変えたもの)を削除します。

% rm -r ~/work/python3
% rm -r ~/local/python_20210103

ついでに

環境変数の追加

初めて Python3 をインストールした時はスルーしていましたが、どうやら下記を .cshrc に追記した方が良いみたいなのでこのタイミングで追記しておきます。

setenv  PYTHON $HOME/local/python/lib
setenv  PYTHONPATH $HOME/local/python/lib/python3.9/site-packages

requests モジュールをインストール

元々インストールしてあった requests モジュールを再度インストールします。

% pip3 install requests

▶︎さくらのレンタルサーバ スタンダードのお申込みはこちら(公式ページ)

▶︎初めから Python3 系を使えるレンタルサーバー 7 選

【Python3】_ctypes と libffi のインストールに苦しんだ記録

経緯

さくらのレンタルサーバ上で MySQL のデータベースを使えるので、それを Python で操作したいと思ったのが始まりです。

mysqlclient を使えば良いらしかったので「pip3 install mysqlclient」を実行するも、エラーが出て成功しない。

なんとかインストールを終えるまでの過程が文系の私には?だいぶややこしかったのでその記録を書き留めます。

  1. 問題発生1(No module named ‘_ctypes’)
  2. 調査と原因1(libffi が無い)
  3. libffi をインストール(sudo は使えない)
  4. 問題発生2(INFO: Could not locate ffi libs and/or headers)
  5. 調査と原因2(./configure 文の修正)
  6. 解決(mysqlclient インストール成功)

問題発生1(No module named ‘_ctypes’)

上記の通り「pip3 install mysqlclient」を実行したところ、下記のエラーが出てインストールが失敗しました。

ModuleNotFoundError: No module named '_ctypes'

直訳すると「_ctypes モジュールがありません」

_ctypes モジュールとはなんぞや。そしてそれはどこにあるのでしょうか。。。

調査と原因1(libffi が無い)

取り敢えず知識ゼロから出来ることは、情報の海に身を投げてなんとなくわかるまで溺れること。。。調べた結果断片的ですが自分の理解できる範囲で下記の情報が得られました。

  • _ctypes と libffi
    • _ctypes は C 言語で書かれたライブラリを Python から利用するためのモジュールであり、libffiに依存している。
    • ソースからPythonをビルドする際、libffiが見つからない場合は _ctypes のビルドはスキップされる。
    • _ctypes がビルドされていない Python から _ctypes を利用しようとすると、当該エラー(ModuleNotFoundError: No module named ‘_ctypes’)が発生する。
  • 原因
    • つまり、libffi がインストールされていない状態で Python をインストールしたため、_ctypes のビルドがされていなかった。
  • 解決方法
    • 当該エラーを解消するには、libffi をインストールした上で Python を再ビルド・再インストールする必要がある。

libffi をインストール(sudo は使えない)

「sudo apt-get install -y libffi-dev」というコマンドが出てきましたが、さくらのレンタルサーバー(スタンダード)では管理者権限が与えられていないので sudo が使えません。

% sudo apt-get install -y libffi-dev
/usr/local/bin/sudo: Permission denied.

この通り、拒否されてしまいます。諸々調べた結果下記の方法でインストール出来ました。

問題発生2(INFO: Could not locate ffi libs and/or headers)

めでたく libffi をインストール出来たので Python をインストールし直しました。が、念のため make のログを確認したところ下記を発見。

INFO: Could not locate ffi libs and/or headers

Failed to build these modules:
_ctypes               _zoneinfo 

直訳すると「ffi libs およびヘッダーが見つからず _ctypes モジュールと _zoneinfo モジュールをビルド出来ませんでした。」とのこと。ショック。

しょうがないのでとりあえず続けて make install しましたが、当然 _ctypes モジュールが無いので「pip3 install mysqlclient」を実行しても前回と全く同じエラーで失敗します。

ModuleNotFoundError: No module named '_ctypes'

調査と原因2(./configure 文の修正)

また海に放り出されました。今回は「INFO: Could not locate ffi libs and/or headers」の文言を頼りに調べました。

こちらのページ(英語)を見たところ、どうやら CPPFLAGS、LDFLAGS、PKG_CONFIG_PATH の設定が必要みたいです。PKG_CONFIG_PATH の設定は libffi のインストールの時に行っていたので、取り敢えず CPPFLAGS と LGFLAGS だけでやってみます。

python-3.9.0.tgz は残して他を消し、再度下記の「./configure」文で Python のインストールを試してみます。

./configure --prefix=$HOME/local/python/ --with-system-ffi LDFLAGS="-L $HOME/local/lib/" CPPFLAGS="-I $HOME/local/include/"
項目雑なメモ
–prefixPython3 をインストールする場所
–with-system-ffilibffi のシステムバージョンへの接続を有効にするスイッチ。
CPPFLAGSCプリプロセッサのオプション
include パスを入れるっぽい?
LDFLAGSリンク用のディレクトリを指定する。
lib フォルダを入れるっぽい?

解決(mysqlclient インストール成功)

上記の「./configure」文のあとで make を実行しました。そしてログを確認すると下記の通り _ctypes のエラーはなくなりました。_zoneinfo は何かよくわかりませんし特に今回必要だとも思ってないので無視します。

Failed to build these modules:
_zoneinfo

今回は「pip3 install mysqlclient」も無事成功しました。

% pip3 install mysqlclient
Collecting mysqlclient
  Using cached mysqlclient-2.0.3.tar.gz (88 kB)
Using legacy 'setup.py install' for mysqlclient, since package 'wheel' is not installed.
Installing collected packages: mysqlclient
    Running setup.py install for mysqlclient ... done
Successfully installed mysqlclient-2.0.3
WARNING: You are using pip version 20.2.3; however, version 20.3.3 is available.
You should consider upgrading via the '/home/xxxxxx/local/python/bin/python3.9 -m pip install --upgrade pip' command.
% 

さくらレンタルサーバーに libffi をインストールする

  1. SSH でサーバーに接続
  2. ファイルのダウンロードと解凍
  3. インストール
  4. インストール後の設定

SSH でサーバーに接続

% ssh abcabc@abcabc.sakura.ne.jp
abcabc@abcabc.sakura.ne.jp's password: 

ファイルのダウンロードと解凍

ダウンロード用のフォルダを作成

ファイルをダウンロードする前に、ダウンロード用のフォルダを作ります。下記のコマンドで「work」フォルダとその配下に「libffi」フォルダを作成します。

% mkdir -p ~/work/libffi

wget でファイルをダウンロード

作成した「libffi」フォルダに移動して、圧縮ファイルをダウンロードします。

% cd work/libffi
% wget ftp://sourceware.org/pub/libffi/libffi-3.2.1.tar.gz

*初めは最新の「libffi-3.3.tar.gz」で進めたのですが後述の make のところで下記のエラーを返され、すぐに原因も分からなかったので一旦全部ファイルを削除して「libffi-3.2.1.tar.gz」で再チャレンジしました。

gcc: warning: ‘-x assembler-with-cpp’ after last input file has no effect
gcc: No input files specified
*** [libffi.map] Error code 1

上記の wget コマンドを実行してから ls を実行すると圧縮ファイルがダウンロードされたのが確認できます。

% ls
libffi-3.2.1.tar.gz
% 

ファイルを解凍する

ダウンロードした圧縮ファイルを解凍します。

% tar xvfz libffi-3.2.1.tar.gz

ファイルが解凍され、元々ダウンロードした圧縮ファイルとは別に「libffi-3.2.1」という名前のフォルダが作成されています。

インストール

「libffi-3.2.1」のフォルダへ移動し ./configure を実行します。prefix でインストール先を指定します。

% cd libffi-3.2.1
% ./configure --prefix=$HOME/local/libffi/3_2_1

実行するとプロセスが走ってドバドバとターミナルに表示されるので入力待ちになるのを待ちます。

make そして make install を順に実行します。

% make
% make install

.configure の prefix で指定した場所にインストールされました。

インストール後の設定

シンボリックリンクの作成

% mkdir -p ~/local/include
% ln -s $HOME/local/libffi/3_2_1/lib/libffi-3.2.1/include/ffi.h $HOME/local/include/
% ln -s $HOME/local/libffi/3_2_1/lib/libffi-3.2.1/include/ffitarget.h $HOME/local/include/

% mkdir -p ~/local/lib
% ln -s $HOME/local/libffi/3_2_1/lib/libffi.a $HOME/local/lib/
% ln -s $HOME/local/libffi/3_2_1/lib/libffi.la $HOME/local/lib/
% ln -s $HOME/local/libffi/3_2_1/lib/libffi.so $HOME/local/lib/
% ln -s $HOME/local/libffi/3_2_1/lib/libffi.so.6 $HOME/local/lib/

% mkdir -p ~/local/lib/pkgconfig/
% ln -s $HOME/local/libffi/3_2_1/lib/pkgconfig/libffi.pc $HOME/local/lib/pkgconfig/

上記を実行すると下記の様に local 配下に include、lib、lib > pkgconfig が作成され、その配下のシンボリックリンクも確認できます。

環境変数の設定

シンボリックリンクを作成したのでそれぞれ LD_LIBRARY_PATH と PKG_CONFIG_PATH に追加します。他のソースをビルドするときやコマンド実行するときに役立ちます。

シェルの種類ユーザプロファイル
Bourne シェル (sh) または Korn シェル (ksh).profile
Bourne Again シェル (bash).bash_profile
C シェル (csh).login と .cshrc
TC シェル (tcsh).tcshrc と .cshrc
Z シェル (zsh).zlogin と .zshrc

今回はサーバーのシェルが csh なので .cshrc を編集して環境変数を設定します。

.cshrc の編集

% cd ~/
% vi .cshrc

.cshrc に下記を追記します。

setenv  LD_LIBRARY_PATH $HOME/local/lib
setenv  PKG_CONFIG_PATH $HOME/local/lib/pkgconfig

.cshrc で追記した内容を反映させます。

% source ~/.cshrc
% rehash

echo コマンドで確認すると、指定したパスが表示されます。

% echo $LD_LIBRARY_PATH
/home/abcabc/local/lib
% echo $PKG_CONFIG_PATH
/home/abcabc/local/lib/pkgconfig

以上で libffi のインストール作業は完了です。

LD_LIBRARY_PATH と PKG_CONFIG_PATH

LD_LIBRARY_PATH 変数

LD_LIBRARY_PATHは、アプリケーションがリンクされている動的共有ライブラリを検索する際の対象ディレクトリを動的リンクローダーに指示します。複数のディレクトリをコロン (:) で区切ったもので、コンパイルされた検索パスと標準の場所(大抵 /lib、/usr/lib 等)の前に検索されます。

PKG_CONFIG_PATH 変数

pkg-config は、プログラムのコンパイルとシステムにインストールされているライブラリとの接続に必要な情報を提供します。
この情報は .pc ファイルに保存されており、pkg-config ツールで認識されている特定の場所にあります。

pkg-config が .pc ファイルを検索する際、デフォルトでは /usr/lib/pkgconfig と /usr/share/pkgconfig を検索します。しかし、一部のローカルモジュールは /usr/local などの別のプレフィックスにインストールされる場合があるため、PKG_CONFIG_PATH 変数で検索対象のパスを追加します。