文章目录
创建步骤
1. 创建元数据
元数据的概念
sqlalchemy中一个重要的元素是SQL Expression Language(用来生成sql语句的)。而它的实现就是用一些Python对象来表示数据库中的表和列等概念。这些Python对象就称为元数据。
最常用的sqlalchemy中的元数据是MetaData,Table和Colum类。
元数据的创建方法
在sqlalchemy中创建元数据用来存储应用中所有数据表。通常一个应用中只有一个元数据。
方式1:直接方式
利用SQL alchemy包中的MetaData类生成。
from sqlalchemy import MetaData
metadata_obj = MetaData()
方式2:ORM方式
利用SQL alchemy下orm子包中的registry类下的metadata()函数生成。
from sqlalchemy.orm import registry
mapper_registry = registry()
metadata_obj = mapper_registry.metadata()
2. 声明表数据
当我们创建项目与数据库交互的过程中,通常会出现如下两种情况:1.数据库中还没有相应的数据表,需要我们创建数据表。2.数据库中已经有相应的数据表,需要我们创建与之对应的数据模型类。
针对第一种方式我们通常称为声明式方式,第二种方式我们通常称为反射式方式。这一个章节主要讲述声明式方式。
在SQL alchemy中通常存在三种方式进行声明式创建数据表,分别是通过Table类,通过ORM类,通过混合方式。
方式1:Table方式
Table方式就是利用SQL alchemy中的Table类来创建数据表模型。
from sqlalchemy import Table,Column,String,Integer,ForeignKey
user_table = Table(
#定义表的名称
"user",
#定义存放在哪个元数据中
metadata_obj,
#定义各字段
Column("id",Integer,primary_key=True,autoincrement=True),
Column("name",String(30),nullable=False),
Column("fullname",String(50))
)
address_table = Table(
"address",
metadata_obj,
Column("id",Integer,primary_key=True,autoincrement=True),
Column("user_id",ForeignKey("user.id"),nullable=False),
Column("email_address",String(50))
)
方式2:ORM方式
ORM方式就是利用定义类的方式创建数据表。
创建基类
由于要创建一个数据表的模型类,故要首先基于一个固定的父类,来创建相应的类,这样才能被python认为是一个数据表模型类。
方法1
利用registry实例对象的generate_base函数创建。
from sqlalchemy.orm import registry
mapper_registry = registry()
Base = mapper_registry.generate_base()
方法2
利用SQL alchemy的orm子包中的declarative_base函数创建。
from sqlalchemy.orm import declarative_base
Base = declarative_base()
自定义类
要创建自定义的数据表模型类,需要继承基类。
from sqlalchemy.orm import relationship
class User(Base):
#定义表名称
__tablename__ = "user"
#定义各列id等为列名
id = Column(Integer,primary_key=True,autoincrement=True)
name = Column(String(30))
fullname = Column(String(50))
# 定义外键关系,Address表示类,user表示Address类中relationship的名字
address = relationship("Address",back_populates="user")
# 定义类的字符串表现形式,!r表示利用对象的__repr__方法返回
def __repr__(self):
return f"User(id={self.id!r},name={self.name!r},fullname={self.fullname!r})"
class Address(Base):
__tablename__ = "address"
id = Column(Integer,primary_key = True)
email_address = Column(String,nullable = False)
user_id = Column(Integer,ForeignKey("user_account.id"))
# 定义外键关系,User表示类,address表示User类中relationship的名字
user = relationship("User",back_populates="address")
def __repr__(self) -> str:
return f"Address(id={self.id!r},email_address={self.email_address!r})"
方式3:混合方式
通过观察上面两种方式发现,ORM方式中定义各列的部分和Table方式基本一致。故这里可以用这两种方式的混合方式来创建数据表模型类。
from sqlalchemy import Table,Column,String,Integer,ForeignKey
from sqlalchemy.orm import relationship,registry
mapper_registry = registry()
metadata_obj = mapper_registry.metadata()
user_table = Table(
#定义表的名称
"user",
#定义存放在哪个元数据中
metadata_obj,
#定义各字段
Column("id",Integer,primary_key=True,autoincrement=True),
Column("name",String(30),nullable=False),
Column("fullname",String(50))
)
address_table = Table(
"address",
metadata_obj,
Column("id",Integer,primary_key=True,autoincrement=True),
Column("user_id",ForeignKey("user.id"),nullable=False),
Column("email_address",String(50))
)
Base = mapper_registry.generate_base()
class User(Base):
__table__ = user_table
address = relationship("Address",back_populates="user")
def __repr__(self):
return f"User(id={self.id!r},name={self.name!r},fullname={self.fullname!r})"
class Address(Base):
__table__ = address_table
user = relationship("User",back_populates="address")
def __repr__(self) -> str:
return f"Address(id={self.id!r},email_address={self.email_address!r})"
3. 反射数据表
反射数据表就是根据数据库中已经存在的数据表,自动生成其对应的数据表模型类。
from sqlalchemy import MetaData,create_engine
metadata_obj = MetaData()
url="mysql+pymysql://root:123456@127.0.0.1:3306/testdb"
engine = create_engine(url)
some_table = Table("some_table", metadata_obj, autoload_with=engine)
4.与数据库交互
创建表
利用metadata实例对象的create_all方法来在指定的数据库中创建其包含的所有的数据表。
metadata_obj.create_all(engine)
删除表
利用metadata实例对象的drop_all方法来在指定的数据库中删除其包含的所有的数据库表。
metadata_obj.drop_all(engine)
示例代码
声明式创建数据库表
from importlib.metadata import metadata
from sqlalchemy import Table,Column,Integer,String,ForeignKey,create_engine
from sqlalchemy.orm import declarative_base,relationship
dburl = 'mysql+pymysql://root:123456@127.0.0.1:3306/testdb'
engine = create_engine(dburl)
Base = declarative_base()
metadata_obj = Base.metadata
user_table = Table(
"user",
metadata_obj,
Column("id",Integer,primary_key=True,autoincrement=True),
Column("name",String(30))
)
address_table = Table(
"address",
metadata_obj,
Column("id",Integer,primary_key=True,autoincrement=True),
Column("email_address",String(200)),
Column("user_id",ForeignKey("user.id"),nullable=False)
)
class User(Base):
__table__ = user_table
address = relationship("Address",back_populates="user")
def __repr__(self):
return f'User(name={self.name!r})'
class Address(Base):
__table__ = address_table
user = relationship("User",back_populates="address")
def __repr__(self):
return f'Address(email_address={self.email_address!r},user={self.user!r})'
def create_table(metadata,engine):
metadata.create_all(engine)
if __name__ == "__main__":
create_table(metadata_obj,engine)
反射式创建数据表模型
from sqlalchemy import create_engine,Table
from sqlalchemy.orm import declarative_base,Session
urldb = 'mysql+pymysql://root:123456@127.0.0.1:3306/testdb'
engine = create_engine(urldb)
Base = declarative_base()
metadata_obj = Base.metadata
# 利用Table中的autoload自动生成对应的表
stu_table = Table("student",metadata_obj,autoload_with=engine)
class Student(Base):
__table__ = stu_table
def __repr__(self) -> str:
return f"Student(name={self.name!r},age={self.age!r})"
# 向数据库中插入数据
def insert_stu(name:str,age:int):
with Session(engine) as session:
stu = Student(name=name,age=age)
session.add(stu)
session.commit()
if __name__ == "__main__":
insert_stu("Jack",12)