http://www.codexiu.cn/python/SQLAlchemy%E5%9F%BA%E7%A1%80%E6%95%99%E7%A8%8B/73/529/
SQLAlchemy模型使用
本篇内容为大家提供的是SQLAlchemy基础教程中的SQLAlchemy模型使用,该教程主要介绍了SQLAlchemy模型的定义、创建、查询、修改、删除、JOIN,详细而全面,感兴趣的同学可以参考学习一下。
SQLAlchemy模型使用
3.1. 模型定义
3.2. 创建
3.3. 查询
3.4. 修改
3.5. 删除
3.6. JOIN
3.SQLAlchemy 模型使用
3.1. 模型定义
对于 Table 的定义, 本来是直接的实例化调用, 通过 declarative 的包装, 可以像”定义类”这样的更直观的方式来完成.
user = Table(‘user’, metadata,
Column(‘user_id’, Integer, primary_key = True),
Column(‘user_name’, String(16), nullable = False),
Column(‘email_address’, String(60)),
Column(‘password’, String(20), nullable = False)
)
-- coding: utf-8 --
from sqlalchemy import create_engine
from sqlalchemy import Column
from sqlalchemy.types import String, Integer, CHAR, BIGINT
from sqlalchemy.ext.declarative import declarative_base
BaseModel = declarative_base()
Engine = create_engine(‘postgresql://test@localhost:5432/test’, echo=True)
class Blog(BaseModel):
tablename = ‘blog’
id = Column(CHAR(32), primary_key=True)
title = Column(String(64), server_default='', nullable=False)
text = Column(String, server_default='', nullable=False)
user = Column(CHAR(32), index=True, server_default='', nullable=False)
create = Column(BIGINT, index=True, server_default='0', nullable=False)
class User(BaseModel):
tablename = ‘user’
id = Column(CHAR(32), primary_key=True)
name = Column(String(32), server_default='', nullable=False)
username = Column(String(32), index=True, server_default='', nullable=False)
password = Column(String(64), server_default='', nullable=False)
def init_db():
BaseModel.metadata.create_all(Engine)
def drop_db():
BaseModel.metadata.drop_all(Engine)
if name == ‘main‘:
#init_db()
drop_db()
#BaseModel.metadata.tables[‘user’].create(Engine, checkfirst=True)
#BaseModel.metadata.tables[‘user’].drop(Engine, checkfirst=False)
pass
3.2. 创建
session = Session()
session.add(User(id=uuid.uuid4().hex))
session.add(Blog(id=uuid.uuid4().hex))
session.add_all([
User(id=uuid.uuid4().hex),
Blog(id=uuid.uuid4().hex)
])
session.commit()
执行的顺序并不一定会和代码顺序一致, SQLAlchemy 自己会整合逻辑再执行.
3.3. 查询
SQLAlchemy 实现的查询非常强大, 写起来有一种随心所欲的感觉.
查询的结果, 有几种不同的类型, 这个需要注意, 像是:
instance
instance of list
keyed tuple of list
value of list
基本查询
session.query(User).filter_by(username=’abc’).all()
session.query(User).filter(User.username==’abc’).all()
session.query(Blog).filter(Blog.create >= 0).all()
session.query(Blog).filter(Blog.create >= 0).first()
session.query(Blog).filter(Blog.create >= 0 | Blog.title == ‘A’).first()
session.query(Blog).filter(Blog.create >= 0 & Blog.title == ‘A’).first()
session.query(Blog).filter(Blog.create >= 0).offset(1).limit(1).scalar()
session.query(User).filter(User.username == ‘abc’).scalar()
session.query(User.id).filter(User.username == ‘abc’).scalar()
session.query(Blog.id).filter(Blog.create >= 0).all()
session.query(Blog.id).filter(Blog.create >= 0).all()[0].id
dict(session.query(Blog.id, Blog.title).filter(Blog.create >= 0).all())
session.query(Blog.id, Blog.title).filter(Blog.create >= 0).first().title
session.query(User.id).order_by(‘id desc’).all()
session.query(User.id).order_by(‘id’).first()
session.query(User.id).order_by(User.id).first()
session.query(User.id).order_by(-User.id).first()
session.query(‘id’, ‘username’).select_from(User).all()
session.query(User).get(‘16e19a64d5874c308421e1a835b01c69’)
多表查询
session.query(Blog, User).filter(Blog.user == User.id).first().User.username
session.query(Blog, User.id, User.username).filter(Blog.user == User.id).first().id
session.query(Blog.id,
User.id,
User.username).filter(Blog.user == User.id).first().keys()
条件查询
from sqlalchemy import or_, not_
session.query(User).filter(or_(User.id == ”,
User.id == ‘16e19a64d5874c308421e1a835b01c69’)).all()
session.query(User).filter(not_(User.id == ‘16e19a64d5874c308421e1a835b01c69’)).all()
session.query(User).filter(User.id.in_([‘16e19a64d5874c308421e1a835b01c69’])).all()
session.query(User).filter(User.id.like(‘16e19a%’)).all()
session.query(User).filter(User.id.startswith(‘16e19a’)).all()
dir(User.id)
函数
from sqlalchemy import func
session.query(func.count(‘1’)).select_from(User).scalar()
session.query(func.count(‘1’), func.max(User.username)).select_from(User).first()
session.query(func.count(‘1’)).select_from(User).scalar()
session.query(func.md5(User.username)).select_from(User).all()
session.query(func.current_timestamp()).scalar()
session.query(User).count()
3.4. 修改
还是通常的两种方式:
session.query(User).filter(User.username == ‘abc’).update({‘name’: ‘123’})
session.commit()
user = session.query(User).filter_by(username=’abc’).scalar()
user.name = ‘223’
session.commit()
如果涉及对属性原值的引用, 则要考虑 synchronize_session 这个参数.
‘evaluate’ 默认值, 会同时修改当前 session 中的对象属性.
‘fetch’ 修改前, 会先通过 select 查询条目的值.
False 不修改当前 session 中的对象属性.
在默认情况下, 因为会有修改当前会话中的对象属性, 所以如果语句中有 SQL 函数, 或者”原值引用”, 那是无法完成的操作, 自然也会报错, 比如:
from sqlalchemy import func
session.query(User).update({User.name: func.trim(‘123 ‘)})
session.query(User).update({User.name: User.name + ‘x’})
这种情况下, 就不能要求 SQLAlchemy 修改当前 session 的对象属性了, 而是直接进行数据库的交互, 不管当前会话值:
session.query(User).update({User.name: User.name + ‘x’}, synchronize_session=False)
是否修改当前会话的对象属性, 涉及到当前会话的状态. 如果当前会话过期, 那么在获取相关对象的属性值时, SQLAlchemy 会自动作一次数据库查询, 以便获取正确的值:
user = session.query(User).filter_by(username=’abc’).scalar()
print user.name
session.query(User).update({User.name: ‘new’}, synchronize_session=False)
print user.name
session.commit()
print user.name
执行了 update 之后, 虽然相关对象的实际的属性值已变更, 但是当前会话中的对象属性值并没有改变. 直到 session.commit() 之后, 当前会话变成”过期”状态, 再次获取 user.name 时, SQLAlchemy 通过 user 的 id 属性, 重新去数据库查询了新值. (如果 user 的 id 变了呢? 那就会出事了啊.)
synchronize_session 设置成 ‘fetch’ 不会有这样的问题, 因为在做 update 时已经修改了当前会话中的对象了.
不管 synchronize_session 的行为如何, commit 之后 session 都会过期, 再次获取相关对象值时, 都会重新作一次查询.
3.5. 删除
session.query(User).filter_by(username=’abc’).delete()
user = session.query(User).filter_by(username=’abc’).first()
session.delete(user)
删除同样有像修改一样的 synchronize_session 参数的问题, 影响当前会话的状态.
3.6. JOIN
SQLAlchemy 可以很直观地作 join 的支持:
r = session.query(Blog, User).join(User, Blog.user == User.id).all()
for blog, user in r:
print blog.id, blog.user, user.id
r = session.query(Blog, User.name, User.username).join(User, Blog.user == User.id).all()
print r