ブログシステムその2

データベース

Posted by めろん on 2024/05/27 00:12

【PR】本記事はアフィリエイト広告を利用しています。

サーバについて

このブログシステムはフルスクラッチで作成されていてVPS上で稼働しているという話は前回していると思いますが、

お安いプランで私がかれこれ数年近く運用しています。
スペックもかなり低めで構築していますが、ブログ程度の運用であれば問題ないということです。

データベース接続


お気づきの通り(?)このシステムはpython3で構築されています。
また高速に動作させる為にtornadoを利用しています。
Djangoとかあるのになんでこれなのかというと、軽いからです。

データベースは、MariaDBを利用してオリジナルの薄いラッパーを作ってます。
まあこんなの役に立つのかしりませんが、私が作ったライブラリは以下の通りです。

参考程度にしてください。
なんの保証もしません。
趣味で作ってるものなので、適当です。
利用する場合は、ここのサイトを紹介してもらえればありがたいです。

メソッド名がマイクロソフトさんみたいな名前にしているのはご愛敬ってことで(笑)
DAO風味ですかね、VB6風味というか懐かしい香りがするでしょ?

importしているmariadbのライブラリは純正で御座います。

# Module Imports
# coding: utf-8
import mariadb
import sys

#------------------------------------------------------------------------------
#   MariaDB接続ラッパークラス
#------------------------------------------------------------------------------
class   MariaDBRecordSet:
    #--------------------------------------------------------------------------
    #   コンストラクタ
    #--------------------------------------------------------------------------
    def __init__( self, Cursor ):
        try:
            self.cur  = Cursor      #   カーソル
            self.Record = None      #   レコードデータ
        except Exception as e:
            print( str( e ) )

    #--------------------------------------------------------------------------
    #   デストラクタ
    #--------------------------------------------------------------------------
    def __del__( self ):
        try:
            #   クローズさせる
            if( self.cur is not None ):
                self.cur.close()
                self.conn = None
                self.index = 0
        except Exception as e:
            print( str( e ) )

    #--------------------------------------------------------------------------
    #   レコードがもうない場合はTrue それ以外は False
    #--------------------------------------------------------------------------
    def IsEOF( self ):
        try:
            if( self.Record is None ):
                return True
            else:
                return False
        except Exception as e:
            print( str( e ) )
            return False

    #--------------------------------------------------------------------------
    #   カラム数の取得
    #--------------------------------------------------------------------------
    def __len__( self ):
        try:
            return len( self.Record )
        except Exception as e:
            print( str( e ) )
            return 0
    #--------------------------------------------------------------------------
    #   カラム数の取得
    #--------------------------------------------------------------------------
    def ColCount( self ):
        try:
            return len( self.Record )
        except Exception as e:
            print( str( e ) )
            return 0

    #--------------------------------------------------------------------------
    #   値取得
    #--------------------------------------------------------------------------
    def ColValue( self, ColNo ):
        try:
            return self.Record[ ColNo ]
        except Exception as e:
            print( str( e ) )
            return None

   
    #--------------------------------------------------------------------------
    #   nextはiterとセット
    #--------------------------------------------------------------------------
    def __iter__( self ):
        try:
            return self
        except Exception as e:
            print( str( e ) )
            return None

    def __next__( self ):
        if( self.Record is None ):
            raise StopIteration()
        #   既にない場合
        if( self.index >= len( self.Record ) ):
            raise StopIteration()
        Value = self.Record[self.index]
        self.index = self.index + 1
        return Value

    #--------------------------------------------------------------------------
    #   カーソル移動
    #--------------------------------------------------------------------------
    def MoveNext( self ):
        try:
            self.index = 0
            self.Record = self.cur.fetchone()
            return self.Record
        except Exception as e:
            print( str( e ) )

