sqlalchemyでテーブルを動的に生成する

3106 ワード

sqlalchemyの初心者として、完全に自分のニーズに基づいて勉強しています.最近、問題が発生しました.現在、手元にログ・ファイルがたくさんあり、日ごとに整理され、毎日のログ・ファイルが同じディレクトリの下に個別に置かれています.各ディレクトリの下のファイルの個数は異なり、どれだけ少ないか、各ファイルにはいくつかの記録が含まれているため、毎日のこれらのログファイルに含まれる総記録数も異なり、少なければ20万件以上、多ければ6000万件以上である.処理を容易にするために、これらのレコードをすべてデータベースに格納する必要があります.合計47日間、この47日間のすべてのログ・レコードをデータベースの同じテーブルにすべて格納すると、クエリーが遅くなります.そこで,まずログ記録を分割し,異なるログを異なるテーブルに入れる必要があり,自然と同じ日のすべてのログを同じテーブルに入れることが最も簡単であると考えられる.このように、データベースに47個のテーブルを作成し、各ディレクトリのログファイルのすべてのレコードを対応するテーブルに挿入する必要があります.
sqlalchemyを使用したことがあることはよく知られていますが、pythonの有名なORMフレームワークであり、リレーショナル・データベースのテーブル構造をオブジェクトにマッピングすることを実現しています.sqlalchemyの一般的な使用方法に従って、データベース内の各テーブルに対応するクラスを定義する必要があります.複数のテーブルがある場合は、複数のクラスを定義する必要がありますが、ここでは、作成する必要があるテーブルのフィールドは完全に同じですが、テーブル名が異なるだけです.そのため、テーブル構造を記述するためのクラスを1つだけ定義する方法が必要です.その後、このクラスをすべてのテーブルに関連付ける方法が必要です.インターネットで資料を検索することで、このニーズを実現する方法が見つかりました.つまり、テーブルに対応するクラスを定義する際に__を使用します.abstract__ = True文は、pythonのtypeメソッドを使用してデータベース・テーブルに対応するクラスを動的に生成することができます.コードを見てみましょう.
#   __abstract__=True               

class ConLogClass(Base):                                                             

    __abstract__ = True                                                              

    # __tablename__ == should be 'conlog_%s'                                         

                                                                                     

    id = Column(Integer, primary_key=True)                                           

    device_id = Column(Integer)                                                      

    sample_time = Column(Integer)                                                    

    sip = Column(String(16))                                                         

    dip = Column(String(16))         
#    ID       

cid_class_dict = {}
#    ID   

 def get_conlog_model(cid):                                                                                                                                       

        if cid not in cid_class_dict:

            cls_name, table_name = get_class_name_and_table_name(cid)

            cls = type(cls_name, (ConLogClass, ), {'__tablename__': table_name})

            cid_class_dict[cid] = cls

        return cid_class_dict[cid]
#    ID       

def get_class_name_and_table_name(self, cid):

         return 'ConLog%s' % cid, 'conlog_%s' % cid
#        

engine = create_engine('mysql+mysqldb://root:[email protected]:3306/logs')

#   session

DBSession = sessionmaker(bind=engine)

session = DBSession()

cid = 1112

#    ID           

model = get_conlog_model(cid)

#               

 re = model(device_id=data[‘device_id’],

                        sample_time = data[’sample_time’],

                        sip = data[’sip’],

                        dip = data[‘dip’])

#      session

session.add(re)

#     

session.commit()

これでsqlalchemyを用いてデータベーステーブルを動的に生成する機能が実現し,次にログの挿入とクエリー機能を実現するだけでよい.原理は同じであり,異なるテーブルIDから異なるクラスモデルが得られ,クラスモデルによりレコードが生成される.