1.使用ORM创建表
from typing import List
from typing import Optional
from sqlalchemy import ForeignKey,String
from sqlalchemy import create_engine
from sqlalchemy.orm import DeclarativeBase
from sqlalchemy.orm import Mapped
from sqlalchemy.orm import mapped_column
from sqlalchemy.orm import relationship
from sqlalchemy.orm import Session
#建立数据引擎
engine = create_engine("mysql+pymysql://remote:qwer0487@192.168.198.186:3306/test", echo=False)
class Base(DeclarativeBase):
pass
#声明表模型
class User(Base):
__tablename__ = "user_account"#表名
id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str] = mapped_column(String(30))
fullname: Mapped[Optional[str]] = mapped_column(String(50))
addresses: Mapped[List["Address"]] = relationship(#relationship()函数用于定义模型之间的关系,第一个参数为模型名,第二个参数为关系类型,back_populates参数用于指定反向引用的属性名。
back_populates="user", cascade="all, delete-orphan"
)
def __repr__(self) -> str:#repr() 函数将对象转化为供解释器读取的形式。
return f"User(id={self.id!r}, name={self.name!r}, fullname={self.fullname!r})"
class Address(Base):
__tablename__ = "address"
id: Mapped[int] = mapped_column(primary_key=True)
email_address: Mapped[str] = mapped_column(String(50), nullable=False)
user_id: Mapped[int] = mapped_column(ForeignKey("user_account.id"))
user: Mapped["User"] = relationship(back_populates="addresses")
def __repr__(self) -> str:
return f"Address(id={self.id!r}, email_address={self.email_address!r})"
# Base.metadata.create_all(engine)
#插入操作
"""
with Session(engine) as session: 创建了一个 SQLAlchemy 的 Session 对象,并将其赋值给 session。
Session 对象实现了上下文管理协议,所以你可以在 with 语句的代码块中使用 session 来执行数据库操作,而不需要手动关闭 session,
因为当离开 with 语句的代码块时,Session 对象的 __exit__ 方法会被自动调用,关闭数据库会话。
总的来说,使用 with as 语句的目的是为了简化资源管理,确保资源在使用完毕后能被正确关闭和清理,避免资源泄露
"""
with Session(engine) as session:#Session()函数用于创建一个会话,会话用于执行SQL语句并管理事务,参数为数据库引擎。
spongebob = User(
name="spongebob",
fullname="Spongebob Squarepants",
addresses=[
Address(email_address="spongebob@sqlalchemy.org"),
]
)
sandy = User(
name="sandy",
fullname="Sandy Cheeks",
addresses=[
Address(email_address="sandy@sqlalchmey.org"),
Address(email_address="sandy@squirrelpower.org"),
],
)
partick = User(name="patrick", fullname="Patrick Star")
#session.add_all([spongebob, sandy, partick])#add_all()函数用于将多个对象添加到会话中。
#session.commit()#commit()函数用于提交事务,将会话中的所有操作作为一个事务提交到数据库中。
#简单查询操作
from sqlalchemy import select
with Session(engine) as session:
stmt = select(User).where(User.name.in_(["spongebob", "sandy"]))#in_()函数用于判断某个字段的值是否在列表中。
for user in session.scalars(stmt):#scalars()函数用于执行查询并返回结果集中。
print(user)
#结果:
"""
User(id=1, name='spongebob', fullname='Spongebob Squarepants')
User(id=2, name='sandy', fullname='Sandy Cheeks')
"""
session = Session(engine)
#多表查询操作
stmt = (
select(Address)
.join(Address.user)
.where(User.name == "sandy")
.where(Address.email_address == "sandy_cheeks@sqlalchemy.org")
)
sandy_address = session.scalars(stmt).one()#one()函数用于返回结果集中的第一条记录。
#Address(id=2, email_address='sandy@sqlalchmey.org')
#更新操作
stmt = select(User).where(User.name == "patrick")
patrick = session.scalars(stmt).one()
#patrick=User(id=3, name='patrick', fullname='Patrick Star')
patrick.addresses.append(Address(email_address="patrickstar@sqlalchemy.org"))#添加新的邮箱地址
sandy_address.email_address = "sandy_cheeks@sqlalchemy.org"#修改邮箱地址
# session.commit()#提交事务
#删除操作
sandy = session.get(User,2)#get()函数用于根据主键获取记录。
sandy.addresses.remove(sandy_address)#删除一个邮箱地址
session.flush()#flush()在不提交事务的情况下,为更改的内容发出DELETE语句。
# 级联删除
session.delete(patrick)#删除用户,级联删除用户的邮箱地址
session.commit()#提交事务
2.使用orm的session
from sqlalchemy import create_engine
from sqlalchemy import text
from sqlalchemy.orm import Session
#与Mysql建立连接,用户名为remote,密码为123456,端口号为3306,数据库名称为vote echo=True表示打印日志
engine = create_engine('mysql+pymysql://remote:qwer0487@192.168.198.186:3306/vote',echo=True)
session = Session(engine)
#使用text()方法执行原生sql语句
result = session.execute(text('select *from vote_announce'))
# print(result.all())
#使用映射关系获得数据from sqlalchemy import create_engine
from sqlalchemy import MetaData, ForeignKey
from sqlalchemy import Table, Column, Integer, String, ForeignKey
# #与Mysql建立连接,用户名为remote,密码为123456,端口号为3306,数据库名称为vote echo=True表示打印日志
engine = create_engine('mysql+pymysql://remote:qwer0487@192.168.198.186:3306/test',echo=True)
metadata_obj=MetaData()
user_table = Table(
"user_account",#表名
metadata_obj,#assigns itself to a MetaData collection
#列对象
Column("id", Integer, primary_key=True),
Column("name", String(30)),
Column("fullname", String(50)),
)
#简单的属性与方法
print(user_table.columns.id)#获取列对象
print(user_table.columns.keys())#获取所有列名
print(user_table.primary_key)#获取主键
#声明约束关系
adress_table = Table(
"address",#表名
metadata_obj,
Column("id", Integer, primary_key=True),
Column("user_id",ForeignKey("user_account.id"),nullable=False),#外键
Column("email_address", String(50), nullable=False),
)
#使用MetaData对象创建表
#Migration tools are usually appropriate,a schema management tool such as Alembic,最好使用迁移工具
metadata_obj.create_all(engine)
for row_dict in result.mappings():
print(row_dict)
3.Table对象建立数据库元数据
from sqlalchemy import create_engine
from sqlalchemy import MetaData, ForeignKey,insert
from sqlalchemy import Table, Column, Integer, String, ForeignKey
# #与Mysql建立连接,用户名为remote,密码为123456,端口号为3306,数据库名称为vote echo=True表示打印日志
engine = create_engine('mysql+pymysql://remote:qwer0487@192.168.198.186:3306/test',echo=True)
metadata_obj=MetaData()#创建一个MetaData对象
user_table = Table(
"user_account",#表名
metadata_obj,#assigns itself to a MetaData collection
#列对象
Column("id", Integer, primary_key=True),
Column("name", String(30)),
Column("fullname", String(50)),
)
#简单的属性与方法
print(user_table.columns.id)#获取列对象
# user_account.id
print(user_table.columns.keys())#获取所有列名
# ['id', 'name', 'fullname']
print(user_table.primary_key)#获取主键
# PrimaryKeyConstraint(Column('id', Integer(), table=<user_account>, primary_key=True, nullable=False))
#声明约束关系
adress_table = Table(
"address",#表名
metadata_obj,
Column("id", Integer, primary_key=True),
Column("user_id",ForeignKey("user_account.id"),nullable=False),#外键
Column("email_address", String(50), nullable=False),
)
metadata_obj.create_all(engine)#发送数据库命令,创建表
# CREATE TABLE user_account (
# id INTEGER NOT NULL AUTO_INCREMENT,
# name VARCHAR(30),
# fullname VARCHAR(50),
# PRIMARY KEY (id)
# )
# 2024-01-04 14:20:10,877 INFO sqlalchemy.engine.Engine [no key 0.00059s] {}
# 2024-01-04 14:20:10,889 INFO sqlalchemy.engine.Engine
# CREATE TABLE address (
# id INTEGER NOT NULL AUTO_INCREMENT,
# user_id INTEGER NOT NULL,
# email_address VARCHAR(50) NOT NULL,
# PRIMARY KEY (id),
# FOREIGN KEY(user_id) REFERENCES user_account (id)
# )
# 2024-01-04 14:20:10,890 INFO sqlalchemy.engine.Engine [no key 0.00092s] {}
# 2024-01-04 14:20:10,906 INFO sqlalchemy.engine.Engine COMMIT
# 1.建立数据库引擎,使用引擎自带的connect
```python
from sqlalchemy import create_engine
from sqlalchemy import text
#与Mysql建立连接,用户名为remote,密码为123456,端口号为3306,数据库名称为vote echo=True表示打印日志
engine = create_engine('mysql+pymysql://remote:qwer0487@192.168.198.186:3306/vote',echo=True)
conn = engine.connect()
#使用text()方法执行原生sql语句
result = conn.execute(text('select *from vote_announce'))
# print(result.all())
#使用映射关系获得数据
for row_dict in result.mappings():
print(row_dict)
4.sqlalchemy建立数据库引擎
from sqlalchemy import create_engine
from sqlalchemy import text
#与Mysql建立连接,用户名为remote,密码为123456,端口号为3306,数据库名称为vote echo=True表示打印日志
engine = create_engine('mysql+pymysql://remote:qwer0487@192.168.198.186:3306/vote',echo=True)
conn = engine.connect()
#使用text()方法执行原生sql语句
result = conn.execute(text('select *from vote_announce'))
# print(result.all())
#使用映射关系获得数据
for row_dict in result.mappings():
print(row_dict)
5.Alembic数据库迁移的步骤
基础步骤
- 安装 Alembic:
pip install alembic
- 创建数据库模型: 在你的 Python 项目中创建一个文件,用于定义数据库模型。这通常是使用 SQLAlchemy 来定义的。
from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
username = Column(String, nullable=False)
email = Column(String, nullable=False)
- 配置 Alembic: 使用 Alembic 初始化配置。
alembic init alembic
这将在项目根目录下创建一个名为 alembic 的目录,包含配置文件和其他必要的文件。
- 编辑 Alembic 配置文件:
编辑 alembic.ini 文件,配置数据库连接字符串。
sqlalchemy.url = driver://user:password@localhost/dbname
- 编辑 alembic/env.py 文件,将数据库模型导入并与 Base 绑定。
from your_project.models import Base
target_metadata = Base.metadata
- 创建迁移脚本: 这将自动生成一个迁移脚本,描述了数据库模型的创建过程。
alembic revision --autogenerate -m "create tables"
- 升级数据库:
alembic upgrade head
注意
易错点注释