ホームページ  >  記事  >  バックエンド開発  >  初心者向けに 5 分で Python を学び SQL で遊べる魔法のツール!

初心者向けに 5 分で Python を学び SQL で遊べる魔法のツール!

WBOY
WBOY転載
2023-04-12 17:28:151715ブラウズ

初心者向けに 5 分で Python を学び SQL で遊べる魔法のツール!

背景

実は最初はpymysqlを使っていたのですが、メンテナンスが面倒でコードインジェクションのリスクもあったため、単純にORMを使っていました。フレームワークを直接。

ORMとはObject Relational Mapperのことで、簡単に言うとデータベースのテーブルとPythonのクラスとのマッピングであり、Pythonのクラスを操作することで間接的にデータベースを操作することができます。

より有名な Python ORM フレームワークは、SQLAlchemy と Peewee です。ここでは比較はしませんが、SQLAlchemy の個人的な使用法について簡単に説明します。友人全員の役に立てば幸いです。

  • sqlalchemy バージョン: 1.3.15
  • pymysql バージョン: 0.9.3
  • mysql バージョン: 5.7

初期化作業

一般に、ORM フレームワークを使用する場合、データベース接続、基本的なマッピングの定義など、いくつかの初期化作業が必要になります。

MySQL を例に挙げると、データベース接続を作成するには、DSN 文字列を渡すだけで済みます。エコーは、対応する SQL ステートメントを出力するかどうかを示し、デバッグに役立ちます。

from sqlalchemy import create_engine
engine = create_engine('mysql+pymysql://$user:$password@$host:$port/$db?charset=utf8mb4', echo=True)

個人的なデザイン

私個人としては、ORM フレームワークを導入するときに、私のプロジェクトでは次のデザインの MVC パターンを参照します。このうち、model にはいくつかのデータベース モデル、つまりデータベース テーブルにマッピングされた Python クラスが格納され、model_op には各モデルに対応する操作 (追加、削除、確認、変更) が格納され、呼び出し元 (main.py など) が実行されるときに、データベース操作を実行する場合、model_op 層を呼び出すだけで済みます。分離を実現するためにモデル層を気にする必要はありません。

├── main.py
├── model
│ ├── __init__.py
│ ├── base_model.py
│ ├── ddl.sql
│ └── py_orm_model.py
└── model_op
 ├── __init__.py
 └── py_orm_model_op.py

マッピングステートメント (モデルの紹介)

たとえば、このようなテストテーブルがある場合