#------------------------------------------------------------------------------
#   MariaDB接続ラッパークラス
#
#   オフィシャル:https://mariadb.com/docs/server/connect/programming-languages/python/
#   ドライバ準拠:https://peps.python.org/pep-0249/
#   カーソル操作:https://peps.python.org/pep-0249/#cursor-objects
#------------------------------------------------------------------------------
class   MariaDB:
    #   コンストラクタ
    def __init__( self ):
        try:
            self.conn   = None
        except Exception as e:
            print( str( e ) )
    #   デストラクタ
    def __del__( self ):
        try:
            #   クローズさせる
            if( self.conn is not None ):
                self.conn.close()
                self.conn = None
        except Exception as e:
            print( str( e ) )

    #
    #   再接続
    #
    def ReConnect(self):
        try:
            self.conn = mariadb.connect(
                user=self.UserId,
                password=self.Password,
                host=self.HostName,
                port=self.PortNo,
                database=self.DataBase
            )
        except mariadb.Error as e:
            print(f"MariaDB プラットフォームへの接続エラー: {e}")
        except Exception as e:
            print( str( e ) )

    #--------------------------------------------------------------------------
    #   値取得
    #--------------------------------------------------------------------------
    def Connect( self,
                 UserId = "",
                 Password = "",
                 HostName = "",
                 DataBase = "",
                 PortNo = 3306 ):
        try:
            self.UserId = UserId
            self.Password = Password
            self.HostName = HostName
            self.DataBase = DataBase
            self.PortNo = PortNo

            self.conn = mariadb.connect(
                user=self.UserId,
                password=self.Password,
                host=self.HostName,
                port=self.PortNo,
                database=self.DataBase
            )
        except mariadb.Error as e:

            print(f"MariaDB プラットフォームへの接続エラー: {e}")

        except Exception as e:
            print( str( e ) )

    #--------------------------------------------------------------------------
    #   SQLの実行(戻り値なし)
    #--------------------------------------------------------------------------
    def ExecuteSQL( self, SQLStr = "" ):
        try:
            if( self.conn is None ):
                print( "データベースに接続されていません" )
                return None
            #   カーソルの作成
            cur = self.conn.cursor()
            cur.execute( SQLStr )
            #   コネクターでコミットする必要があるようだ
            #   https://mariadb.com/ja/resources/blog/how-to-connect-python-programs-to-mariadb/
            self.conn.commit()
            cur.close()
            return True

        except Exception as e:
            print( str(e) )
            if( "Server has gone away" == str( e ).strip() ):
                #   DBから強制的に切断された場合
                self.ReConnect()
                return self.ExecuteSQL(SQLStr)
            return False

    #--------------------------------------------------------------------------
    #   レコードセットの取得
    #--------------------------------------------------------------------------
    def OpenRecordSet( self, SQLStr = "" ):
        try:
            if( self.conn is None ):
                print( "データベースに接続されていません" )
                return None
            #   カーソルの作成
            cur = self.conn.cursor()
            cur.execute( SQLStr )
            Rec = MariaDBRecordSet( cur, )
            Rec.MoveNext()
            return Rec

        except Exception as e:
            print(str(e))
            if( "Server has gone away" == str( e ).strip() ):
                #   DBから強制的に切断された場合
                self.ReConnect()
                return self.OpenRecordSet(SQLStr)
            return None

私は旧式の人間なので、SQL文はダイレクトで弄りたい人です。

フレームワークで勝手にクラス作って中で何しているのか分からないのがどうも具合が悪いんです。

このシステムもテンプレートをつかったMVCモデルで作っております。
というか、クライアント部分はjavascriptでゴリゴリ書かなければならず
デザインも見ればわかると思いますがbootstrapを使用しテンプレート単位でカスタムなcssファイルを
作ってます。

最初はSQLを直接テーブルにインサートして記事を書いてましたが(笑)流石にメンドクサイなと思って
記事管理コンソールと記事追加編集画面を作って、今もその画面で編集しています。

画像をアップロードするのも手動でしてたので面倒だったんです。

後、クリップボードから直接イメージの貼り付けなんかもできるようにしました。
個別にアップロードしてリンクを埋め込んだりするのはメンドクサイですしね。