sqlalchemy使用上的小tips


sqlalchemy object序列化为json

灵感来源于 Django REST framework

posts = Post.query.all()
serializer = Seralizer(posts,many=True)
data = serializer.data

多个实例

单个实例

post = Post.query.first()
serializer = Seralizer(post,many=False)
data = serializer.data

排除字段

serializer = Seralizer(post,exclude=['title'])

仅包括字段

serializer = Seralizer(post,include=['title'])

关系查询深度

serializer = Seralizer(post,depth=3)
  • depth

    默认为2

增加一些自定义的函数

serializer = Serializer(post,extra=['get_post_count'])

Post

class Post(Model):
    ......
    def get_post_count(self):
        return 11

可传递参数的函数

class PostSerializer(Serializer):
    count = Field(source = 'get_post_count',args={'name':'hello'},default=20)
    class Meta:
        include = []
        depth = 2
        include = []
        exclude = []
        extra = ['count']

像django orm一样使用sqlalchemy

djang orm与sqlalchemy相比,为什么很多人都认为django orm更好用,大概就是因为django orm更方便

基本查询(已实现)

  • gt
  • lt
  • lte
  • gte
  • contains
  • in
  • exact
  • iexact
  • startswith
  • istartswith
  • iendswith
  • endswith
  • isnull
  • range
  • year
  • month
  • day

示例:

Post.query.filter_by(title__contains = 'sql').all()
Post.query.exclude_by(title__contains = 'sql').all()

关系查询

Post.query.filter_by(tags__name__contains = 'sql').all()

其它

Post.query.filter_by(tags__name__contains = 'sql').or(Post.id == 1,Post.id == 2).all()
Post.query.filter_by(tags__name__contains = 'sql').and(Post.id == 1,Post.id == 2).all()
Post.query.filter_by(tags__name__contains = 'sql').exists()
Post.query.load_only('title')

去掉一些sqlalchemy的重复工作

flask-sqlalchemy为例,通过继承 models.py 中的Mixin,就可以去除部分重复工作

ModelMixin

自增ID -- id

post = Post(·····)
post.save() # 保存
post.delete() # 保存

批量操作

  • bulk_insert
  • bulk_update
  • bulk_save

ModelTimeMixin

增加两字段

  • created_at

    数据创建时间

  • updated_at

    数据更新时间

ModelUserMixin

关联用户表,与User表现为多对一关系(即一个用户有多个post)

class Post(ModelUserMixin, Model):

    user_related_name = 'posts'
    titile = ...

There are comments.

  • sqlalchemy序列化为json


    为什么需要这个需求?

    sqlalchemy 是个好东西,虽然其文档犹如/老太婆的裹脚布--又臭又长/,饱受诟病

    使用 restful 时sqlalchemy返回的是一个 object 类,假设前后端分离,前端无法处理

    如何实现?

    直接给出代码

    class Serializer(object):
    
        def __init__(self, instance, many=False, include=[], exclude=[], depth=2):
            self.instance = instance
            self.many = many
            self.include = include
            self …

  • sqlalchemy常见数据类型及配置


    类型名称python类型描述
    Integerint常规整形,通常为32位
    SmallIntegerint短整形,通常为16位
    BigIntegerint或long精度不受限整形
    Floatfloat浮点数
    Numericdecimal.Decimal定点数
    Stringstr可变长度字符串
    Textstr可变长度字符串,适合大量文本
    Unicodeunicode可变长度Unicode字符串
    Booleanbool布尔型
    Datedatetime.date日期类型
    Timedatetime.time时间类型
    Intervaldatetime.timedelta时间间隔
    Enumstr字符列表 …
  • sqlalchemy学习(一)


    sqlalchemy

    系统的学一下sqlalchemyA,不过没有中文文档,只能用我的渣英文能力慢慢看原文档了

    数据库连接

    >>> from sqlalchemy import create_engine
    >>> engine = create_engine('sqlite:///:memory:', echo=True)
    

    echo为True输出日志

    各种数据库连接方式

    dialect+driver://username:password@host:port/database
    
    1. Postgresql

      # default
      engine = create_engine('postgresql://scott:tiger@localhost/mydatabase')
      # psycopg2
      engine = create_engine('postgresql+psycopg2://scott:tiger@localhost/mydatabase')
      # pg8000
      engine = create_engine('postgresql+pg8000://scott:tiger …
  • flask-sqlalchemy使用


    简单的例子这里已经有了
    中文 这里记录一下平时我遇到的一些问题

    一对多

    需求:一个问题对应多个回复
    下面给出代码(字段不完整)

    class Questions(db.Model):
        __tablename__ = 'questions'
        id = db.Column(db.Integer, primary_key=True)
        title = db.Column(db.String(50), nullable=False)
        content = db.Column(db.Text, nullable=False)
    
        def __init__(self,title,content):
            self.title = title
            self.content = content …
  • 关于sqlalchemy的desc


    也就是降序排序

    简单使用

    questions = Questions.query.order_by(Questions.time.desc()).all()

    设置默认排序

    如果几乎所有的questions都是按照时间降序排序,总不能每一条语句都加上order_by(Questions.time.desc())
    所以设置默认排序是有效的

    class Questions(db.Model):
        __tablename__ = 'questions'
        id = db.Column(db.Integer, primary_key=True)
        title = db.Column(db.String(50), nullable=False)
        content = db.Column(db.Text, nullable=False)
        time = db.Column …
  • 关于sqlalchemy的filter_by与filter


    都可看做是where但用法不一样

    filter_by

    question = Questions.query.filter_by(id=1).first()
    

    filter

    question = Questions.query.filter(Questions.id==1).first()
    

    其实就是===还有是否带类名的区别
    如果要select * from questions where id < 5
    这时只能使用filter

    questions = Questions.query.filter(Questions.id < 5).all()
    

    多个条件

    question = Questions.query.filter_by(name='hello',id=5).first()
    # 或者 …