create table py_orm (
 `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '唯一id',
 `name` varchar(255) NOT NULL DEFAULT '' COMMENT '名称',
 `attr` JSON NOT NULL COMMENT '属性',
 `ct` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
 `ut` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON update CURRENT_TIMESTAMP COMMENT '更新时间',
 PRIMARY KEY(`id`)
)ENGINE=InnoDB COMMENT '测试表';

ORM フレームワークでは、マッピング結果は Class 以下の Python です

# py_orm_model.py
from .base_model import Base
from sqlalchemy import Column, Integer, String, TIMESTAMP, text, JSON
class PyOrmModel(Base):
 __tablename__ = 'py_orm'
 id = Column(Integer, autoincrement=True, primary_key=True, comment='唯一id')
 name = Column(String(255), nullable=False, default='', comment='名称')
 attr = Column(JSON, nullable=False, comment='属性')
 ct = Column(TIMESTAMP, nullable=False, server_default=text('CURRENT_TIMESTAMP'), comment='创建时间')
 ut = Column(TIMESTAMP, nullable=False, server_default=text('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'), comment='更新时间')

まず、PyOrmModel が Base クラスを継承していることがわかります。これは、sqlalchemy によって提供される基本クラスです。これは、宣言した Python クラスに対していくつかのチェックを行い、それをbase_model に置きます。

# base_model.py
# 一般base_model做的都是一些初始化的工作
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
engine = create_engine("mysql+pymysql://root:123456@127.0.0.1:33306/orm_test?charset=utf8mb4", echo=False)

第二に、各 Python クラスには __tablename__ 属性が含まれている必要があります。そうでないと、対応するテーブルが見つかりません。

3 番目に、データ テーブルを作成するには 2 つの方法があります。1 つ目は、MySQL で手動で作成する方法です。Python クラスの定義に問題がない限り、正常に動作します。2 つ目は、MySQL で手動で作成する方法です。次のような ORM フレームワークの作成を使用することです。

# main.py
# 注意这里的导入路径,Base创建表时会寻找继承它的子类,如果路径不对,则无法创建成功
from sqlachlemy_lab import Base, engine
if __name__ == '__main__':
 Base.metadata.create_all(engine)

作成効果:

...
2020-04-04 10:12:53,974 INFO sqlalchemy.engine.base.Engine
CREATE TABLE py_orm (
id INTEGER NOT NULL AUTO_INCREMENT,
name VARCHAR(255) NOT NULL DEFAULT '' COMMENT '名称',
attr JSON NOT NULL COMMENT '属性',
ct TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
ut TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
 PRIMARY KEY (id)
)

4 番目、フィールド属性について

  • 1.primary_key と autoincrement の方が簡単です理解すると、これらは MySQL の主キーと増分属性です。
  • 2. int型の場合は長さを指定する必要はありませんが、varchar型の場合は長さを指定する必要があります。
  • 3.nullable は、MySQL の NULL と NOT NULL に対応します
  • 4.default とserver_default について:default は、ORM フレームワーク レベルでのデフォルト値を表します。つまり、フィールドが挿入されるときにフィールドが挿入されるかどうかを表します。 Inserting 値が割り当てられていない場合は、定義したデフォルト値が使用されます。server_default はデータベース レベルのデフォルト値を表し、これは DDL ステートメントのデフォルトのキーワードです。

セッションの紹介

SQLAlchemy ドキュメントには、データベースへの追加、削除、変更はセッションを通じて実行されると記載されています。

>>> from sqlalchemy.orm import sessionmaker
>>> Session = sessionmaker(bind=engine)
>>> session = Session()
>>> orm = PyOrmModel(id=1, name='test', attr={})
>>> session.add(orm)
>>> session.commit()
>>> session.close()

上記のように、操作ごとにセッションを取得、送信、解放する必要があることがわかります。これは冗長で面倒なので、通常はカプセル化の層を実行します。

1. コンテキスト マネージャーを使用して、セッションの異常なロールバックと終了を処理します。この部分は参照記事とほぼ一致しています。

# base_model.py
from contextlib import contextmanager
from sqlalchemy.orm import sessionmaker, scoped_session
def _get_session():
 """获取session"""
 return scoped_session(sessionmaker(bind=engine, expire_on_commit=False))()
# 在这里对session进行统一管理,包括获取,提交,回滚和关闭
@contextmanager
def db_session(commit=True):
 session = _get_session()
 try:
 yield session
 if commit:
 session.commit()
 except Exception as e:
 session.rollback()
 raise e
 finally:
 if session:
 session.close()

2. PyOrmModelにmodelとdict間の変換用メソッドを2つ追加

class PyOrmModel(Base):
 ...
 @staticmethod
 def fields():
 return ['id', 'name', 'attr']
 @staticmethod
 def to_json(model):
 fields = PyOrmModel.fields()
 json_data = {}
 for field in fields:
 json_data[field] = model.__getattribute__(field)
 return json_data
 @staticmethod
 def from_json(data: dict):
 fields = PyOrmModel.fields()
 model = PyOrmModel()
 for field in fields:
 if field in data:
 model.__setattr__(field, data[field])
 return model

3. データベース操作のカプセル化、参考記事と違い直接呼び出します セッションは削除されているので、つまり、呼び出し元はモデル層に注意を払う必要がなく、結合が軽減されます。

# py_orm_model_op.py
from sqlachlemy_lab.model import db_session
from sqlachlemy_lab.model import PyOrmModel
class PyOrmModelOp:
 def __init__(self):
 pass
 @staticmethod
 def save_data(data: dict):
 with db_session() as session:
 model = PyOrmModel.from_json(data)
 session.add(model)
 # 查询操作,不需要commit
 @staticmethod
 def query_data(pid: int):
 data_list = []
 with db_session(commit=False) as session:
 data = session.query(PyOrmModel).filter(PyOrmModel.id == pid)
 for d in data:
 data_list.append(PyOrmModel.to_json(d))
 return data_list

4.呼び出し元

# main.py
from sqlachlemy_lab.model_op import PyOrmModelOp
if __name__ == '__main__':
 PyOrmModelOp.save_data({'id': 1, 'name': 'test', 'attr': {}})

完全なコードについては、

https://github.com/yangancode/python_lab/tree/masterを参照してください。 / sqlachlemy_lab

以上が初心者向けに 5 分で Python を学び SQL で遊べる魔法のツール!の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事は51cto.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。