Python SQLAlchemy基本操作和常用技巧包含大量实例,非常好python

时间:2021-12-27 03:08:05

http://www.makaidong.com/%E8%84%9A%E6%9C%AC%E4%B9%8B%E5%AE%B6/28053.shtml

"Python SQLAlchemy基本操作和常用技巧包含大量实例,非常好python":关键词python sqlalchemy 基本 作和 常用 技巧 包含 大量 实例 非常好 python

首先说下,由于最新的 0.8 版还是开发版本,因此我使用的是 0.79 版,api 也许会有些不同。
因为我是搭配 mysql innodb 使用,所以使用其他其他数据库 的也不能完全照搬本文。

接着就从安装开始介绍吧,以 debian/ubuntu 为例(请确保有管理员权限):
1.mysql

复制代码 代码如下:
apt-get install mysql-server
apt-get install mysql-client
apt-get install libmysqlclient15-dev

2.python-mysqldb

复制代码 代码如下:
apt-get install python-mysqldb

3.easy_install

复制代码 代码如下:
wget http://peak.telecommunity.com/dist/ez_setup.py

python ez_setup.py
4.mysql-python

复制代码 代码如下:
easy_install mysql-python

5.sqlalchemy

复制代码 代码如下:
easy_install sqlalchemy

如果是用其他操作系统,遇到问题就 google 一下吧。我是在 mac os x 上开发的,途中也遇到些问题,不过当时没记下来……
值得一提的是我用了 mysql-python 来连 mysql,因为不支持异步调用,所以和 tornado 不是很搭。不过性能其实很好,因此以后再去研究下其他方案吧……

装好后就可以开始使用了:

复制代码 代码如下:
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

db_connect_string = 'mysql+mysqldb://root:123@localhost/ooxx?charset=utf8'
engine = create_engine(db_connect_string, echo=true)
db_session = sessionmaker(bind=engine)
session = db_session()

这里的 db_connect_string 就是连接其他数据库 的路径。“mysql+mysqldb”指定了使用 mysql-python 来连接,“root”和“123”分别是用户名和密码,“localhost”是其他数据库 的域名,“ooxx”是使用的其他数据库 名(可省略),“charset”指定了连接时使用的字符集(可省略)。
create_engine() 会返回一个其他数据库 引擎,echo 参数为 true 时,会显示每条执行的 sql 语句,生产环境下可关闭。
sessionmaker() 会生成一个其他数据库 会话类。这个类的实例可以当成一个其他数据库 连接,它同时还记录了一些查询的数据,并决定什么时候执行 sql 语句。由于 sqlalchemy 自己维护了一个其他数据库 连接池(默认 5 个连接),因此初始化一个会话的开销并不大。对 tornado 而言,可以在 basehandler 的 initialize() 里初始化:

复制代码 代码如下:
class basehandler(tornado.web.requesthandler):
    def initialize(self):
        self.session = models.db_session()

def on_finish(self):
        self.session.close()

对其他 web 服务器开发来说,可以使用 sqlalchemy.orm.scoped_session,它能保证每个线程获得的 session 对象都是唯一的。不过 tornado 本身就是单线程的,如果使用了异步方式,就可能会出现问题,因此我并没使用它。

拿到 session 后,就可以执行 sql 了:

复制代码 代码如下:
session.execute('create database abc')
print session.execute('show database s').fetchall()
session.execute('use abc')
# 建 user 表的开发过程
print session.execute('select * from user where id = 1').first()
print session.execute('select * from user where id = :id', {'id': 1}).first()

不过这和直接使用 mysql-python 没啥区别,所以就不介绍了;我还是喜欢 orm 的方式,这也是我采用 sqlalchemy 的唯一原因。

于是来定义一个表:

复制代码 代码如下:
from sqlalchemy import column
from sqlalchemy.types import char, integer, string
from sqlalchemy.ext.declarative import declarative_base

basemodel = declarative_base()

def init_db():
    basemodel.metadata.create_all(engine)

def drop_db():
    basemodel.metadata.drop_all(engine)

class user(basemodel):
    __tablename__ = 'user'

id = column(integer, primary_key=true)
    name = column(char(30)) # or column(string(30))

init_db()

declarative_base() 创建了一个 basemodel 类,这个类的子类可以自动与一个表关联。
以 user 类为例,它的 __tablename__ 属性就是其他数据库 中该表的名称,它有 id 和 name 这两个字段,分别为整型和 30 个定长字符。column 还有一些其他的参数,我就不解释了。
最后,basemodel.metadata.create_all(engine) 会找到 basemodel 的所有子类,并在其他数据库 中建立这些表;drop_all() 则是删除这些表。

接着就开始使用这个表吧:

复制代码 代码如下:
from sqlalchemy import func, or_, not_

user = user(name='a')
session.add(user)
user = user(name='b')
session.add(user)
user = user(name='a')
session.add(user)
user = user()
session.add(user)
session.commit()

