1. 使用docker中的mysql
自己使用vs code + docker的本地開(kāi)發(fā)環(huán)境,除了費(fèi)電,其它一切良好,不用考慮過(guò)多本機(jī)環(huán)境切換的問(wèn)題。
連接docker中的mysql,host需要設(shè)置為該docker的ip,可進(jìn)入容器后使用cat /etc/hosts進(jìn)行查看。若是設(shè)置了hostname,也可以使用hostname進(jìn)行連接
2. 密碼中有特殊字符的連接方式
可用python的format方式進(jìn)行填充,示例:
# 初始化數(shù)據(jù)庫(kù)連接:
engine = create_engine(
f'mysql+pymysql://{name}:{password}@{host}:{port}/{db_name}')
3. 外鍵的使用
mysql中的外鍵描述
mysql中的外鍵,是為了保證數(shù)據(jù)的一致性。
主鍵:如user表中,一般使用id作為主鍵,不可重復(fù)
外鍵:如user_info表中,用戶的詳細(xì)信息。
只有user表中新增了用戶 z的信息,user_info表中才可以新增用戶z的詳細(xì)信息
可約束為只有user_info表中沒(méi)有用戶 z的信息了,才可以刪除user表中的用戶z
這樣保證了數(shù)據(jù)的一致性
sqlalchemy中使用外鍵
sqlalchemy中可以設(shè)置外鍵,需要用ForeignKey字段標(biāo)識(shí)。同時(shí)可設(shè)置關(guān)聯(lián)查詢及反向關(guān)聯(lián)查詢,類似于mysql中的join字段
示例說(shuō)明:
給用戶設(shè)定角色,角色對(duì)應(yīng)相應(yīng)的權(quán)限
角色分為 admin,leader,user
admin可以查看所有頁(yè)面,即有 admin,leader,user的權(quán)限
leader可以查看自己及組員的頁(yè)面,即leader,user的權(quán)限
user只能查看自己的頁(yè)面,即user的權(quán)限
關(guān)系圖如下:

示例:
權(quán)限對(duì)應(yīng)表authority的sql(sqlalchemy自動(dòng)生成的)
CREATE TABLE `authority` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`authority` varchar(20) DEFAULT NULL COMMENT '權(quán)限名稱',
`role` int(11) DEFAULT NULL COMMENT '角色id',
`create_time` datetime DEFAULT NULL COMMENT '創(chuàng)建時(shí)間',
PRIMARY KEY (`id`),
KEY `ix_authority_role` (`role`),
KEY `ix_authority_authority` (`authority`),
CONSTRAINT `authority_ibfk_1` FOREIGN KEY (`role`) REFERENCES `role` (`id`) ON DELETE SET NULL ) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8mb3
對(duì)應(yīng)的類
from sqlalchemy import String, Column, Integer, create_engine, DateTime, Boolean, ForeignKey
from sqlalchemy.orm import sessionmaker, relationship
from sqlalchemy.ext.declarative import declarative_base
from datetime import datetime
Base = declarative_base()
class UserAuthority(Base):
__tablename__ = 'authority'
id = Column(Integer, primary_key=True, autoincrement=True)
authority = Column(String(20), index=True, comment="權(quán)限名稱")
role = Column(Integer, ForeignKey(
"role.id", ondelete="SET NULL"), index=True, comment="角色id")
create_time = Column(DateTime, default=datetime.now(), comment="創(chuàng)建時(shí)間")
# 反向查詢外鍵,可在 UserRole 實(shí)例對(duì)象中調(diào)用 UserAuthority 的屬性,如 UserRole.UserAuthority
user = relationship('UserRole', backref="UserAuthority")
def __repr__(self):
return "<user (id='%s', role='%s')>" % (self.id, self.role)
角色role表的sql(sqlalchemy自動(dòng)生成的)
CREATE TABLE `role` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`role` varchar(20) DEFAULT NULL COMMENT '角色名',
`create_time` datetime DEFAULT NULL COMMENT '創(chuàng)建時(shí)間',
PRIMARY KEY (`id`),
UNIQUE KEY `ix_role_role` (`role`) )
ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb3
對(duì)應(yīng)的類
class UserRole(Base):
__tablename__ = 'role'
id = Column(Integer, primary_key=True, autoincrement=True)
role = Column(String(20), index=True, unique=True, comment="角色名")
create_time = Column(DateTime, default=datetime.now(), comment="創(chuàng)建時(shí)間")
# 反向查詢外鍵,可在 User 實(shí)例對(duì)象中調(diào)用 UserRole 的屬性,如 User.UserRole
user = relationship('User', backref="UserRole")
def __repr__(self):
return "<user (id='%s', role='%s')>" % (self.id, self.role)
用戶user表的sql(sqlalchemy自動(dòng)生成的)
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) DEFAULT NULL COMMENT '用戶名',
`password` varchar(128) DEFAULT NULL COMMENT '密碼',
`role` int(11) DEFAULT NULL COMMENT '角色id',
`is_delete` tinyint(1) DEFAULT NULL COMMENT '刪除標(biāo)記,為T(mén)rue時(shí)表示可用',
`create_time` datetime DEFAULT NULL COMMENT '創(chuàng)建時(shí)間',
`last_login` datetime NOT NULL COMMENT '最后登陸時(shí)間',
`update_time` datetime NOT NULL COMMENT '更新時(shí)間',
PRIMARY KEY (`id`),
UNIQUE KEY `ix_user_name` (`name`),
KEY `ix_user_is_delete` (`is_delete`),
KEY `ix_user_role` (`role`) )
ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb3
對(duì)應(yīng)的類
class User(Base):
# 表名
__tablename__ = 'user'
# 表結(jié)構(gòu)
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String(20), index=True, unique=True, comment="用戶名")
password = Column(String(128), comment="密碼")
role = Column(Integer, ForeignKey(
"role.id", ondelete="SET NULL"), index=True, comment="角色id")
is_delete = Column(Boolean, default=True, index=True,
comment="刪除標(biāo)記, 為T(mén)rue時(shí)表示可用")
create_time = Column(DateTime, default=datetime.now(), comment="創(chuàng)建時(shí)間")
last_login = Column(DateTime, default=datetime.now(),
nullable=False, comment="最后登陸時(shí)間")
update_time = Column(DateTime, default=datetime.now(),
nullable=False, comment="更新時(shí)間")
def __repr__(self):
return "<user (id='%s', name='%s')>" % (self.id, self.name)
在用戶中查詢對(duì)應(yīng)的角色:
e1 = session.query(User).filter_by(id=3).first()
# 在 User 實(shí)例對(duì)象中調(diào)用 UserRole 的屬性
print(e1.name, e1.UserRole.role)
在用戶中查詢對(duì)應(yīng)的權(quán)限
e1 = session.query(User).filter_by(id=7).first()
# 在用戶的實(shí)例對(duì)象中查詢對(duì)應(yīng)的權(quán)限。因?yàn)橐粋€(gè)用戶可能有多個(gè)權(quán)限,因此返回一個(gè)list
print([x.authority for x in e1.UserRole.UserAuthority])