【SQLAlchemy】03-SQLAlchemy関連
6805 ワード
いい風は力を借りて,私を青雲に送ってくれた.
SQLAlchemyを使用して外部キーを作成するのは簡単です.サブテーブルにフィールドを追加します.タイプは関連する親テーブルのフィールドタイプと一致します.
外部キー
上のコード
外部キー制約: RESTRICT:親テーブルデータが削除され、削除がブロックされます.デフォルトはこれです. NO ACTION:MySQLで、同じくRESTRICT. CASCADE:カスケード削除. SET NULL:親テーブルデータが削除され、子テーブルデータがNULLに設定されます.
サンプルコード:
一対多
上記のコードは、
注:マルチクラスクエリークラス クエリーのクラス
一対一
コードにより、1対1の関係は2つのクラスで
多対多多対多の関係は、中間テーブルを介して彼らの関係をバインドする必要があります. まず2つの多対多のモデルを定義する は マルチペアを作成する必要がある2つのモデルのうち任意に1つのモデルを選択し、3つの関係をバインドするためにrelationship属性を定義し、relationshipを使用する場合、
サンプルコード、記事対応ラベル:
ORMレベルでのデータ削除
ORMレベルでデータを削除するとmysqlレベルの外部キー制約は無視されます.対応するデータは直接削除され、テーブルの外部キーからNULLに設定されます.このような行為を回避するには、テーブルの外部キーの
SQLAlchemyでは、セッションに1つのデータを追加すれば、彼に関連付けられたデータをデータベースに一緒に保存できます.これらはどのように設定されていますか?実はrelationshipを通じて、これらの属性を設定できるキーワードパラメータ
SQLAlchemyを使用して外部キーを作成するのは簡単です.サブテーブルにフィールドを追加します.タイプは関連する親テーブルのフィールドタイプと一致します.
外部キー
class Parent(Base):
__tablename__ = 'parent'
id = Column(Integer, primary_key=True)
children = relationship("Child")
class Child(Base):
__tablename__ = 'child'
id = Column(Integer, primary_key=True)
parent_id = Column(Integer, ForeignKey('parent.id'))
上のコード
Parent
とChild
は外部キー関係を確立し、サブテーブルの外部キーparent_id
は親テーブルのプライマリキーid
に関連しているので、現在のフィールドタイプは親テーブルのid
タイプと一致する必要があり、次にForeignKey('parent.id')
のパラメータはテーブル名である.フィールド名は、モデル名に書かないでください.フィールド名: parent_id = Column(Integer, ForeignKey('parent.id'))
外部キー制約:
サンプルコード:
parent_id = Column(Integer, ForeignKey("parent.id", ondelete="CASCADE"))
一対多
class User(Base):
__tablename__ = 'user'
id = Column(Integer,primary_key=True,autoincrement=True)
username = Column(String(50),nullable=False)
# articles = relationship("Article")
class Article(Base):
__tablename__ = 'article'
id = Column(Integer,primary_key=True,autoincrement=True)
title = Column(String(50),nullable=False)
content = Column(Text,nullable=False)
author = relationship("User",backref="articles")
上記のコードは、
user
--article
が1対多の関係であることを示している.すなわち、1人が複数の文章を発表することができるので、author
の外部キーフィールドがuser
表のプライマリキーに関連付けられ、relationship
を提供している.このクラスは属性を定義することができる.後で関連するテーブルにアクセスするときに直接属性アクセスでアクセスできます.注:
relationship
の最初のパラメータはモデル名であり、backref
は逆クエリを表します.たとえば、次のようになります.article = session.query(Article).first()
#
user = article.author
print(user.username)
user = session.query(User).first()
articles = user.articles
backref
:主にクエリー・マルチクラスとして使用されます.このパラメータをマルチクラスのrelationship
で使用しない場合は、クラスでrelationship
を定義する必要があります.たとえば、次のようにします.class User(Base):
__tablename__ = 'user'
id = Column(Integer,primary_key=True,autoincrement=True)
username = Column(String(50),nullable=False)
#
articles = relationship("Article")
一対一
sqlalchemy
で、2つのモデルを1対1の関係にマッピングする場合は、親モデルで参照を指定するときに、uselist=False
というパラメータを渡す必要があります.親モデルに、後でこれをモデルから参照するときは、リストではなくオブジェクトであることを伝えます.class User(Base):
__tablename__ = 'user'
id = Column(Integer,primary_key=True,autoincrement=True)
username = Column(String(50),nullable=False)
extend = relationship("UserExtend",uselist=False)
class UserExtend(Base):
__tablename__ = 'user_extend'
id = Column(Integer, primary_key=True, autoincrement=True)
school = Column(String(50))
uid = Column(Integer,ForeignKey("user.id"))
user = relationship("User",backref="extend")
コードにより、1対1の関係は2つのクラスで
relationship
を定義しているが、親パラメータの複数の1つのuselist=False
は、結果セットではなく1対1の関係がオブジェクトであることを示している.1対のマルチプロセスではTrue
がデフォルトである.2つのクラスがrelationship
を定義しているため、同様にサブクラスのみで定義されるように簡略化することができる.コードは以下の通りである.from sqlalchemy.orm import backref
class UserExtend(Base):
......
user = relationship("User",backref=backref("extend",uselist=False))
多対多
Table
を使用して中間テーブルを定義し、中間テーブルは一般的に2つのモデルを含む外部キーフィールドであり、2つを複合プライマリキーとして使用する.secondary=
を入力する必要があります.サンプルコード、記事対応ラベル:
# ------------------------ ------------------------------
article_tag = Table(
"article_tag", #
Base.metadata,
Column("article_id", Integer, ForeignKey("article.id"), primary_key=True), # article
Column("tag_id", Integer, ForeignKey("tag.id"), primary_key=True) # tag
)
# -----------------------Article----------------------------
class Article(Base):
__tablename__ = "article"
id = Column(Integer, primary_key=True, autoincrement=True)
title = Column(String(50), nullable=False)
content = Column(Text, nullable=False)
# , , article
tags = relationship("Tag", backref="articles", secondary=article_tag)
# -----------------------Tag--------------------------------
class Tag(Base):
__tablename__ = "tag"
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String(50), nullable=False)
ORMレベルでのデータ削除
ORMレベルでデータを削除するとmysqlレベルの外部キー制約は無視されます.対応するデータは直接削除され、テーブルの外部キーからNULLに設定されます.このような行為を回避するには、テーブルの外部キーの
nullable=False
から空にブロックする必要があります.SQLAlchemyでは、セッションに1つのデータを追加すれば、彼に関連付けられたデータをデータベースに一緒に保存できます.これらはどのように設定されていますか?実はrelationshipを通じて、これらの属性を設定できるキーワードパラメータ
cascade
があります.user = relationship("User",backref="extend",cascade="save-update,delete") #
save-update
:デフォルトのオプション.データを追加すると、他の関連データがデータベースに追加されます.この動作はsave-updateプロパティによって影響されます.user = User(...)
article = Article(...)
article.author = user
session.add(article) # article, user commit
session.commit()
delete
:あるモデルのデータを削除するときにrelationshipを使用して関連するデータも削除するかどうかを示す.delete-orphan
:親テーブルの関連オブジェクトを1つのORMオブジェクトに対して解除すると、自分が削除されることを示します.もちろん、親テーブルのデータが削除されると、自分も削除されます.このオプションは1対多にしか使用できません.多対多および多対一には使用できません.さらに、サブモデルのrelationship
において、single_parent=True
のパラメータを追加する必要がある.class Article(Base):
......
author = relationship("User",backref=backref("articles",cascade="all"),cascade="save-update",single_parent=True,ondelete='')
merge
:デフォルトのオプション.session.merge
を使用してオブジェクトを結合すると、relationship
を使用して関連付けられたオブジェクトもmerge
操作されます.expunge
:削除操作すると、関連するオブジェクトも削除されます.この操作はsession
から削除されるだけで、データベースから削除されることはありません.all
:save-update, merge, refresh-expire, expunge, delete
のいくつかの略語です.