query = session.query(user)
print query # 显示sql 语句
print query.statement # 同上
for user in query: # 遍历时查询
    print user.name
print query.all() # 返回的是一个类似列表的对象
print query.first().name # 记录不存在时,first() 会返回 none
# print query.one().name # 不存在,或有多行记录时会抛出异常
print query.filter(user.id == 2).first().name
print query.get(2).name # 以主键获取,等效于上句
print query.filter('id = 2').first().name # 支持字符串

query2 = session.query(user.name)
print query2.all() # 每行是个元组
print query2.limit(1).all() # 最多返回 1 条记录
print query2.offset(1).all() # 从第 2 条记录开始返回
print query2.order_by(user.name).all()
print query2.order_by('name').all()
print query2.order_by(user.name.desc()).all()
print query2.order_by('name desc').all()
print session.query(user.id).order_by(user.name.desc(), user.id).all()

print query2.filter(user.id == 1).scalar() # 如果有记录,返

此文来自: 马开东博客 转载请注明出处 网址:http://www.makaidong.com

回第一条记录的第一个元素
print session.query('id').select_from(user).filter('id = 1').scalar()
print query2.filter(user.id > 1, user.name != 'a').scalar() # and
query3 = query2.filter(user.id > 1) # 多次拼接的 filter 也是 and
query3 = query3.filter(user.name != 'a')
print query3.scalar()
print query2.filter(or_(user.id == 1, user.id == 2)).all() # or
print query2.filter(user.id.in_((1, 2))).all() # in

query4 = session.query(user.id)
print query4.filter(user.name == none).scalar()
print query4.filter('name is null').scalar()
print query4.filter(not_(user.name == none)).all() # not
print query4.filter(user.name != none).all()

print query4.count()
print session.query(func.count('*')).select_from(user).scalar()
print session.query(func.count('1')).select_from(user).scalar()
print session.query(func.count(user.id)).scalar()
print session.query(func.count('*')).filter(user.id > 0).scalar() # filter() 中包含 user,因此不需要指定表
print session.query(func.count('*')).filter(user.name == 'a').limit(1).scalar() == 1 # 可以用 limit() 限制 count() 的返回数
print session.query(func.sum(user.id)).scalar()
print session.query(func.now()).scalar() # func 后可以跟任意函数名,只要该其他数据库 支持
print session.query(func.current_timestamp()).scalar()
print session.query(func.md5(user.name)).filter(user.id == 1).scalar()

query.filter(user.id == 1).update({user.name: 'c'})
user = query.get(1)
print user.name

user.name = 'd'
session.flush() # 写其他数据库 ,但并不提交
print query.get(1).name

session.delete(user)
session.flush()
print query.get(1)

session.rollback()
print query.get(1).name
query.filter(user.id == 1).delete()
session.commit()
print query.get(1)

增删改查都涉及到了,自己看看输出的 sql 语句就知道了,于是基础知识就介绍到此了。

下面开始介绍一些进阶的知识。

如何批量插入大批数据?

可以使用非 orm 的方式:

复制代码 代码如下:
session.execute(
    user.__table__.insert(),
    [{'name': `randint(1, 100)`,'age': randint(1, 100)} for i in xrange(10000)]
)
session.commit()

上面我批量插入了 10000 条记录,半秒内就执行完了;而 orm 方式会花掉很长时间。

如何让执行的 sql 语句增加前缀?

使用 query 对象的 prefix_with() 开发方法

复制代码 代码如下:
session.query(user.name).prefix_with('high_priority').all()
session.execute(user.__table__.insert().prefix_with('ignore'), {'id': 1, 'name': '1'})

如何替换一个已有主键的记录?

使用 session.merge() 开发方法 替代 session.add(),其实就是 select + update:

复制代码 代码如下:
user = user(id=1, name='ooxx')
session.merge(user)
session.commit()

或者使用
mysql 的 insert … on duplicate key update,需要用到 @compiles
装饰器,有点难懂,自己搜索看吧:《sqlalchemy on duplicate key update》 和
sqlalchemy_mysql_ext。

如何使用无符号整数?

可以使用 mysql 的方言:

复制代码 代码如下:
from sqlalchemy.dialects.mysql import integer

id = column(integer(unsigned=true), primary_key=true)

模型的属性名需要和表的字段名不一样怎么办?

开发时遇到过一个奇怪的需求,有个其他系统开发的表里包含了一个“from”字段,这在 python 里是关键字,于是只能这样处理了:

复制代码 代码如下:
from_ = column('from', char(10))

如何获取字段的长度?

column 会生成一个很复杂的对象,想获取长度比较麻烦,这里以 user.name 为例:

复制代码 代码如下:
user.name.property.columns[0].type.length

如何指定使用 innodb,以及使用 utf-8 编码?

最简单的方式就是修改其他数据库 的默认配置。如果非要在代码里指定的话,可以这样:

