Python数据库ORM框架SQLALchemy操作数据库简单封装表关系(一对一、一对多、多对多)增删改查crud工具

SQLALchemy

SQLALchemy是python下操作数据库的工具包,是一个数据库ORM(对象关系映射)框架,使用SQLALchemy可以极大的简化对数据库和数据的操作,使用ORM管理数据更直观方便.这里我记录一次关于sqlalchemy使用的简单实践,包括了创建数据库连接、定义模型、表关系(一对一、一对多、多对多)增删改查、crud工具,最后使用了pytest进行了一些测试.

创建项目

项目文件

首相创建一个项目目录,包括一下文件:
database.py 数据库创建和连接的配置文件
models.py 模型 定义表和关系
crud.py crud的操作封装工具
test_db.py 项目的测试文件
在这里插入图片描述

安装SQLALchemy

终端输入:

pip install sqlalchemy

进入python的交互模式下检测版本:

>>> import sqlalchemy
>>> sqlalchemy.__version__  
1.4.0

创建数据库和数据库的连接

database.py 的代码如下:

import os,sys
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR)

# 组装数据库的绝对地址
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
DB_DIR = os.path.join(BASE_DIR, 'data.db')
# 数据库访问地址
SQLALCHEMY_DATABASE_URL = "sqlite:///" + DB_DIR
# print(SQLALCHEMY_DATABASE_URL)

# 创建SQLite数据库
# engine = create_engine(SQLALCHEMY_DATABASE_URL, echo=False)
# 创建一个使用内存的SQLite数据库
engine = create_engine("sqlite+pysqlite:///:memory:", echo=False, future=True)

# 数据模型的基类
Base = declarative_base()

# 启动会话
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

# 获取一个数据连接 异步 fastapi下使用.
# def get_db():
#     db = SessionLocal()
#     try:
#         yield db
#     finally:
#         db.close()

# 获取一个数据连接 
def get_db():
    db = SessionLocal()
    try:
        return db
    finally:
        db.close()

if __name__ == '__main__':
    db = get_db()
    print(dir(db))

最后可以运行这个文件,打印获得的数据库连接的属性,如果看到了一堆属性就是成功连接,看代码中的注释应该就能了解个大概了,这里就不一一介绍了.

定义模型

models.py 的部分代码如下,以为代码太长了,文末留有代码仓库地址.

from database import Base
from sqlalchemy import String, Column, Integer, DateTime, Enum, Table, ForeignKey
from sqlalchemy.orm import relationship

class User(Base):
    __tablename__ = 'user'
    id = Column(Integer, primary_key=True)
    username = Column(String(100), nullable=False, index=True)
    # user 一对一 UserData
    userdata = relationship('UserData',uselist=False,back_populates='user')
    # user 一对多 Article
    articles = relationship('Article',uselist=True,back_populates='user')

首先头部引入相关的依赖,比如database中Base,这个是定义model的基类,引入表的字段类型,还有relationship是用来定义表关系的方法.

关系使用 relationship() 函数表示。然而外键必须用类ForeignKey来单独声明. 这里的一对一关系使用User(用户基本资料)和UserData(用户的拓展资料),如果需要给用户的基本资料添加一写拓展资料,这种关系必须是一对一的关系。这里我们假设需要为用户添加一个邮件的拓展资料,分别定义用户User和UserData模型,并使用关系方法定义他们之间的一对一关系.

uselist=False 标志指示在关系的“多”端放置标量属性而不是集合。将一对多转换为一对一, back_populates() 显示表明双方的对应关系,这种方法比较简单。

一对多和一对一关系基本相似,去掉 uselist=False 就可以了,这里user和article为一堆多关系.

多对多关系,您需要定义一个用于关系的辅助表。对于这个辅助表, 强烈建议不使用模型,而是采用一个实际的表(但是我就建立了一个模型,具体参看代码,感觉也没什么影响?有大佬知道这其中的奥秘么?)。这里使用了 Article 和 Tag 之间的多对多关系,一个文章可以有多个标签,一个标签下也可以有多个文章。关系辅助表article_tag一定要在模型表之前定义,不然创建表的时候容易报错。

crud的封装

把一些常用的crud封装起来,使用的时候更方便,这里我只是封装了几个测试的,大家可以根据自己的需求进行封装.

from sqlalchemy.orm import Session
from models import *

def get_user(db:Session,username:str): 
    return db.query(User).filter(User.username==username).first()

def get_users(db:Session,skip:int = 0,limit:int=100):
    return db.query(User).all()

def get_articles(db:Session,skip:int = 0,limit:int=10):
    return db.query(Article).offset(skip).limit(limit).all()

测试

最后使用pytest测试了一下整个项目的crud和crud的封装的方法,直接运行测试文件,即可看到测试的结果,具体代码就不贴啦,最后放一张数据库表的er图,大家可以结合图中的关系理解一下.

在这里插入图片描述

本文代码仓库:
https://github.com/bosichong/sqlalchemy-test

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

这里不提提纳里

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值