sqlalchemy学习

SQLAlchemy实战教程
autoincrement

当主键是int类型是,这个属性默认是true,需要显示设置autoincrement=False关闭

flush 和 commit

session就是transaction,flush的作用是将sql发送到bd服务器,commit的作用是提交事务。flush之后在当前session中能看到效果,commit之后在其他的session中也能看到效果

merge

接受一个model对象,作用类似与MySQL的replace into, 就是有则更新无则插入。add接受相同的参数,直接插入。

update

接受一个字典,键是User.name这样的属性返回的字符串

session.update({User.id:123,User.name:'CooMark'})
execute

执行sql,返回的结果是个sqlalchemy.engine.ResultProxy对象
http://docs.sqlalchemy.org/en/rel_1_0/core/connections.html?highlight=sqlalchemy%20engine%20result%20resultproxy#sqlalchemy.engine.ResultProxy

pc = session.execute('select 123 as age')

row = fetchone()

col1 = row[0]    # access via integer position, 索引检索

col2 = row['age']   # access via name, 用名字检索列

col3 = row[mytable.c.mycol] # access via Column object.
原文: 作为一个Pythoner,不会SQLAlchemy都不好意思跟同行打招呼!
#作者:笑虎
#链接:https://zhuanlan.zhihu.com/p/23190728
#来源:知乎
#著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

# _*_ coding: utf-8 _*_

import sqlalchemy
import sqlalchemy.orm
import sqlalchemy.ext.declarative

# 利用数据库字符串构造engine, echo为True将打印所有的sql语句, 其他数据库的链接方式可自行百度
# engine = sqlalchemy.create_engine("mysql+pymysql://username:password@hostname/dbname", encoding="utf8", echo=True)
engine = sqlalchemy.create_engine("mysql+pymysql://dba_0:mimadba_0@101.200.174.172/data_secret", encoding="utf8", echo=False)

"""
# 利用engine创建connection,因为使用了with所以不需要close操作,这部分不是重点
with engine.connect() as conn:
    # 最基础的用法
    result = conn.execute("select * from tablename limit 10;")
    for item in result:
        print(item)

    # execute的几种用法,这里具体还是得参考pymysql的用法,不需要执行commit操作
    conn.execute("insert into tablename(id, url, title) values(1, 'url1', 'title1');")
    conn.execute("insert into tablename(id, url, title) values(%s, %s, %s);", 2, "url2", "title2")
    conn.execute("insert into tablename(id, url, title) values(%s, %s, %s)", (3, "url3", "title3"))
    conn.execute("insert into tablename(id, url, title) values(%s, %s, %s)", [(31, "url31", "title31"), (32, "url32", "title32")])

    # 使用事务可以进行批量提交和回滚
    trans = conn.begin()
    try:
        conn.execute("insert into tablename(id, url, title) values(%s, %s, %s)", [(4, "url4", "title4"), (5, "url5", "title5")])
        trans.commit()
    except Exception as excep:
        trans.rollback()
        raise
    trans.close()
"""

# 首先需要生成一个BaseModel类,作为所有模型类的基类
BaseModel = sqlalchemy.ext.declarative.declarative_base()


# 构建数据模型User
class User(BaseModel):
    __tablename__ = "Users"         # 表名
    __table_args__ = {
        "mysql_engine": "InnoDB",   # 表的引擎
        "mysql_charset": "utf8",    # 表的编码格式
    }

    # 表结构,具体更多的数据类型自行百度
    id = sqlalchemy.Column("id", sqlalchemy.Integer, primary_key=True, autoincrement=True)
    name = sqlalchemy.Column("name", sqlalchemy.String(50), nullable=False)
    age = sqlalchemy.Column("age", sqlalchemy.Integer, default=0)

    # 添加角色id外键(关联到Role.id属性)
    role_id = sqlalchemy.Column("role_id", sqlalchemy.Integer, sqlalchemy.ForeignKey("Roles.id"))

    # 添加关系属性(关联到role_id外键上)
    role = sqlalchemy.orm.relationship("Role", foreign_keys="User.role_id")

    # 添加关系属性(关联到role_id外键上),如果使用了这种方式,Role模型中的users可以省略
    # role = sqlalchemy.orm.relationship("Role", foreign_keys="User.role_id", backref=sqlalchemy.orm.backref("users"))


# 构建数据模型Role
class Role(BaseModel):
    __tablename__ = "Roles"         # 表名
    __table_args__ = {
        "mysql_engine": "InnoDB",   # 表的引擎
        "mysql_charset": "utf8",    # 表的编码格式
    }

    # 表结构,具体更多的数据类型自行百度
    id = sqlalchemy.Column("id", sqlalchemy.Integer, primary_key=True)
    name = sqlalchemy.Column("name", sqlalchemy.String(50), unique=True)

    # 添加关系属性(关联到User.role_id属性上)
    users = sqlalchemy.orm.relationship("User", foreign_keys="User.role_id")


