python sqlalchemy 库 教程

Published by rcdfrd on 2022-03-30
# 连接数据库 
from sqlalchemy import create_engine
engine = create_engine('sqlite:///test.db?check_same_thread=False', echo=True)
# echo参数是设置SQLAlchemy日志显示的快捷方式 如果我们不想看见执行的详细过程,可以将echo设置为False
# create_engine()函数返回一个Engin的实例,代表着访问数据库的接口。
# 延迟连接 当create_engine()第一次调用,它没有尝试去连接数据库,仅仅是当我们执行数据库操作时,才会去连接数据库。


# 定义映射
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
# 当我们在使用ORM的时候,数据库中的一张表对应着我们的一个类,我们使用declarative_base()创建一个基类。

#现在我们有了一个基类Base,我们可以定义很多映射的类,先从一张完整的表格,名字为Users开始,一个新的User类将会映射到我们的那种表格上,在类中我们定义关于表格的详细信息。主要是表名、列名和数据类型。
class User(Base):
    __tablename__ = 'users'
    # id = Column(Integer, primary_key=True)
    id = Column(Integer, Sequence('user_id_seq'), primary_key=True)
    name = Column(String)
    fullname = Column(String)
    nickname = Column(String)

    def __repr__(self):
        return "<User(name='%s', fullname='%s', nickname='%s')>" % (
            self.name, self.fullname, self.nickname)
# 一个最简单的类需要一个__tablename__属性,和至少一行Column和一个外键primary key。
# User类定义了一个__repr__()方法,但是这个是可选的,我们在这里定义是为了打印出类的对象的内容。

# 创建一个模型 通过声明系统,我们已经定义了我们表格的详细信息,我们可以通过__table__属性来看我们定义的类
print(User.__table__)

# 创建表
# 当我们定义了我们的类,声明系统使用一个Python的metaclass来执行其他任务,一旦这个类声明完成。
# 表的对象是一个更大的称为元数据集合的一个成员。当我们使用这个系统,可以使用这个对象.metadata属性声明我们基类的属性。
# MetaData是一个注册表,当我们的数据库不存在一个users表格,我们可以使用MetaData去创建一个不存在的表格,我们调用MetaData.create_all()方法,Engine作为一个数据库的连接。
Base.metadata.create_all(engine)

# 在上面的声明一个表中的列时,我们注意到列的数据类型为字符串,但是没有指定长度;在SQLite和PostgreSQL中这样的声明是合法的,但是在其他的数据库中是不允许的。所以,如果运行这个教程在洽谈的数据库中,可能会报错。最好我很使用下面的声明方式。
Column(String(50))
# 另外在Firebird和Oracle数据库中要求sequences去生成一个新的外键约束。你可以使用序列来构造。
from sqlalchemy import Sequence
Column(Integer, Sequence('user_id_seq'), primary_key=True)

# 完整的Table的定义为:
class User1(Base):
    __tablename__ = 'users'
    id = Column(Integer, Sequence('user_id_seq'), primary_key=True)
    name = Column(String(50))
    fullname = Column(String(50))
    password = Column(String(12))

    def __repr__(self):
        return "<User(name='%s', fullname='%s', password='%s')>" % (
                                self.name, self.fullname, self.password)

# 创建一个映射的类的对象
# 我们来创建一个User的对象.
ed_user = User(name='ricky', fullname='yuziyong', password='123')
print(ed_user.name)
print(ed_user.fullname)

# 创建数据库会话
Session = sessionmaker(bind=engine)
session = Session()

# 把用户添加入数据库
session.add(ed_user)
# 提交更新
session.commit()

# 添加多用户
session.add_all([
    User(name='wendy', fullname='Wendy Williams', nickname='windy'),
    User(name='mary', fullname='Mary Contrary', nickname='mary'),
    User(name='fred', fullname='Fred Flintstone', nickname='freddy')])

# 回滚  (将数据库内容回到上一次commit的状态)
session.rollback()  

# 查询
for instance in session.query(User).order_by(User.id):
    print(instance.name, instance.fullname)

for name, fullname in session.query(User.name, User.fullname):
    print(name, fullname)

for row in session.query(User, User.name).all():
   print(row.User, row.name)
for u in session.query(User).order_by(User.id)[1:3]:
   print(u)

for name, in session.query(User.name).\
            filter_by(fullname='Ed Jones'):
   print(name)

for user in session.query(User).\
         filter(User.name=='ed').\
         filter(User.fullname=='Ed Jones'):
   print(user)

# 查询是否存在用户
session.query(exists().where(Username.name == 'zhangsan')).scalar() # -> bool

# 更改一个用户信息
user = session.execute(select(User).filter_by(name='zhangsan')).scalar_one()
user.name = 'zhangsan'
session.commit()

# 关闭会话
session.close()
Session.close()