SQLAlchemy使用

6 篇文章 0 订阅
2 篇文章 0 订阅

SQLAlchemy

原文地址:Object Relational Tutorial

获得当前版本

sqlalchemy.__version__

Connecting

from sqlalchemy import create_engine
engine = create_engine('',echo=True)

Declare a Mapping

定义基类

from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()

定义Model类

from sqlalchemy import Sequence
class User(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)

在数据库中创建表

>>> Base.metadata.create_all(engine)

Create an Instance of Mapped Class

user = User(name='ed', fullname='Ed Jones', password='abc')

Creating a Session

from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind=engine)

或则先创建session类,再绑定engine

Session = sessionmaker()
Session.configure(bind=engine)

实例化

session = Session()

Adding and Updating Object

session.add(user)   # user状态为pending,如果query查询user,就会flush到数据库,commit也会flush到数据库
session.add_all([user1, user2,...])
session.new  # 获得所有pending的对象
# 修改
user.password = 'zyx'
session.dirty  # 获得未提交的脏数据
# 提交数据
session.commit()

Rolling Back

session.rollback()  # 事务回滚

Querying

session.query(User).order_by(User.id)  # Talle
query(User.name, User.fullname)        # Column
>>> for row in session.query(User, User.name).all():
...    print(row.User, row.name)       # namedtuple
>>> for row in session.query(User.name.label('name_label')).all():
...    print(row.name_label)           # 单独的column设置label

>>> from sqlalchemy.orm import aliased   
>>> user_alias = aliased(User, name='user_alias')  # 设置别名
>>> for row in session.query(user_alias, user_alias.name).all():
...    print(row.user_alias)
LIMIT and OFFSET
session.query(User).order_by(User.id)[1:3]
WHERE
session.query(User.name).filter_by(fullname='Ed Jones')  # 关键字传参
session.query(User.name).filter(User.fullname=='Ed Jones')

Common Filter Operators:

   * equels: User.name == 'ed'
   * not equels: User.name != 'ed
   * LIKE: User.name.like('%ed%')
   * ILIKE: User.name.ilike('%ed%')    # 忽略大小写
   * IN: User.name.in_(['ed', 'wendy'])
        `User.name.in_(session.query(User.name).filter(User.name.like('%ed%')))`
   * NOT IN: ~User.name.in_(['ed', 'wendy'])
   * IS NULL: User.name == None
   * IS NOT NULL: User.name != None
   * AND: 
    	`from sqlalchemy import and_`
        `and_(User.name == 'ed', User.fullname=='Ed Jones')`
        或者:
        query.filter(User.name == 'ed', User.fullname == 'Ed Jones')
        query.filter(User.name == 'ed').filter(User.fullname == 'Ed Jones')
   * OR: from sqlalchemy import or_
        or_(User.name == 'ed', User.name == 'wendy')
   * MATCH: User.name.match('wendy')    # 有些数据库不支持,如SQLite
Returning List and Scalars
all()
first()
one() only one, 两个异常,MultipleResultsFound, NoResultFound
one_or_none() 一个异常,MultipleResultsFound,没有返回None
scalar() 调用one(), 成功后返回行的第一列,多为id
Using Textual SQLAlchemy 使用原生sql语句
>>> from sqlalchemy import text
SQL>>> for user in session.query(User).\
...             filter(text("id<224")).\
...             order_by(text("id")).all():
...     print(user.name)
使用parameters,colon:做占位符
>>> session.query(User).filter(text("id<:value and name=:name")).\
...     params(value=224, name='fred').order_by(User.id).one()
<User(name='fred', fullname='Fred Flinstone', password='blah')>

使用columns对应TextClause到ORM column

>>> stmt = text("SELECT name, id, fullname, password "
...             "FROM users where name=:name")
>>> stmt = stmt.columns(User.name, User.id, User.fullname, User.password)
SQL>>> session.query(User).from_statement(stmt).params(name='ed').all()
Counting
count()   # 返回query的行数,并不适合使用
>>> from sqlalchemy import func
>>> session.query(func.count(User.name), User.name).group_by(User.name).all()
[(1, u'ed'), (1, u'fred'), (1, u'mary'), (1, u'wendy')]   # 使用聚合函数
# SELECT count(*) FROM table
session.query(func.count('*')).select_from(User).scalar()
session.query(func.count(User.id)).scalar()  # 使用id(唯一)省略,select_from

Building a Relationship

>>> from sqlalchemy.orm import relationship
>>> class Address(Base):
...     __tablename__ = 'addresses'
...     id = Column(Integer, primary_key=True)
...     email_address = Column(String, nullable=False)
...     user_id = Column(Integer, ForeignKey('users.id'))
...
...     user = relationship("User", back_populates="addresses")

更多Basic Relationship Patterns

Querying with Joins

query = session.query(User, Address).select_from(Address).join(User)

select_from定义从哪一张表开始join,默认是从query中最左边的开始join

query.join(Address, User.id==Address.user_id)  

指定ON条件,不指定默认使用外键

Using Aliases

>>> from sqlalchemy.orm import aliased
>>> adalias1 = aliased(Address)
>>> adalias2 = aliased(Address)
SQL>>> for username, email1, email2 in \
...     session.query(User.name, adalias1.email_address, adalias2.email_address).\
...     join(adalias1, User.addresses).\
...     join(adalias2, User.addresses).\
...     filter(adalias1.email_address=='jack@google.com').\
...     filter(adalias2.email_address=='j25@yahoo.com'):
...     print(username, email1, email2)
jack jack@google.com j25@yahoo.com

一张表被join两次,使用别名,获得有两个email地址分别为jack@google.com和j25@yahoo.com的user

Using Subqueries

Using EXISTS

Common Relationship Operators

==
!=
== None
contains
any
has
with_parent

Deleting

session.delete(item)
session.close() -> ROLLBACK
Cascade (ORM level)
addresses = relationship("Address", back_populates='user', cascade="all, delete-orphan")

Many To Many Relationship

User.posts = relationship(BlogPost, back_populates=“author”, lazy=“dynamic”)
懒加载

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值