タグ: サーバー

  • SQLite + Alembic 「no such column」「duplicate column name」の解決法

    FastAPI + SQLAlchemy + Alembic を使って開発中のエラー。備忘録がてらブログに残しておきます。


    エラーその1: no such column

    API 実行時に以下のエラーが出ました。

    sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such column: sakes.created_by_id

    テーブル sakes に必要なカラム created_by_id が存在していません。

    モデルでは定義しているのに DB に反映されていない状態です。


    エラーその2: duplicate column name

    Alembic でマイグレーションを流そうとすると、今度はこんなエラー。

    sqlite3.OperationalError: duplicate column name: password

    既に users テーブルに password カラムがあるのに、再度追加しようとして失敗しています。

    要するに「DB と Alembic の履歴がズレている」状態。


    解決手順

    1. Alembic 履歴を DB に合わせる

    既に存在しているカラムについては、DB に合わせて履歴を進めるだけでOK。

    poetry run alembic stamp 3ed4e13e6b65

    これで「password はもうあるよ」と Alembic に教えました。


    2. 新しいカラムを追加するマイグレーションを作成

    不足していた sakes.created_by_id を追加するためのリビジョンを作成。

    poetry run alembic revision -m "add created_by_id to sakes"

    生成されたファイルに処理を追記:

    def upgrade() -> None:
        with op.batch_alter_table("sakes") as batch:
            batch.add_column(sa.Column("created_by_id", sa.Integer(), nullable=True))
            batch.create_index("ix_sakes_created_by_id", ["created_by_id"])

    そして適用!

    poetry run alembic upgrade head

    3. 確認

    sqlite3 ochoko.db "PRAGMA table_info(sakes);"

    ちゃんと created_by_id が入っているのを確認。

    API を再実行したら 500 エラーが消えました 🎉

  • Vercelを使いつつ、ロリポップのメーラーを使えるようにする。

    Vercelを使いつつ、ロリポップのメーラーを使えるようにする。

    Vercelにネームサーバーを切り替えたらメールが止まってしましました。

    今回はこれの解決策についてです。

    やり方

    まず、Vercelの管理画面を開き、Settings -> Domains を開きます。

    開いたら、DNS Records に MX, TXT の設定をします。

    Name: @
    Type: MX
    Value: mx01.lolipop.jp
    TTL: 60
    Priority: 10

    Name: @
    Type: TXT
    Value: v=spf1 include:spf.muumuu-domain.com ~all
    TTL: 60

    こんな感じに設定すればOKです!

    参考

    https://lolipop.jp/info/news/7173

  • Next.js で Recoil を使いたい TypeError: Cannot destructure property ‘ReactCurrentDispatcher’ of ‘react__WEBPACK_IMPORTED_MODULE_0___default(…).__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED’ as it is undefined.

    Next.js で Recoil を使いたい TypeError: Cannot destructure property ‘ReactCurrentDispatcher’ of ‘react__WEBPACK_IMPORTED_MODULE_0___default(…).__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED’ as it is undefined.

    Recoil を使ったプロジェクトをNext.js に移行しようとしたところ以下のようなエラーが出てしましました。

    TypeError: Cannot destructure property 'ReactCurrentDispatcher' of 'react__WEBPACK_IMPORTED_MODULE_0___default(...).__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED' as it is undefined.

    この記事はこれを解決するための記事です。

    やり方

    ページまたはコンポーネントごと、SSRをオフにする。

    今までRecoilを使っていたページを下記のようにラップしてしまいます。

    私の場合の例を出しますと。元々はdiagnosis.tsx にrecoil を含む動作を書いていたたのですが、
    pages/diagnosis.tsx を直接書くのではなく、diagnosis.page.tsx に全てコードを移行し、
    diagnosis.tsx の中で動的にインポートしました。

    // pages/diagnosis.tsx
    import dynamic from 'next/dynamic';
    
    // diagnosis.page.tsx をクライアントサイドのみで読み込む
    const DiagnosisPageComponent = dynamic(() => import('../diagnosis.page'), {
      ssr: false,
    });
    
    export default function DiagnosisPage() {
      return <DiagnosisPageComponent />;
    }
    元々のRecoilを含むコード

    diagnosis.page.tsx には実際の実装(Recoil フックを呼び出す部分)を記述します。こうすると、サーバーサイドでは空っぽのコンポーネントしか返さないため、エラーを回避できました。

    React と ReactDOM のバージョンを一致させる

    以上で解決できない場合はReact と ReactDOM のバージョンを見直してみてください。どちらも同じバージョン出ないと不具合が出る場合があります。

  • Ubuntu 毎日決まった時間に再起動をかける crontab

    Ubuntu 毎日決まった時間に再起動をかける crontab

    Ubuntu を自宅サーバーとして運用する際に、一定期間に一度再起動したいものです。

    システムやサービスが長期間動作することで、まれにハングアップや不具合が発生することがあります。定期的に再起動することで、こうした問題を未然に防ぎ、安定した運用が可能になります。

    環境

    • Ubuntu 24.04.1 LTS
    • version 24.04

    2025/02/06時点

    やり方

    crontab コマンドを使います。このコマンドは定期的にコマンドやスクリプトを自動実行するた目につかいます。

    cron ジョブの編集画面を開きます。

    sudo crontab -e

    エディタを選択して!と言われるので、nano を選択します。

    crontab

    スケジュールを追加します。今回は毎日午前3時に再起動する設定にしました。

    0 3 * * * /sbin/shutdown -r now

    書き方

    • 0 3 * * *:毎日3時0分に実行
    • 0:分(0分)
    • 3:時(3時)
    • *:日(毎日)
    • *:月(毎月)
    • *:曜日(毎週)
    crontab edit

    入力したら、ctrl O で保存して、return, ctrl X で抜けましょう。

    確認

    以下コマンドで確認できます。

    sudo systemctl status cron

    ログは以下に記録されます。

    grep CRON /var/log/syslog

  • レンタルサーバーで Unity WebGL 埋め込み This can happen if build compression was enabled

    WordPress にUnityで制作したものを埋め込む際に下記のようなエラーが出ました。

    WordPressの wp-content/upload の直下にビルドしたフォルダをアップロードしました。

    This can happen if build compression was enabled but web server hosting the content was misconfigured to not serve the file with HTTP Response Header "Content-Encoding: gzip" present. Check browser Console and Devtools Network tab to debug.

    これの解決方法です。

    サーバー側のGzip対応を確認

    私の利用しているロリポップではGzipに対応しています。

    https://support.lolipop.jp/hc/ja/articles/360048374954-GZIP%E3%81%AF%E5%88%A9%E7%94%A8%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%99%E3%81%8B

    以下のように .htaccess を作成し、build フォルダや index.html があるディレクトリに .htaccess をアップロードしました。

    <IfModule mod_mime.c>
        # WebAssembly用のContent-Type設定
        AddType application/wasm .wasm
        AddEncoding gzip .gz
    </IfModule>
    
    <IfModule mod_headers.c>
        # gzip圧縮ファイルのContent-Type設定
        <FilesMatch "\.wasm\.gz$">
            Header set Content-Encoding gzip
            Header set Content-Type application/wasm
        </FilesMatch>
    </IfModule>
    
    <IfModule mod_rewrite.c>
        RewriteEngine On
        RewriteCond %{HTTP:Accept-Encoding} gzip
        RewriteCond %{REQUEST_FILENAME}.gz -f
        RewriteRule ^(.*)$ $1.gz [QSA,L]
    </IfModule>

    公開できました!

  • Ubuntu DDNS(動的DNS)は使った方がええ🥦 with NO-IP

    ❓これは何

    Ubuntu をファイルサーバーとして利用しています。

    外部のネットワークから利用することを考えると、
    IPアドレスが変更される場合に対応するために動的DNS(DDNS, Dynamic DNS)を使ってみてもいいのかも……。

    といった動機で NO-IP を使ってDDNSを利用するまでの記事です。

    🪴 環境

    2024/07/21時点

    • Distributor ID: Ubuntu
    • Description: Ubuntu 24.04 LTS
    • Release: 24.04
    • Codename: noble

    🛠️ やり方

    NO-IP のアカウント作成

    https://noip.com にアクセスしてアカウントを作成します。

    2つ以上のドメインを使用しない限り、無料版で大丈夫だと思います。

    左のタブから Dynamic DNS を開いて、
    “NO IP Hostnames”を選択します。

    次のような画面になると思うので、
    緑の”Create Hostname”ボタンを押下します。

    次のようなポップアップが開くので、
    Hostname, Domain をそれぞれ入力、選択します。
    できたら、 ”Create Hostname” を押します。

    画像ではRecord TypeはAAAAになっていますが、 DNS Host(A)の選択のままで進めてください🙏

    次のような感じで、追加されているはずです。

    Ubuntu での設定

    ddclient をインストールします。

    sudo apt update
    sudo apt install ddclient -y

    install をすると、次の画面が出てくると思います。

    今回はno-ip.com を使用しているのでこれを選択します。

    ユーザー名の入力

    パスワードの入力をします。

    一般の家庭の場合は上の選択肢の ‘web-based ip discovery service’で問題ないでしょう。
    これはルーターがあって、ネットワークに接続されている場合の選択肢です。

    下の選択肢はコンピューターが直接インターネットに接続されている場合の選択肢だそうですが、一般家庭の場合これに当てはまらないと思います。

    ネットワクークについてざっくり理解したい方は 以下の記事 をご覧ください。

    https://coiai.boy.jp/1465/

    さきほど、noip.comでせいさくしたドメインを入力してください。

    設定を間違ってしまった、
    変更したい、
    といった場合はconf ファイルから設定できます。

    sudo vi /etc/ddclient.conf


    ddclientの自動起動を設定します。

    sudo systemctl enable ddclient
    sudo systemctl start ddclient

    📕 参考サイト様

    no-ip の使い方
    https://www.noip.com/support/knowledgebase/free-dynamic-dns-getting-started-guide-ip-version

    🥦 まとめ

    ブロッコリーはいっぱい食べた方がええ!