Pythonデータの永続性-SQLAlchemy

リレーショナルデータベースは、データをテーブルに保持します。テーブル構造は、Pythonの対応する組み込みデータ型にマップされる基本的にプライマリデータ型のみの属性のデータ型を定義します。ただし、Pythonのユーザー定義オブジェクトを永続的に保存したり、SQLテーブルとの間で取得したりすることはできません。

これは、SQLタイプとPythonなどのオブジェクト指向プログラミング言語との違いです。SQLには、dict、tuple、list、またはユーザー定義クラスなど、他のSQLと同等のデータ型はありません。

オブジェクトをリレーショナルデータベースに格納する必要がある場合は、INSERTクエリを実行する前に、まずそのインスタンス属性をSQLデータ型に分解する必要があります。一方、SQLテーブルから取得されるデータはプライマリタイプです。目的のタイプのPythonオブジェクトは、Pythonスクリプトで使用するためにを使用して構築する必要があります。ここで、オブジェクトリレーショナルマッパーが役立ちます。

オブジェクトリレーションマッパー(ORM)

アン Object Relation Mapper(ORM)は、クラスとSQLテーブルの間のインターフェースです。Pythonクラスはデータベース内の特定のテーブルにマップされるため、オブジェクトタイプとSQLタイプの間の変換が自動的に実行されます。

Pythonコードで記述されたStudentsクラスは、データベースのStudentsテーブルにマップされます。その結果、すべてのCRUD操作は、クラスのそれぞれのメソッドを呼び出すことによって実行されます。これにより、PythonスクリプトでハードコードされたSQLクエリを実行する必要がなくなります。

したがって、ORMライブラリは、生のSQLクエリの抽象化レイヤーとして機能し、迅速なアプリケーション開発に役立ちます。 SQLAlchemyPythonで人気のあるオブジェクトリレーショナルマッパーです。モデルオブジェクトの状態の操作は、データベーステーブルの関連する行と同期されます。

SQLALchemyライブラリには ORM API およびSQL式言語(SQLAlchemy Core)。式言語は、リレーショナルデータベースのプリミティブ構造を直接実行します。

ORMは、SQL式言語の上に構築された高レベルで抽象化された使用パターンです。ORMは式言語の応用使用法であると言えます。このトピックでは、SQLAlchemy ORM APIについて説明し、SQLiteデータベースを使用します。

SQLAlchemyは、方言システムを使用したそれぞれのDBAPI実装を通じて、さまざまなタイプのデータベースと通信します。すべての方言では、適切なDBAPIドライバーがインストールされている必要があります。以下のタイプのデータベースの方言が含まれています-

  • Firebird
  • Microsoft SQL Server
  • MySQL
  • Oracle
  • PostgreSQL
  • SQLite
  • Sybase

SQLAlchemyのインストールは、pipユーティリティを使用して簡単かつ簡単です。

pip install sqlalchemy

SQLalchemyが正しくインストールされているかどうかとそのバージョンを確認するには、Pythonプロンプトで次のように入力します-

>>> import sqlalchemy
>>>sqlalchemy.__version__
'1.3.11'

データベースとの相互作用は、の戻り値として取得されたEngineオブジェクトを介して行われます。 create_engine() 関数。

engine =create_engine('sqlite:///mydb.sqlite')

SQLiteを使用すると、インメモリデータベースを作成できます。インメモリデータベース用のSQLAlchemyエンジンは次のように作成されます-

from sqlalchemy import create_engine
engine=create_engine('sqlite:///:memory:')

代わりにMySQLデータベースを使用する場合は、そのDB-APIモジュール(pymysqlとそれぞれの方言ドライバー)を使用してください。

engine = create_engine('mysql+pymydsql://root@localhost/mydb')

create_engineには、オプションのecho引数があります。trueに設定すると、エンジンによって生成されたSQLクエリが端末にエコーされます。

SQLAlchemyには declarative baseクラス。モデルクラスとマップされたテーブルのカタログとして機能します。

from sqlalchemy.ext.declarative import declarative_base
base=declarative_base()

次のステップは、モデルクラスを定義することです。上記のdeclarative_baseクラスのベース–オブジェクトから派生する必要があります。

セットする __tablename__プロパティからデータベースに作成するテーブルの名前。その他の属性はフィールドに対応しています。それぞれがSQLAlchemyのColumnオブジェクトであり、そのデータ型は以下のリストのいずれかからのものです-

  • BigInteger
  • Boolean
  • Date
  • DateTime
  • Float
  • Integer
  • Numeric
  • SmallInteger
  • String
  • Text
  • Time

