SQLAlchemy(十)
ORM操作在实际项目中的应用非常多,涉及到的框架也是根据不同的项目有不同的处理模块,不过操作流程和步骤都是大同小异基本没有什么太大变化,唯一需要注意的就是在实际操作过程中你要使用的ORM框架的处理性能和是否支持事务、是否支持分布式等特性来进行确定使用哪个ORM框架进行操作,一般在python程序中ORM操作都是对mysqldb和pymysql这样的底层模块进行的封装处理。例如文章中要讲解的sqlalchemy就是底层封装mysqldb的实现,不过我们的在使用过程中需要使用pymysql进行替代。
1、安装
- $ pip install sqlalchemy
安装完成之后,可以通过引入sqlalchemy进行版本查看,确认sqlalchemy是否安装成功
2、连接引擎
使用sqlalchemy进行数据库操作,首先我们需要建立一个指定数据库的连接引擎对象。建立引擎对象的方式被封装在了sqlalchemy.create_engine函数中,通过指定的数据库连接信息就可以进行创建。
创建数据库连接引擎时参数设置语法:
- # 引入建立引擎的模块
- from sqlalchemy import create_engine
- # pymsql创建引擎连接
- # mysql+pymysql://<username>:<password>@<host>/<dbname>[?<options>]
- engine = create_engine("mysql+pymysql://root:123456@192.168.3.109:3306/test", encoding="utf-8", echo=True)
指定的数据库连接字符串表示了目标数据库的配置信息;encoding配置参数指定了和和数据库之间交换的数据的编码方式,同时echo参数表示随时在控制台展示和数据库之间交互的各种信息。
create_engine()函数返回的是sqlalchemy最核心的接口之一,该引擎对象会根据开发人员指定的数据库进行对应的sql api的调用处理。
3、连接会话
创建了数据库连接引擎对象之后,我们需要获取和指定数据库之间的连接,通过连接进行数据库中数据的增删改查操作,和数据库的连接我们称之为和指定数据库之间的会话。
我们使用 sessionmaker 方法创建session。
- # 引入创建session连接会话的模块
- from sqlalchemy.orm import sessionmaker
- # 创建一个连接会话对象;需要指定是和哪个数据库引擎之间的会话
- Session = sessionmaker(bind=engine)
- session = Session()
- # 如果在创建会话的时候没有指定数据库引擎,可以通过如下的方式完成引擎绑定操作
- # Session = sessionmaker()
- # Session.configure(bind=engine)
- # session = Session()
此时的session不是线程安全的,并且我们一般session对象都是全局的,那么在多线程情况下,当多个线程共享一个session时,数据处理就会发生错误。为了保证线程安全,需使用scoped_session方法。
- # 引入创建session连接会话的模块
- from sqlalchemy.orm import sessionmaker, scoped_session
- # 创建一个连接会话对象;需要指定是和哪个数据库引擎之间的会话
- Session = scoped_session(sessionmaker(bind=engine))
- session = Session()
4、ORM之Object操作
我们的程序中的对象要使用sqlalchemy的管理,实现对象的orm操作,就需要按照框架指定的方式进行类型的创建操作,sqlalchemy封装了基础类的声明操作和字段属性的定义限制方式,开发人员要做的事情就是引入需要的模块并在创建对象的时候使用它们即可
基础类封装在sqlalchemy.ext.declarative.declarative_base模块中
字段属性的定义封装在sqlalchemy模块中,通过sqlalchemy.Column定义属性,通过封装的Integer、String、Float等定义属性的限制
常用的SQLAlchemy字段类型
类型名 | python中类型 | 说明 |
---|---|---|
Integer | int | 普通整数,一般是32位 |
SmallInteger | int | 取值范围小的整数,一般是16位 |
BigInteger | int或long | 不限制精度的整数 |
Float | float | 浮点数 |
Numeric | decimal.Decimal | 普通整数,一般是32位 |
String | str | 变长字符串 |
Text | str | 变长字符串,对较长或不限长度的字符串做了优化 |
Unicode | unicode | 变长Unicode字符串 |
UnicodeText | unicode | 变长Unicode字符串,对较长或不限长度的字符串做了优化 |
Boolean | bool | 布尔值 |
Date | datetime.date | 时间 |
Time | datetime.datetime | 日期和时间 |
LargeBinary | str | 二进制文件 |
常用的SQLAlchemy列选项
选项名 | 说明 |
---|---|
primary_key | 如果为True,代表表的主键 |
unique | 如果为True,代表这列不允许出现重复的值 |
index | 如果为True,为这列创建索引,提高查询效率 |
nullable | 如果为True,允许有空值,如果为False,不允许有空值 |
default | 为这列定义默认值 |
常用的SQLAlchemy关系选项
选项名 | 说明 |
---|---|
backref | 在关系的另一模型中添加反向引用 |
primary join | 明确指定两个模型之间使用的联结条件 |
uselist | 如果为False,不使用列表,而使用标量值 |
order_by | 指定关系中记录的排序方式 |
secondary | 指定多对多中记录的排序方式 |
secondary join | 在SQLAlchemy中无法自行决定时,指定多对多关系中的二级联结条件 |
4.1 创建基础类
- # 引入需要的模块
- from sqlalchemy.ext.declarative import declarative_base
- # 创建基础类
- BaseModel = declarative_base()
4.2 创建模型类
定义模型类必须继承自之前创建的基础类BaseModel,同时通过指定__tablename__确定和数据库中某个数据表之间的关联关系,指定某列类型为primary_key设定的主键,其他就是通过Column指定的自定义属性了。
sqlalchemy会根据指定的__tablename__和对应的Column列字段构建自己的accessors访问器对象,这个过程可以称为instrumentation,经过instrumentation映射的类型就可以进行数据库中数据的操作了。
- # 引入需要的模块
- from sqlalchemy import Column, String, Integer, ForeignKey
- # 创建模型类
- class User(BaseModel):
- # 定义表名
- __tabelname__ = "tbl_user"
- # 创建字段类型
- id = Column(Integer, primary_key=True)
- name = Column(String(50))
- age = Column(Integer)
- class Author(BaseModel):
- __tablename__ = "tbl_author"
- id = Column(Integer, primary_key=True)
- name = Column(String(50))
- class Book(BaseModel):
- __tablename__ = "tbl_book"
- id = Column(Integer, primary_key=True)
- book_name = Column(String(50))
- # ForeignKey 定义外键,需要导入
- author_id = Column(Integer, ForeignKey("tbl_author.id"))
4.3 模型类映射操作
完成了模型类的定义之后,Declarative会通过python的metaclass对模型类进行操作,根据定义的模型类创建table对象,构建程序中类型和数据库table对象之间的映射mapping关系。
通过类型对象的metadata可以实现和数据库之间的交互,有需要时可以通过metadata发起create table操作,通过Base.metadata.create_all()进行操作,该操作会检查目标数据库中是否有需要创建的表,不存在的情况下创建对应的表。
- # 删除所有模型类创建的表格(慎用)
- BaseModel.metadata.drop_all(engine)
- # 创建所有模型类的表格,有则不创建
- BaseModel.metadata.create_all(engine)
5、数据的增、查、改、删
5.1 增
在程序代码中根据定义的数据类型创建对象的方式比较简单,创建对象并通过会话对象将数据对象持久化到数据库中。
- # 增
- user1 = User(name="张三", age=18)
- user2 = User(name="李四", age=19)
- user3 = User(name="王五", age=20)
- # 将单个对象加入到会话对象中
- session.add(user1)
- # 将多个对象加入到会话对象中
- session.add_all([user2, user3])
- # 提交数据
- session.commit()
5.2 查
Session是sqlalchemy和数据库交互的桥梁,Session提供了一个Query对象实现数据库中数据的查询操作
5.2.1 基础查询
查询所有数据
- # 返回User对象所有字段的所有信息,返回结果为对象列表
- session.query(User)
排序查询
- # 指定排序查询
- session.query(User).order_by(User.id) # 升序查询
- session.query(User).order_by(-User.id) # 降序查询
- session.query(User).order_by(-User.id, User.name) # 多条件排序查询
查询指定列
- # 返回User对象字段为id和name的所有信息,返回结果为元组列表
- session.query(User.id, User.name)
为字段取别名
- # 为字段取别名
- session.query(User.id, User.name.label("n"))
- # 对应SQL语句:SELECT tbl_user.id AS tbl_user_id, tbl_user.name AS n FROM tbl_user
分页查询
- # 使用limit()+offset()切片分页
- # limit()限制返回条数
- # offset()偏移
- ret = session.query(User).limit(3).offset(2).all() # 返回第2条以后的3条数据,即第3至第5条数据
- print(ret)
- # 使用slice()切片分页
- ret = session.query(User).slice(2, 5).all() # 返回第3至第5条数据
- print(ret)
- # 使用python列表切片分页
- ret = session.query(User).all()[2:5] # 返回第3至第5条数据
- print(ret)
分组查询
- # 分组查询
- session.query(User.name).group_by(User.name)
聚合函数
- # 查询常用聚合函数
- from sqlalchemy.sql import func
- session.query(func.max(User.age), # 最大
- func.min(User.age), # 最小
- func.sum(User.age), # 求和
- func.avg(User.age), # 平均
- func.count(User.age) # 统计
- )
去重
- # 去重查询
- from sqlalchemy import distinct
- session.query(distinct(User.name))
5.2.2 条件筛选
在实际使用过程中经常用到条件查询,主要通过filter和filter_by进行操作,重点讲解使用最为频繁的filter条件筛选函数
等值条件_equals / not equals
- # 等于
- session.query(User).filter(User.name == "李四")
- # 不等于
- session.query(User).filter(User.name != "李四")
模糊条件_like/notlike
- # 用户名包含“张”
- session.query(User).filter(User.name.like("%张%"))
- # 用户名不包含“张”
- session.query(User).filter(User.name.notlike('%张%'))
范围条件_in / not in
- # in
- session.query(User).filter(User.id.in_([1, 2, 4]))
- # not in
- session.query(User).filter(~User.id.in_([1, 2, 4]))
空值条件
- # 空值
- session.query(User).filter(User.name == None)
- session.query(User).filter(User.name.is_(None))
- # 非空
- session.query(User).filter(User.name != None)
- session.query(User).filter(User.name.isnot(None))
并且条件
- from sqlalchemy import and_
- session.query(User).filter(User.name == '张三').filter(User.age == 18)
- session.query(User).filter(User.name == '张三', User.age == 18)
- session.query(User).filter(and_(User.name == '张三', User.age == 18))
或者条件
- from sqlalchemy import or_
- session.query(User).filter(or_(User.name == '张三', User.name == '李四'))
5.2.3 多表查询
- # 多表查询
- session.query(Author.name, Book.book_name).filter(Author.id == Book.author_id)
- # 对应SQL:SELECT tbl_author.name, tbl_book.book_name FROM tbl_author, tbl_book WHERE tbl_author.id = tbl_book.author_id
- # 内联查询join
- session.query(Author.name, Book.book_name).join(Author, Author.id == Book.author_id)
- # 对应SQL:SELECT tbl_author.name, tbl_book.book_name FROM tbl_book INNER JOIN tbl_author ON tbl_author.id = tbl_book.author_id
- # 左联查询outerjoin。没有右联查询
- session.query(Author.name, Book.book_name).outerjoin(Author, Author.id == Book.author_id)
- # 对应SQL:SELECT tbl_author.name, tbl_book.book_name FROM tbl_book LEFT OUTER JOIN tbl_author ON tbl_author.id = tbl_book.author_id
- # 并集查询
- author_name = session.query(Author.name)
- book_name = session.query(Book.book_name)
- author_name.union(book_name)
- # 对应SQL:SELECT anon_1.c_name FROM
- # (SELECT tbl_author.name as c_name FROM tbl_author UNION SELECT tbl_book.book_name as c_name FROM tbl_book) AS anon_1
5.2.4 获取查询结果
获取查询对象有这么几种方法one()
,all()
,first(),one(),one_or_none()
,scalar(),以及get()等。
下面对这几个方法的用法及效果做简单解释。
all()
返回查询到的所有的结果。
这个方法比较危险的地方是如果数据量大且没有使用limit
子句限制的话,所有的结果都会加载到内存中。
它返回的是一个列表,如果查询不到任何结果,返回的是空列表。
- ret = session.query(User).all()
- print(ret) # [<__main__.User object at 0x0000000003894F60>, <__main__.User object at 0x00000000038942E8>]
first()
返回查询到的第一个结果,如果没有查询到结果,返回None
。
- ret = session.query(User).first()
- print(ret) # <__main__.User object at 0x0000000003894358>
one()
如果只能查询到一个结果,返回它,否则抛出异常。
没有结果时抛sqlalchemy.orm.exc.NoResultFound
,有超过一个结果时抛sqlalchemy.orm.exc.MultipleResultsFound
。
- ret = session.query(User).filter(User.id == 2).one()
- print(ret) # <__main__.User object at 0x00000000038954A8>
one_or_none()
比起one()
来,区别只是查询不到任何结果时不再抛出异常而是返回None
。
- ret = session.query(User).filter(User.id == 2).one_or_none()
- print(ret) # <__main__.User object at 0x00000000038954A8>
scalar()
这个方法与.one_or_none()
的效果一样。
如果查询到很多结果,抛出sqlalchemy.orm.exc.MultipleResultsFound
异常。
如果只有一个结果,返回它,没有结果返回None
。
- ret = session.query(User).filter(User.id == 2).scalar()
- print(ret) # <__main__.User object at 0x00000000038954A8>
get()
这是个比较特殊的方法。它用于根据主键来返回查询结果,因此它有个参数就是要查询的对象的主键。
如果没有该主键的结果返回None
,否则返回这个结果。
- ret = session.query(User).get(2)
- print(ret) # <__main__.User object at 0x00000000038954A8>
当获取的结果为一个对象时,可以通过 对象.模型类属性 的方式取出值
- user = session.query(User).get(2)
- print(user) # <__main__.User object at 0x00000000038954A8>
- print(user.name) # 李四
5.3 改
- # update()更新数据
- session.query(User).filter(User.id == 2).update({"name": "李四改"})
- session.query(User).filter(User.id >= 4).update({"age": 88})
- session.commit()
5.4 删
- # delete()删除数据
- session.query(User).filter(User.id == 2).delete()
- session.query(User).filter(User.id >= 4).delete()
- session.commit()
6、执行原生SQL语句
使用原生sql语句需要引入text方法,传入要执行的sql语句,若需要给sql语句传参,需要使用 :param 的方式定义参数名,然后使用 params() 并以键值对的方式传入值
- from sqlalchemy import text
- session.query(User).from_statement(text('select * from tbl_user where name=:name and age=:age')).params(name='李四', age=19)
- session.query(User).from_statement(text('update tbl_user set name=:name where id=:id')).params(name='赵六', id=1)
- session.commit()
还有一种类似于pymysql使用 execute() 执行原生sql的方法
- ret = session.execute('select * from tbl_user where name=:name', {"name": "赵六"}).fetchall() # 所有数据以元组的形式保存在列表中
- print(ret) # [(1, '赵六', 18, 2), (4, '赵六', 18, 2)]
- ret = session.execute('select * from tbl_user where name=:name', {"name": "赵六"}).fetchone() # 返回第一条数据,无则为None
- print(ret) # (1, '赵六', 18, 2)
附码:
- # 引入建立引擎的模块
- from sqlalchemy import create_engine
- # 引入创建session连接会话的模块
- from sqlalchemy.orm import sessionmaker, scoped_session
- # 模型类需要使用的模块
- from sqlalchemy.ext.declarative import declarative_base
- from sqlalchemy import Column, String, Integer, ForeignKey
- # 数据操作的模块
- from sqlalchemy import distinct, and_, or_
- # 执行原生SQL的模块
- from sqlalchemy import text
- # 1、pymsql创建引擎连接
- # mysql+pymysql://<username>:<password>@<host>/<dbname>[?<options>]
- engine = create_engine("mysql+pymysql://root:123456@192.168.3.109:3306/test", encoding="utf-8", echo=True)
- # 2、创建一个连接会话对象;需要指定是和哪个数据库引擎之间的会话
- Session = sessionmaker(bind=engine)
- session = Session()
- # 如果在创建会话的时候没有指定数据库引擎,可以通过如下的方式完成引擎绑定操作
- # Session = sessionmaker()
- # Session.configure(bind=engine)
- # session = Session()
- # 安全session
- # Session = scoped_session(sessionmaker(bind=engine))
- # session = Session()
- # 3、模型类
- # 创建基础类
- BaseModel = declarative_base()
- # 创建模型类
- class User(BaseModel):
- # 定义表名
- __tabelname__ = "tbl_user"
- # 创建字段类型
- id = Column(Integer, primary_key=True)
- name = Column(String(50))
- age = Column(Integer)
- class Author(BaseModel):
- __tablename__ = "tbl_author"
- id = Column(Integer, primary_key=True)
- name = Column(String(50))
- class Book(BaseModel):
- __tablename__ = "tbl_book"
- id = Column(Integer, primary_key=True)
- book_name = Column(String(50))
- # ForeignKey 定义外键,需要导入
- author_id = Column(Integer, ForeignKey("tbl_author.id"))
- # 删除所有模型类创建的表格(慎用)
- # BaseModel.metadata.drop_all(engine)
- # 创建所有模型类的表格,有则不创建
- BaseModel.metadata.create_all(engine)
- # 4、数据操作
- # 增
- user1 = User(name="张三", age=18)
- user2 = User(name="李四", age=19)
- user3 = User(name="王五", age=20)
- # 将单个对象加入到会话对象中
- session.add(user1)
- # 将多个对象加入到会话对象中
- session.add_all([user2, user3])
- # 提交数据
- session.commit()
- # 返回User对象所有字段的所有信息,返回结果为对象列表
- session.query(User)
- # 指定排序查询
- session.query(User).order_by(User.id) # 升序查询
- session.query(User).order_by(-User.id) # 降序查询
- session.query(User).order_by(-User.id, User.name) # 多条件排序查询
- # 返回User对象字段为id和name的所有信息,返回结果为元组列表
- session.query(User.id, User.name)
- # 为字段取别名
- session.query(User.id, User.name.label("n"))
- # 对应SQL语句:SELECT tbl_user.id AS tbl_user_id, tbl_user.name AS n FROM tbl_user
- # 分组查询
- session.query(User.name).group_by(User.name)
- # 查询常用聚合函数
- from sqlalchemy.sql import func
- session.query(func.max(User.age), # 最大
- func.min(User.age), # 最小
- func.sum(User.age), # 求和
- func.avg(User.age), # 平均
- func.count(User.age) # 统计
- )
- # 去重查询
- session.query(distinct(User.name))
- # 使用limit()+offset()切片分页
- # limit()限制返回条数
- # offset()偏移
- ret = session.query(User).limit(3).offset(2).all() # 返回第2条以后的3条数据,即第3至第5条数据
- print(ret)
- # 使用slice()切片分页
- ret = session.query(User).slice(2, 5).all() # 返回第3至第5条数据
- print(ret)
- # 使用python列表切片分页
- ret = session.query(User).all()[2:5] # 返回第3至第5条数据
- print(ret)
- # 等于
- session.query(User).filter(User.name == "李四")
- # 不等于
- session.query(User).filter(User.name != "李四")
- # 用户名包含“张”
- session.query(User).filter(User.name.like("%张%"))
- # 用户名不包含“张”
- session.query(User).filter(User.name.notlike('%张%'))
- # in
- session.query(User).filter(User.id.in_([1, 2, 4]))
- # not in
- session.query(User).filter(~User.id.in_([1, 2, 4]))
- # 空值
- session.query(User).filter(User.name == None)
- session.query(User).filter(User.name.is_(None))
- # 非空
- session.query(User).filter(User.name != None)
- session.query(User).filter(User.name.isnot(None))
- # 并且
- session.query(User).filter(User.name == '张三').filter(User.age == 18)
- session.query(User).filter(User.name == '张三', User.age == 18)
- session.query(User).filter(and_(User.name == '张三', User.age == 18))
- # 或者
- session.query(User).filter(or_(User.name == '张三', User.name == '李四'))
- # 多表查询
- session.query(Author.name, Book.book_name).filter(Author.id == Book.author_id)
- # 对应SQL:SELECT tbl_author.name, tbl_book.book_name FROM tbl_author, tbl_book WHERE tbl_author.id = tbl_book.author_id
- # 内联查询join
- session.query(Author.name, Book.book_name).join(Author, Author.id == Book.author_id)
- # 对应SQL:SELECT tbl_author.name, tbl_book.book_name FROM tbl_book INNER JOIN tbl_author ON tbl_author.id = tbl_book.author_id
- # 左联查询outerjoin。没有右联查询
- session.query(Author.name, Book.book_name).outerjoin(Author, Author.id == Book.author_id)
- # 对应SQL:SELECT tbl_author.name, tbl_book.book_name FROM tbl_book LEFT OUTER JOIN tbl_author ON tbl_author.id = tbl_book.author_id
- # 并集查询
- author_name = session.query(Author.name)
- book_name = session.query(Book.book_name)
- author_name.union(book_name)
- # 对应SQL:SELECT anon_1.c_name FROM
- # (SELECT tbl_author.name as c_name FROM tbl_author UNION SELECT tbl_book.book_name as c_name FROM tbl_book) AS anon_1
- # all()返回所有的数据
- session.query(User).all()
- # first()返回查询到的第一个结果,如果没有查询到结果,返回None。
- session.query(User).first()
- # one()如果只能查询到一个结果,返回它,否则抛出异常。
- session.query(User).filter(User.id == 2).one()
- # one_or_none()比起one()来,区别只是查询不到任何结果时不再抛出异常而是返回None。
- session.query(User).filter(User.id == 2).one_or_none()
- # scalar()这个方法与.one_or_none()的效果一样。
- session.query(User).filter(User.id == 2).scalar()
- # get()这是个比较特殊的方法。它用于根据主键来返回查询结果,因此它有个参数就是要查询的对象的主键。如果没有该主键的结果返回None,否则返回这个结果。
- session.query(User).get(2)
- # update()更新数据
- session.query(User).filter(User.id == 2).update({"name": "李四改"})
- session.query(User).filter(User.id >= 4).update({"age": 88})
- session.commit()
- # delete()删除数据
- session.query(User).filter(User.id == 2).delete()
- session.query(User).filter(User.id >= 4).delete()
- session.commit()
- # 执行原生SQL
- session.query(User).from_statement(text('select * from tbl_user where name=:name and age=:age')).params(name='李四', age=19)
- session.query(User).from_statement(text('update tbl_user set name=:name where id=:id')).params(name='赵六', id=1)
- session.commit()
原文参考:https://blog.csdn.net/u012089823/article/details/94650310
SQLAlchemy(十)的更多相关文章
- 我的python开发目录模块连接
一.python语言 二.HTML 三.css 四.javascript 五.DOM 六.jquery 七.AJAX 八.WEB前端插件 九.自定义WEB框架 十.WEB框架之tornado 十一.M ...
- Python开发【十二章】:ORM sqlalchemy
一.对象映射关系(ORM) orm英文全称object relational mapping,就是对象映射关系程序,简单来说我们类似python这种面向对象的程序来说一切皆对象,但是我们使用的数据库却 ...
- 循序渐进Python3(十)-- 2 -- SqlAlchemy
ORM 对象关系映射(英语:Object Relation Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序技术,用于实现面向对象编程语言里不同类 ...
- 循序渐进Python3(十)-- 3 -- SqlAlchemy
使用sqlalchemy 创建外键关联 ), ), ) host_user = Column(String(), ), ), ]).first()for item in works.workinfo: ...
- python【第十二篇下】操作MySQL数据库以及ORM之 sqlalchemy
内容一览: 1.Python操作MySQL数据库 2.ORM sqlalchemy学习 1.Python操作MySQL数据库 2. ORM sqlachemy 2.1 ORM简介 对象关系映射(英语: ...
- python运维开发(十二)----rabbitMQ、pymysql、SQLAlchemy
内容目录: rabbitMQ python操作mysql,pymysql模块 Python ORM框架,SQLAchemy模块 Paramiko 其他with上下文切换 rabbitMQ Rabbit ...
- python第六十六天--sqlalchemy
#!usr/bin/env python #-*-coding:utf-8-*- # Author calmyan #python #2017/7/6 21:29 #__author__='Admin ...
- python(十二)下:ORM框架SQLAlchemy使用学习
此出处:http://blog.csdn.net/fgf00/article/details/52949973 本节内容 ORM介绍 sqlalchemy安装 sqlalchemy基本使用 多外键关联 ...
- 第二百八十九节,MySQL数据库-ORM之sqlalchemy模块操作数据库
MySQL数据库-ORM之sqlalchemy模块操作数据库 sqlalchemy第三方模块 sqlalchemysqlalchemy是Python编程语言下的一款ORM框架,该框架建立在数据库API ...
- 六十 数据库访问 使用SQLAlchemy
数据库表是一个二维表,包含多行多列.把一个表的内容用Python的数据结构表示出来的话,可以用一个list表示多行,list的每一个元素是tuple,表示一行记录,比如,包含id和name的user表 ...
随机推荐
- 如何为Dash/Zeal生成c++ 文档: 以abseil文档为例
目录 1. 软件安装 2 Sample源文件下载: 3. 生成步骤 3.1 使用doxygen生成html文件 3.2 使用docsetutil 生成 dash/Zeal 格式 1. 软件安装: 1. ...
- SQL->Python->PySpark计算KS,AUC及PSI
KS,AUC 和 PSI 是风控算法中最常计算的几个指标,本文记录了多种工具计算这些指标的方法. 生成本文的测试数据: import pandas as pd import numpy as np i ...
- 【Redis的那些事 · 上篇】Redis的介绍、五种数据结构演示和分布式锁
Redis是什么 Redis,全称是Remote Dictionary Service,翻译过来就是,远程字典服务. redis属于nosql非关系型数据库.Nosql常见的数据关系,基本上是以key ...
- LuoguB2105 矩阵乘法 题解
Content 给定一个 \(n\times m\) 的矩阵 \(A\) 和一个 \(m\times k\) 的矩阵 \(B\),求两个矩阵相乘得到的矩阵. \(n\times m\) 的矩阵 \(A ...
- LuoguP7127 「RdOI R1」一次函数(function) 题解
Content 设 \(S_k\) 为直线 \(f(x)=kx+k-1\),直线 \(f(x)=(k+1)x+k\) 与 \(x\) 轴围成的三角形的面积.现在给出 \(t\) 组询问,每组询问给定一 ...
- java 图形化小工具Abstract Window Toolit
老掉牙的历史 Java1.0在发布的时候,就为我们提供了GUI操作的库,这个库系统在所有的平台下都可以运行,这套基本的类库被称作抽象窗口工具集(Abstract Window Toolit),简称 ...
- 当是class com.cosl.po.Pc$$EnhancerByCGLIB$$38c58f03时,反射属性都他妈不好用了
当是class com.cosl.po.Pc$$EnhancerByCGLIB$$38c58f03时,反射属性都他妈不好用了 搞不懂为什么?
- 【LeetCode】283. Move Zeroes 解题报告(Java & Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 方法一:首尾指针 方法二:头部双指针+双循环 方法三 ...
- 【LeetCode】50. Pow(x, n) 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述: 题目大意 解题方法 递归 迭代 日期 题目地址: https://le ...
- Rikka with wood sticks(hdu5203)
Rikka with wood sticks Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/O ...