# 利用Session对象连接数据库
DBSessinon = sqlalchemy.orm.sessionmaker(bind=engine)   # 创建会话类
session = DBSessinon()                                  # 创建会话对象


# 删除所有表
BaseModel.metadata.drop_all(engine)
# 创建所有表,如果表已经存在,则不会创建
BaseModel.metadata.create_all(engine)

try:
    # 清空数据,不需要commit操作
    session.query(User).filter(User.id != -1).delete()
    session.query(Role).filter(Role.id != -1).delete()
    # 删除数据的另外一种形式:session.delete()

    # 插入数据,这里的一个实例只插入一次,第二次插入不生效
    session.add(Role(id=1, name="student"))
    session.add(Role(id=2, name="teacher"))
    session.commit()

    session.add(User(name="James", age=20, role_id=1))
    session.add(User(name="Wade", age=40, role_id=2))
    session.commit()

    user = User(name="Kobe", age=24, role_id=1)
    session.add(user)
    session.commit()

    # 修改数据
    user.name = "Allen"
    session.merge(user)                         # 使用merge方法,如果存在则修改,如果不存在则插入
    session.query(User).filter(User.id == user.id).update({User.name: "Allen"})         # 使用update方法
    session.query(User).filter(User.id == user.id).update({User.age: User.age + 1})     # 使用update方法,自增操作

    # 查询数据
    roles = session.query(Role)                 # 返回全部结果
    for role in roles:
        print("Role:", role.id, role.name)

    users = session.query(User)                 # 返回全部结果
    for user in users:
        print("User:", user.id, user.name, user.age, user.role_id)

    # 其他获取数据的方式
    print("get(id):", session.query(User).get(1))                       # 返回结果集中id为1的项
    print("get[1:3]:", session.query(User)[1:3])                        # 返回结果集中的第2-3项

    # 其他高级查询,这里以Users表为例
    users = session.query(User).filter(User.id > 6)                     # 条件查询
    users = session.query(User).filter(User.id > 6).all()               # 条件查询,返回查询的全部数据
    user = session.query(User).filter(User.id > 6).first()              # 条件查询,返回查询数据的第一项
    users = session.query(User).filter(User.id > 6).limit(10)           # 条件查询,返回最多10条数据
    users = session.query(User).filter(User.id > 6).offset(2)           # 条件查询,从第3条数据开始返回

    users = session.query(User).filter(User.id > 6, User.name == "Kobe")                    # 条件查询,and操作
    users = session.query(User).filter(User.id > 6).filter(User.name == "Kobe")             # 条件查询,and操作
    users = session.query(User).filter(sqlalchemy.or_(User.id > 6, User.name == "Kobe"))    # 条件查询,or操作
    users = session.query(User).filter(User.id.in_((1, 2)))                                 # 条件查询,in操作
    users = session.query(User).filter(sqlalchemy.not_(User.name))                          # 条件查询,not操作

    user_count = session.query(User.id).count()                                             # 统计全部user的数量
    user_count = session.query(sqlalchemy.func.count(User.id)).scalar()                     # scalar操作返回第一行数据的第一个字段
    session.query(sqlalchemy.func.count("*")).select_from(User).scalar()                    # scalar操作返回第一行数据的第一个字段
    session.query(sqlalchemy.func.count(1)).select_from(User).scalar()                      # scalar操作返回第一行数据的第一个字段
    session.query(sqlalchemy.func.count(User.id)).filter(User.id > 0).scalar()              # filter() 中包含 User,因此不需要指定表

    session.query(sqlalchemy.func.sum(User.age)).scalar()                                   # 求和运算,运用scalar函数
    session.query(sqlalchemy.func.avg(User.age)).scalar()                                   # 求均值运算,运用scalar函数
    session.query(sqlalchemy.func.md5(User.name)).filter(User.id == 1).scalar()             # 运用md5函数

    users = session.query(sqlalchemy.distinct(User.name))               # 去重查询,根据name进行去重
    users = session.query(User).order_by(User.name)                     # 排序查询,正序查询
    users = session.query(User).order_by(User.name.desc())              # 排序查询,倒序查询
    users = session.query(User).order_by(sqlalchemy.desc(User.name))    # 排序查询,倒序查询的另外一种形式

    users = session.query(User.id, User.name)                           # 只查询部分属性
    users = session.query(User.name.label("user_name"))                 # 结果集的列取别名
    for user in users:
        print("label test:", user.user_name)                            # 这里使用别名

    users = session.query(sqlalchemy.func.count(User.name).label("count"), User.age).group_by(User.age)    # 分组查询
    for user in users:
        print("age:{0}, count:{1}".format(user.age, user.count))

    # 多表查询
    result = session.query(User, Role).filter(User.role_id == Role.id)
    for user, role in result:
        print("user %s's role is %s" % (user.name, role.name))
    users = session.query(User).join(Role, User.role_id == Role.id)
    for user in users:
        print("user join, name:", user.name)

    # 关联属性的用法
    roles = session.query(Role)
    for role in roles:
        print("role:%s users:" % role.name)
        for user in role.users:
            print("\t%s" % user.name)
    users = session.query(User)
    for user in users:
        print("user %s's role is %s" % (user.name, user.role.name))

