一對多關係
models表建立
import datetime
from sqlalchemy import create_engine
from sqlalchemy.orm import declarative_base, relationship
from sqlalchemy import Column, Integer, String, Text, ForeignKey, DateTime, UniqueConstraint, Index
Base = declarative_base() # Base 當成 models.Model
### 單表
class User(Base):
__tablename__ = 'users' # 表名
# 寫欄位
id = Column(Integer, primary_key=True, autoincrement=True) # id 主鍵
name = Column(String(32), index=True, nullable=False) # name列,索引,不可為空
email = Column(String(32), unique=True)
# datetime.datetime.now不能加括號,加了括號,以後永遠是當前時間
ctime = Column(DateTime, default=datetime.datetime.now)
extra = Column(Text)
def __str__(self):
return self.name
def __repr__(self):
return self.name
# 一對多 :一個興趣被多個人喜歡 一個人只喜歡一個興趣
class Hobby(Base):
__tablename__ = 'hobby'
id = Column(Integer, primary_key=True)
caption = Column(String(50), default='籃球')
def __str__(self):
return self.caption
def __repr__(self):
return self.caption
class Person(Base):
__tablename__ = 'person'
id = Column(Integer, primary_key=True)
name = Column(String(32), index=True, nullable=True)
# hobby指的是tablename而不是類名,uselist=False
# 外來鍵關聯--》強外來鍵--》物理外來鍵
hobby_id = Column(Integer, ForeignKey("hobby.id"))
# 跟資料庫無關,不會新增欄位,只用於快速連表操作
# 類名,backref用於反向查詢
hobby = relationship('Hobby', backref='pers')
def __str__(self):
return self.name
def __repr__(self):
return self.name
操作
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from models import Hobby, Person, User
engine = create_engine(
"mysql+pymysql://root:1234@127.0.0.1:3306/sqlalchemy02",
max_overflow=0, # 超過連線池大小外最多建立的連線
pool_size=5, # 連線池大小
pool_timeout=30, # 池中沒有執行緒最多等待的時間,否則報錯
pool_recycle=-1 # 多久之後對執行緒池中的執行緒進行一次連線的回收(重置)
)
Session = sessionmaker(bind=engine)
session = Session()
# 1 增加 Hobby
hobby = Hobby(caption='足球')
hobby1 = Hobby()
session.add_all([hobby, hobby1])
session.commit()
# 2 增加Person
p1 = Person(name='彭于晏', hobby_id=1)
p2 = Person(name='劉亦菲', hobby_id=2)
session.add_all([p1, p2])
session.commit()
# 3 簡便方式增加person---》增加Person,直接新增Hobby
hobby1 = Hobby(caption='乒乓球')
p1 = Person(name='彭于晏', hobby=hobby1) # 前提是必須有relationship
session.add(p1)
session.commit()
# 4 基於物件的跨表查詢---正向
per=session.query(Person).filter_by(name='彭于晏').first()
print(per)
# 正向
print(per.hobby.caption)
# 5 基於物件的跨表查詢---正向
hobby=session.query(Hobby).filter_by(caption='籃球').first()
print(hobby)
# 反向--->拿到多條
print(hobby.pers)
print(hobby.pers[0].name) # 列表套物件
多對多關係
models表建立
import datetime
from sqlalchemy import create_engine
from sqlalchemy.orm import declarative_base, relationship
from sqlalchemy import Column, Integer, String, Text, ForeignKey, DateTime, UniqueConstraint, Index
Base = declarative_base() # Base 當成 models.Model
### 單表
class User(Base):
__tablename__ = 'users' # 表名
# 寫欄位
id = Column(Integer, primary_key=True, autoincrement=True) # id 主鍵
name = Column(String(32), index=True, nullable=False) # name列,索引,不可為空
email = Column(String(32), unique=True)
# datetime.datetime.now不能加括號,加了括號,以後永遠是當前時間
ctime = Column(DateTime, default=datetime.datetime.now)
extra = Column(Text)
def __str__(self):
return self.name
def __repr__(self):
return self.name
# 一對多 :一個興趣被多個人喜歡 一個人只喜歡一個興趣
class Hobby(Base):
__tablename__ = 'hobby'
id = Column(Integer, primary_key=True)
caption = Column(String(50), default='籃球')
def __str__(self):
return self.caption
def __repr__(self):
return self.caption
class Person(Base):
__tablename__ = 'person'
id = Column(Integer, primary_key=True)
name = Column(String(32), index=True, nullable=True)
# hobby指的是tablename而不是類名,uselist=False
# 外來鍵關聯--》強外來鍵--》物理外來鍵
hobby_id = Column(Integer, ForeignKey("hobby.id"))
# 跟資料庫無關,不會新增欄位,只用於快速連表操作
# 類名,backref用於反向查詢
hobby = relationship('Hobby', backref='pers')
def __str__(self):
return self.name
def __repr__(self):
return self.name
# 多對多
class Boy2Girl(Base):
__tablename__ = 'boy2girl'
id = Column(Integer, primary_key=True, autoincrement=True)
girl_id = Column(Integer, ForeignKey('girl.id'))
boy_id = Column(Integer, ForeignKey('boy.id'))
# boy = relationship('Boy', backref='boy')
class Girl(Base):
__tablename__ = 'girl'
id = Column(Integer, primary_key=True)
name = Column(String(64), unique=True, nullable=False)
class Boy(Base):
__tablename__ = 'boy'
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String(64), unique=True, nullable=False)
# 與生成表結構無關,僅用於查詢方便,放在哪個單表中都可以--等同於manytomany
girls = relationship('Girl', secondary='boy2girl', backref='boys')
if __name__ == '__main__':
# 3.1 建立引擎
engine = create_engine(
"mysql+pymysql://root:1234@127.0.0.1:3306/sqlalchemy02",
max_overflow=0, # 超過連線池大小外最多建立的連線
pool_size=5, # 連線池大小
pool_timeout=30, # 池中沒有執行緒最多等待的時間,否則報錯
pool_recycle=-1 # 多久之後對執行緒池中的執行緒進行一次連線的回收(重置)
)
# 3.2 把表模型同步到資料庫中
Base.metadata.create_all(engine)
# 3.3 刪除表
# Base.metadata.drop_all(engine)
操作
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from models import Hobby, Person, User, Boy, Girl, Boy2Girl
engine = create_engine(
"mysql+pymysql://root:root@127.0.0.1:3306/sqlalchemy02",
max_overflow=0, # 超過連線池大小外最多建立的連線
pool_size=5, # 連線池大小
pool_timeout=30, # 池中沒有執行緒最多等待的時間,否則報錯
pool_recycle=-1 # 多久之後對執行緒池中的執行緒進行一次連線的回收(重置)
)
Session = sessionmaker(bind=engine)
session = Session()
# 1 增加 Boy
boy = Boy(name='王小剛')
boy2 = Boy(name='王小明')
boy3 = Boy(name='王小勇')
session.add_all([boy,boy2,boy3])
session.commit()
# 2 增加Girl
girl = Girl(name='張小華')
girl2 = Girl(name='劉小紅')
girl3 = Girl(name='李小麗')
session.add_all([girl3, girl2, girl])
session.commit()
# 3 增加Boy2Girl
obj1=Boy2Girl(boy_id=1,girl_id=1)
obj2=Boy2Girl(boy_id=1,girl_id=2)
obj3=Boy2Girl(boy_id=1,girl_id=3)
session.add_all([obj2, obj3, obj1])
session.commit()
# ------
# 3 簡便方式增加
obj2=Girl(name='張亦菲')
obj3=Girl(name='李娜扎')
obj1=Boy(name='張小勇',girls=[obj2,obj3])
session.add(obj1)
session.commit()
# 4 基於物件的跨表查詢---正向
boy=session.query(Boy).filter_by(name='張小勇').first()
print(boy.girls[0].name)
# 5 基於物件的跨表查詢---反向
girl=session.query(Girl).filter_by(name='張亦菲').first()
print(girl.boys)
基本增刪改查的使用
from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session
from models import User, Person, Hobby, Boy, Girl, Boy2Girl
from sqlalchemy.sql import text
engine = create_engine("mysql+pymysql://root:1234@127.0.0.1:3306/sqlalchemy02", max_overflow=0, pool_size=5)
Session = sessionmaker(bind=engine)
session = scoped_session(Session)
# 1 新增, add add_all
# 2 刪除
# 2.1 session.query(Users).filter_by(id=1).delete()
# 2.1 session.delete(物件)
user = session.query(User).filter_by(id=1).first()
session.delete(user)
session.commit()
# 3 修改
# 1 方式一:
session.query(Boy).filter_by(id=1).update({'name':'xxx'})
session.commit()
# 2 方式二 類名.屬性名,作為要修改的key
session.query(Boy).filter_by(id=4).update({Boy.name:'xxx1'})
session.commit()
# # id為4的人的名字後+ _nb 類似於django的 F 查詢
session.query(User).filter_by(id=2).update({'name':User.name+'_nb'},synchronize_session=False) # 字串拼接
# session.query(User).filter_by(id=2).update({'id':User.id+6}, synchronize_session="evaluate") # 數字之間加
# session.commit()
# # 3 方式三:
# 物件.name='xxx'
#session.add(物件)
# boy=session.query(Boy).filter_by(id=1).first()
# boy.name='xxzzyy'
# session.add(boy) # 有id就是修改,沒有就是新增
# session.commit()
### 4 查詢---》基本查詢
# 4.1 filter_by 寫條件
# res=session.query(User).filter_by(name='lqz_nb',id=8).first()
# res=session.query(User).filter_by(name='lqz').all() # 放在列表中 不是queryset物件
# 4.2 filter 寫表示式
# res=session.query(User).filter(User.name=='lqz_nb').first()
# res=session.query(User).filter(User.id>=3).all()
# res=session.query(User).filter(User.name!='lqz').all()
# 4.3 只查表中某幾個欄位,並重新命名
# select name as xx,age from user;
# res=session.query(User.name.label('xx'), User.email)
# select name,email from user;
# res=session.query(User.name, User.email).all()
# res=session.query(User)
# 4.4 條件可以使用text自己拼湊
# select * from user where id< 224 and name=lqz order by id
# res = session.query(User).filter(text("id<:value and name=:name")).params(value=224, name='lqz_nb').order_by(User.id).all()
# print(res)
## 4.5 直接原生sql
# SELECT * FROM users where name=lqz
# res = session.query(User).from_statement(text("SELECT * FROM users where name=:name")).params(name='lqz_nb').all()
res = session.query(User).from_statement(text("SELECT * FROM users where name=:name")).params(name='張三')
print(res)