知識(shí)要點(diǎn):表關(guān)系的實(shí)現(xiàn)
1.代碼復(fù)用喘鸟。
在我們用sqlalchemy操作數(shù)據(jù)庫時(shí)服赎,有部分代碼可以重復(fù)使用媒殉,我們將這部分放到一個(gè)模塊中迁客,后面使用就可以調(diào)用這個(gè)模塊郭宝,導(dǎo)入里面的方法。
# 1.連接數(shù)據(jù)庫
from sqlalchemy import create_engine
HOSTNAME = '127.0.0.1' # ip地址
PORT = '3306' # 端口號(hào)
DATABASE = 'mysqldb' # 數(shù)據(jù)庫名
USERNAME = 'root' # 用戶名
PASSWORD = 'password' # 用戶登錄密碼
DB_URI = 'mysql+pymysql://{}:{}@{}:{}/{}?charset=utf8'.format(USERNAME, PASSWORD, HOSTNAME, PORT, DATABASE)
engine = create_engine(DB_URI)
# 2. 聲明映像
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base(engine)
# 5.創(chuàng)建會(huì)話
from sqlalchemy.orm import sessionmaker
Session = sessionmaker(engine)
session = Session()
2.一對(duì)多表關(guān)系的實(shí)現(xiàn)
我們?cè)谥vmysql的時(shí)候?qū)W院與學(xué)生的關(guān)系是一對(duì)多關(guān)系掷漱,下面是通過SQLAlchemy來表示這種關(guān)系粘室。
from connect import Base,session
from sqlalchemy import Column,Integer,String,ForeignKey
from sqlalchemy.orm import relationship
class Department(Base):
__tablename__ = 'department'
d_id = Column(Integer,primary_key=True,autoincrement=True)
d_name = Column(String(100))
student = relationship('Student',backref='department')
def __repr__(self):
return '<Department(d_id="%s",d_name="%s")>' % (self.d_id, self.d_name)
class Student(Base):
__tablename__ = 'student'
s_id = Column(Integer,primary_key=True,autoincrement=True)
s_name = Column(String(50))
d_id = Column(Integer,ForeignKey('department.d_id'))
def __repr__(self):
return '<Student(s_id="%s",s_name="%s",d_id="%s")>' % (self.s_id, self.s_name, self.d_id)
Base.metadata.create_all()
講relationship之前,先回顧一下卜范,外鍵它是一個(gè)約束衔统,但是并不是代表了關(guān)系,之前所講的一對(duì)多海雪,一對(duì)一和多對(duì)多關(guān)系都是在我們的邏輯上锦爵,外鍵約束不能代表這種關(guān)系,注意分清外鍵是約束奥裸,沒有代表關(guān)系险掀。
而在SQLAlchemy里面,這個(gè)relationship代表了一對(duì)多的關(guān)系刺彩,當(dāng)然我們可以通過參數(shù)改變關(guān)系迷郑,它默認(rèn)是一對(duì)多的關(guān)系,而這個(gè)關(guān)系是SQLAlchemy里面的创倔,和數(shù)據(jù)庫沒有關(guān)系,但是relationship是和外鍵一起使用的嗡害。
通過relationship在學(xué)院的類中增加了一個(gè)學(xué)生的屬性,在學(xué)生的類中增加學(xué)生的屬性畦攘。這樣我們就可以通過這個(gè)屬性查出某個(gè)學(xué)院的所有的學(xué)生的列表霸妹,也可以查出某個(gè)學(xué)生的所屬學(xué)院,還可以通過學(xué)院的學(xué)生列表往這個(gè)學(xué)院中添加學(xué)員知押。
3.一對(duì)一表關(guān)系實(shí)現(xiàn)
我們?cè)谥vmysql的時(shí)候?qū)W生表與學(xué)生詳細(xì)信息表的關(guān)系是一對(duì)一關(guān)系叹螟,下面是通過SQLAlchemy來表示這種關(guān)系。
class Student(Base):
__tablename__ = 'student'
s_id = Column(Integer,primary_key=True,autoincrement=True)
s_name = Column(String(50))
d_id = Column(Integer,ForeignKey('department.d_id'))
stu_details = relationship('Stu_details',uselist=False)
def __repr__(self):
return '<Student(s_id="%s",s_name="%s",d_id="%s")>' % (self.s_id, self.s_name, self.d_id)
class Stu_details(Base):
__tablename__ = 'stu_details'
id = Column(Integer,primary_key=True,autoincrement=True)
age = Column(Integer)
city = Column(String(100))
s_id = Column(Integer,ForeignKey('student.s_id'),unique=True)
student = relationship('Student')
在這里實(shí)現(xiàn)一對(duì)一關(guān)系和我們mysql中稍微的差別台盯,我們通過外鍵加唯一鍵實(shí)現(xiàn)mysql層面的一對(duì)一罢绽,通過relationship中的uselist=False實(shí)現(xiàn)python層面的表關(guān)系。
4.多對(duì)多關(guān)系的實(shí)現(xiàn)
我們?cè)谥vmysql的時(shí)候?qū)W生與課程的關(guān)系是多對(duì)多關(guān)系静盅,下面是通過SQLAlchemy來表示這種關(guān)系良价。
stu_course = Table('stu_course',Base.metadata,
Column('s_id',Integer,ForeignKey('students.s_id'),primary_key=True),
Column('c_id',Integer,ForeignKey('course.c_id'),primary_key=True)
)
class Students(Base):
__tablename__ = 'students'
s_id = Column(Integer,primary_key=True)
s_name = Column(String(100))
course = relationship('Course',secondary=stu_course)
class Course(Base):
__tablename__ = 'course'
c_id = Column(Integer,primary_key=True)
c_name = Column(String(100))
students = relationship('Students',secondary=stu_course)
在多對(duì)多的關(guān)系中,我需要再建立一張表,通過這張表明垢,我們建立多對(duì)多的關(guān)系蚣常。使用relationship當(dāng)中secondary參數(shù)來獲取中間表,表示多對(duì)多關(guān)系痊银。
總結(jié)
在數(shù)據(jù)庫中外鍵只有約束的功能抵蚊,但是在SQLAlchemy中,relationship表示了關(guān)系溯革,但是這個(gè)關(guān)系只是在SQL Alchemy里面贞绳,和數(shù)據(jù)庫并沒有關(guān)系,在SQLALchemy里面鬓照,其實(shí)也是轉(zhuǎn)成SQL語句去做的熔酷,但是使用SQLAlchemy給我們提供的這個(gè)方法,可以讓我們寫跟少的SQL語言或者代碼豺裆。