except Exception as excep:
    session.rollback()
    raise

session.close()

转载于:https://my.oschina.net/lemonwater/blog/1549242

<think>我们正在编写一个关于SQLAlchemy的入门教程。根据引用内容,我们知道SQLAlchemy有两种使用方式:Core和ORM。ORM建立在Core之上,Core更底层,可以直接执行SQL语句。对于初学者,通常从ORM开始学习,因为它更符合面向对象编程的习惯。 我们将按照以下结构组织教程: 1. 安装SQLAlchemy 2. 连接数据库 3. 使用ORM定义模型 4. 创建数据库表 5. 基本CRUD操作(增删改查) 6. 简单查询 同时,我们参考了引用[1]和引用[2]的内容,强调SQLAlchemyPython开发人员与数据库交互的重要工具,并介绍了两种使用方式的区别。 下面开始编写教程:</think>### SQLAlchemy 入门教程:Python 数据库交互的终极指南 SQLAlchemyPython 最强大的数据库工具包,提供完整的 SQL 功能和 ORM(对象关系映射)能力,让开发者能用面向对象的方式操作数据库[^1]。本教程将带你从零开始掌握 SQLAlchemy 的核心功能。 #### 1️⃣ 安装与环境准备 ```bash # 安装 SQLAlchemy 和 MySQL 驱动 pip install sqlalchemy pymysql ``` #### 2️⃣ 两种使用模式 SQLAlchemy 提供两种使用方式: - **Core**:底层 SQL 抽象层,适合需要直接控制 SQL 的场景 - **ORM**:高级对象关系映射,类似 Django ORM[^2] ```python from sqlalchemy import create_engine # 创建数据库连接 (MySQL 示例) engine = create_engine('mysql+pymysql://user:password@localhost/mydb') ``` #### 3️⃣ ORM 基础操作 **定义数据模型** ```python from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import Column, Integer, String, DateTime Base = declarative_base() class User(Base): __tablename__ = 'users' id = Column(Integer, primary_key=True) name = Column(String(50), nullable=False) email = Column(String(120), unique=True) created_at = Column(DateTime, default=datetime.now) ``` **创建数据库表** ```python # 创建所有定义的表 Base.metadata.create_all(engine) ``` **CRUD 操作** ```python from sqlalchemy.orm import sessionmaker # 创建会话 Session = sessionmaker(bind=engine) session = Session() # 创建记录 new_user = User(name='Alice', email='alice@example.com') session.add(new_user) session.commit() # 查询记录 user = session.query(User).filter_by(name='Alice').first() print(user.email) # 输出: alice@example.com # 更新记录 user.email = 'new_email@example.com' session.commit() # 删除记录 session.delete(user) session.commit() ``` #### 4️⃣ 高级查询技巧 ```python # 条件查询 users = session.query(User).filter(User.name.like('A%')).all() # 排序和分页 users = session.query(User).order_by(User.created_at.desc()).limit(10).offset(0) # 聚合查询 from sqlalchemy import func count = session.query(func.count(User.id)).scalar() ``` #### 5️⃣ 表关系管理 ```python class Post(Base): __tablename__ = 'posts' id = Column(Integer, primary_key=True) title = Column(String(100)) user_id = Column(Integer, ForeignKey('users.id')) # 定义关系 author = relationship("User", back_populates="posts") # 在 User 类中添加反向引用 User.posts = relationship("Post", back_populates="author") # 查询用户的所有文章 user = session.query(User).get(1) for post in user.posts: print(post.title) ``` #### 6️⃣ 核心 SQL 操作 ```python from sqlalchemy import text # 直接执行 SQL result = engine.execute(text("SELECT * FROM users WHERE name = :name"), {'name': 'Alice'}) for row in result: print(row) ``` #### 7️⃣ 最佳实践 1. **连接池管理**:默认使用 QueuePool 连接池 2. **事务处理**:使用上下文管理器确保安全 ```python with session.begin(): session.add(User(name='Bob')) session.add(Post(title='First Post', user_id=1)) ``` 3. **性能优化**:使用 `selectinload` 避免 N+1 查询问题 ```python from sqlalchemy.orm import selectinload # 一次性加载所有关联数据 users = session.query(User).options(selectinload(User.posts)).all() ``` ### 学习资源推荐 - 官方文档:https://www.sqlalchemy.org/ - SQLAlchemy ORM 教程:https://docs.sqlalchemy.org/en/14/orm/tutorial.html - SQLAlchemy Core 教程:https://docs.sqlalchemy.org/en/14/core/tutorial.html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值