复制代码 代码如下:
class user(basemodel):
    __table_args__ = {
        'mysql_engine': 'innodb',
        'mysql_charset': 'utf8'
    }

mysql 5.5 开始支持存储 4 字节的 utf-8 编码的字符了,ios 里自带的 emoji(如

Python SQLAlchemy基本操作和常用技巧包含大量实例,非常好python的更多相关文章

  1. Python SQLAlchemy基本操作和常用技巧(包含大量实例,非常好)

    https://www.jb51.net/article/49789.htm 首先说下,由于最新的 0.8 版还是开发版本,因此我使用的是 0.79 版,API 也许会有些不同.因为我是搭配 MySQ ...

  2. 【Python】Python SQLAlchemy基本操作和常用技巧

    首先说下,由于最新的 0.8 版还是开发版本,因此我使用的是 0.79 版,API 也许会有些不同.因为我是搭配 MySQL InnoDB 使用,所以使用其他数据库的也不能完全照搬本文. 接着就从安装 ...

  3. Python SQLAlchemy基本操作和常用技巧

    转自:https://www.jb51.net/article/49789.htm 首先说下,由于最新的 0.8 版还是开发版本,因此我使用的是 0.79 版,API 也许会有些不同.因为我是搭配 M ...

  4. SQLAlchemy基本操作和常用技巧

    点击打开链接 Python的ORM框架SQLAlchemy基本操作和常用技巧,包含大量实例,非常好的一个学习SQLAlchemy的教程,需要的朋友可以参考下 python编程语言下的一款开源软件.提供 ...

  5. Python中的 一些常用技巧函数[.join()]

    1.str.join(item)字符串操作函数,参数item可以是字符串.元组.字典,示例 ','.join('abc') [','.join('abc')] 输出: 'a,b,c'['a', 'b' ...

  6. python文件和目录操作方法大全(含实例)【python】

    转自:http://www.jb51.net/article/48001.htm 一.python中对文件.文件夹操作时经常用到的os模块和shutil模块常用方法. 1.得到当前工作目录,即当前Py ...

  7. Python SqlAlchemy使用方法

    1.初始化连接 from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker engine = create ...

  8. python中列表元素连接方法join用法实例

    python中列表元素连接方法join用法实例 这篇文章主要介绍了python中列表元素连接方法join用法,实例分析了Python中join方法的使用技巧,非常具有实用价值,分享给大家供大家参考. ...

  9. 今天整理了几个在使用python进行数据分析的常用小技巧、命令。

    提高Python数据分析速度的八个小技巧 01 使用Pandas Profiling预览数据 这个神器我们在之前的文章中就详细讲过,使用Pandas Profiling可以在进行数据分析之前对数据进行 ...

随机推荐

  1. sql查询单个银行账号重复

    非一单位多银行账号. 今天成都公司熊娇付款时候单位名称在弹出的网银补录变成1,从开户银行看都是正常的,只是在分子公司集团这边点击修改开户银行保存就提示错误“银行账号不能重复” select * fro ...

  2. Linux使用汇总贴

    1. 服务开机启动 比如: update-rc.d ssh enable 2. 修改hostname [基于ubutun] hostname newname vi /etc/hostnamevi /e ...

  3. DNS报文格式

    原文链接地址:http://blog.chinaunix.net/uid-24875436-id-3088461.html DNS报文格式(借个图贴过来):     说明一下:并不是所有DNS报文都有 ...

  4. -bash: crontab: command not found(转)

    操作步骤 1. 确认crontab是否安装: 执行 crontab 命令如果报 command not found,就表明没有安装 2. 安装 crontab 执行 yum install -y vi ...

  5. IP 网际协议

    1. IP数据首部长度: 4位版本号 : 4 位,用于标明 IP 版本号,0100 表示 IPv4,0110 表示 IPv6.目前常见的是 IPv4. 4位首部长度: 首部长度是占4位,可表示的最大十 ...

  6. 201521123062《Java程序设计》第10周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常与多线程相关内容. 2. 书面作业 1.finally 题目4-2 1.1 截图你的提交结果(出现学号) 1.2 4-2中fin ...

  7. Oracle table names are case sensitive (normally all uppercase)

    oracle_fdw error desc: postgres=# select * from test; ERROR:  Oracle table "sangli"." ...

  8. Spring Boot JPA的Column Table 注解命名字段无效

    @Table(name = "OrderInfo") @Entity public class OrderInfo { @Id @GeneratedValue private Lo ...

  9. asp.net core mvc HTTP Error 502.5 - Process Failure

    HTTP Error 502.5 - Process Failure Common causes of this issue: The application process failed to st ...

  10. python常用模块之-random模块

    random模块顾名思义就是生成随机数的模块. random模块有以下常见方法: 1,打印0-1之间的任意随机浮点数,不能指定区间. print(random.random()) 2,打印随机符点数, ...