次のコードは、StudentsテーブルにマップされるStudentという名前のモデルクラスです。

#myclasses.py
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, Numeric
base=declarative_base()
class Student(base):
   __tablename__='Students'
   StudentID=Column(Integer, primary_key=True)
   name=Column(String)
   age=Column(Integer)
   marks=Column(Numeric)

対応する構造を持つStudentsテーブルを作成するには、基本クラスに対して定義されたcreate_all()メソッドを実行します。

base.metadata.create_all(engine)

次に、Studentクラスのオブジェクトを宣言する必要があります。データベースからのデータの追加、削除、取得などのすべてのデータベーストランザクションは、Sessionオブジェクトによって処理されます。

from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind=engine)
sessionobj = Session()

Studentオブジェクトに格納されているデータは、セッションのadd()メソッドによって基になるテーブルに物理的に追加されます。

s1 = Student(name='Juhi', age=25, marks=200)
sessionobj.add(s1)
sessionobj.commit()

これは、studentsテーブルにレコードを追加するためのコード全体です。実行されると、対応するSQLステートメントログがコンソールに表示されます。

from sqlalchemy import Column, Integer, String
from sqlalchemy import create_engine
from myclasses import Student, base
engine = create_engine('sqlite:///college.db', echo=True)
base.metadata.create_all(engine)

from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind=engine)
sessionobj = Session()
s1 = Student(name='Juhi', age=25, marks=200)
sessionobj.add(s1)
sessionobj.commit()

コンソール出力

CREATE TABLE "Students" (
   "StudentID" INTEGER NOT NULL,
   name VARCHAR,
   age INTEGER,
   marks NUMERIC,
   PRIMARY KEY ("StudentID")
)
INFO sqlalchemy.engine.base.Engine ()
INFO sqlalchemy.engine.base.Engine COMMIT
INFO sqlalchemy.engine.base.Engine BEGIN (implicit)
INFO sqlalchemy.engine.base.Engine INSERT INTO "Students" (name, age, marks) VALUES (?, ?, ?)
INFO sqlalchemy.engine.base.Engine ('Juhi', 25, 200.0)
INFO sqlalchemy.engine.base.Engine COMMIT

ザ・ session オブジェクトは、単一のトランザクションに複数のオブジェクトを挿入するためのadd_all()メソッドも提供します。

sessionobj.add_all([s2,s3,s4,s5])
sessionobj.commit()

これで、レコードがテーブルに追加されたので、SELECTクエリと同じようにテーブルからフェッチしたいと思います。セッションオブジェクトには、タスクを実行するためのquery()メソッドがあります。クエリオブジェクトは、Studentモデルのquery()メソッドによって返されます。

qry=seesionobj.query(Student)

このQueryオブジェクトのget()メソッドを使用して、指定された主キーに対応するオブジェクトをフェッチします。

S1=qry.get(1)

このステートメントが実行されている間、コンソールにエコーされる対応するSQLステートメントは次のようになります。

BEGIN (implicit)
SELECT "Students"."StudentID" AS "Students_StudentID", "Students".name AS 
   "Students_name", "Students".age AS "Students_age", 
   "Students".marks AS "Students_marks"
FROM "Students"
WHERE "Products"."Students" = ?
sqlalchemy.engine.base.Engine (1,)

query.all()メソッドは、ループを使用してトラバースできるすべてのオブジェクトのリストを返します。

from sqlalchemy import Column, Integer, String, Numeric
from sqlalchemy import create_engine
from myclasses import Student,base
engine = create_engine('sqlite:///college.db', echo=True)
base.metadata.create_all(engine)
from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind=engine)
sessionobj = Session()
qry=sessionobj.query(Students)
rows=qry.all()
for row in rows:
   print (row)

マップされたテーブルのレコードの更新は非常に簡単です。get()メソッドを使用してレコードをフェッチし、目的の属性に新しい値を割り当ててから、セッションオブジェクトを使用して変更をコミットするだけです。以下では、Juhiの学生のマークを100に変更します。

S1=qry.get(1)
S1.marks=100
sessionobj.commit()

セッションから目的のオブジェクトを削除することで、レコードの削除も同様に簡単です。

S1=qry.get(1)
Sessionobj.delete(S1)
sessionobj.commit()