Python-data-persistence-sqlalchemy
Pythonデータの永続性-SQLAlchemy
リレーショナルデータベースは、データをテーブルに保持します。 テーブル構造は属性のデータタイプを定義します。基本的には、対応するPythonの組み込みデータタイプにマップされるプライマリデータタイプのみです。 ただし、Pythonのユーザー定義オブジェクトを永続的に保存したり、SQLテーブルとの間で取得したりすることはできません。
これは、SQL型とPythonなどのオブジェクト指向プログラミング言語との違いです。 SQLには、dict、タプル、リスト、またはユーザー定義クラスなど、他のものと同等のデータ型はありません。
オブジェクトをリレーショナルデータベースに格納する必要がある場合は、INSERTクエリを実行する前に、そのインスタンス属性を最初にSQLデータ型に分解する必要があります。 一方、SQLテーブルから取得したデータはプライマリタイプです。 目的のタイプのPythonオブジェクトは、Pythonスクリプトで使用するためにを使用して構築する必要があります。 これは、オブジェクトリレーショナルマッパーが役立つ場所です。
オブジェクト関係マッパー(ORM)
オブジェクト関係マッパー(ORM)は、クラスとSQLテーブル間のインターフェースです。 Pythonクラスはデータベース内の特定のテーブルにマップされるため、オブジェクトとSQLタイプの間の変換が自動的に実行されます。
Pythonコードで記述されたStudentクラスは、データベースのStudentテーブルにマップされます。 その結果、すべてのCRUD操作は、クラスのそれぞれのメソッドを呼び出すことによって実行されます。 これにより、PythonスクリプトでハードコードされたSQLクエリを実行する必要がなくなります。
したがって、ORMライブラリは、生のSQLクエリに対する抽象化レイヤーとして機能し、迅速なアプリケーション開発に役立ちます。 SQLAlchemy は、Pythonでよく使用されるオブジェクトリレーショナルマッパーです。 モデルオブジェクトの状態の操作は、データベーステーブルの関連する行と同期されます。
SQLALchemyライブラリには、 ORM API およびSQL式言語( SQLAlchemy Core )が含まれています。 式言語は、リレーショナルデータベースのプリミティブコンストラクトを直接実行します。
ORMは、SQL式言語の上に構築された、高レベルで抽象化された使用パターンです。 ORMは、式言語を応用したものと言えます。 このトピックでは、SQLAlchemy ORM APIについて説明し、SQLiteデータベースを使用します。
SQLAlchemyは、方言システムを使用して、それぞれのDBAPI実装を通じてさまざまなタイプのデータベースと通信します。 すべての方言では、適切なDBAPIドライバーがインストールされている必要があります。 次のタイプのデータベースの方言が含まれています-
- 火の鳥
- Microsoft SQL Server
- MySQL
- オラクル
- PostgreSQL
- SQLite
- Sybase
SQLAlchemyのインストールは、pipユーティリティを使用して簡単かつ簡単です。
pip install sqlalchemy
SQLalchemyが正しくインストールされているかどうかとそのバージョンを確認するには、Pythonプロンプトで次のように入力します-
>>> import sqlalchemy
>>>sqlalchemy.__version__
'1.3.11'
データベースとの相互作用は、* create_engine()*関数の戻り値として取得された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にはオプションのエコー引数があります。 trueに設定すると、エンジンによって生成されたSQLクエリが端末にエコーされます。
SQLAlchemyには*宣言ベース*クラスが含まれています。 モデルクラスとマップされたテーブルのカタログとして機能します。
from sqlalchemy.ext.declarative import declarative_base
base=declarative_base()
次のステップはモデルクラスを定義することです。 上記のdeclarative_baseクラスのオブジェクトであるbaseから派生する必要があります。
tablenameプロパティを、データベースに作成するテーブルの名前に設定します。 その他の属性はフィールドに対応しています。 それぞれがSQLAlchemyのColumnオブジェクトであり、そのデータ型は以下のリストの1つからのものです-
- BigInteger
- ブール値
- Date
- 日付時刻
- 浮く
- 整数
- 数値
- SmallInteger
- ひも
- 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)
対応する構造を持つStudentテーブルを作成するには、基本クラスに定義された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()メソッドがあります。 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()