Day051 ORM _SQLALchemy

一、ORM介绍

1. ORM:Object Relationship Mapping

对象关系映射(Object Relational Mapping,简称ORM)是通过使用描述对象和数据库之间映射的元数据,将面向对象语言程序中的对象自动持久化到关系数据库中。

2. 大白话:对象模型与数据库表的映射


python代码 和SQL代码角度理解:

        class Person(object):
    name = 'xx'
    age = 18
    country ='xx'

# Person类 -> 数据库中的一张表
# Person类中的属性  -> 数据库中一张表字段
# Person类的一个对象 -> 数据库中表的一条数据

# p = Person('xx',xx)
# p.save()

#create table person(name varchar(200),age int,country varchar(100))
      

SQLAlchemy

随着项目的越来越大,采用写原生SQL的方式在代码中会出现大量重复的SQL语句,那么,问题,就出现了:

1.SQL语句重复利用率不高,越复杂的SQL语句条件越多,代码越长,会出现很多相近的SQL语句。

2.很多SQL语句 是在业务逻辑中拼接出来的,如果数据库需要更改,就要去修改这些逻辑,这会很容易漏掉对某些SQL语句的修改。

3.写SQL时容易忽略web安全问题,造成隐患。


ORM,全称Object Relational Mapping,中文名叫做对象关系映射通过ORM我们可以通过类的方式去操作数据库而不用再写原生的SQL语句,通过把表映射成类,把行作为实例,把字段作为属性,ORM在执行对象操作的时候最终还是会把对象的操作转换为数据库的原生语句,但使用ORM有许多优点:

1.易用性:使用ORM做数据库开发可以有效减少重复SQL语句的概率,写出来的模型也更加直观、清晰

2.性能损耗小:ORM转换成底层数据库操作指令确实会有一些开销。但是从实际情况来看,这种性能损耗很少(不足5%),只要不是针对性能有严苛的要求,综合考虑开发效率、代码阅读性,带来的好处远大于性能损耗,而且项目越大作用越明显。

3.设计灵活:可以轻松的写出复杂的查询。

4.可移植性:SQLAlchemy封装了底层的数据库实现,支持多个关系数据库引擎,包括流行的Mysql、PostgreSQL和SQLite,可以非常轻松的切换数据库。


二、定义ORM模型并将其映射到数据库中

1. 用`declarative_base`根据`engine`创建一个ORM基类。

           from sqlalchemy.ext.declarative import declarative_base

   engine = create_engine(DB_URI)
   Base = declarative_base(engine)
      


2. 用这个`Base`类作为基类来写自己的ORM类。要定义`__tablename__`类属性,来指定这个模型映射到数据库中的表名。

        class Person(Base):
    __tablename__ ='person'
      


3. 创建属性来映射到表中的字段,所有需要映射到表中的属性都应该为Column类型:

        class Person(Base):
    __tablename__ ='person'
    #2.在这个ORM模型中创建一些属性,来跟表中的字段进行 一一 映射。这些属性必须是sqlalchemy给我们提供好的数据类型
    id = Column(Integer,primary_key=True,autoincrement=True)
    name = Column(String(50))
    age = Column(Integer)
    country = Column(String(50))
      


4. 使用`Base.metadata.create_all()`来将模型映射到数据库中。

         Base.metadata.create_all()
      

5. 一旦使用`Base.metadata.create_all()`将模型映射到数据库中后,即使改变了模型的字段,也不会重新映射了。


三、SQLAlchemy对数据的增删改查操作

用session做数据的增删改查操作:

1. 构建session对象:所有和数据库的ORM操作都必须通过一个叫做`session`的会话对象来实现,通过以下代码来获取会话对象:

        from sqlalchemy.orm import sessionmaker
engine = create_engine(DB_URI)
Base = declarative_base(engine)
session = sessionmaker(engine)()
      


2. 添加对象:

* 创建对象,也即创建一条数据:

         p1 = Person(name='momo1',age=19,country='china')
      

* 将这个对象添加到`session`会话对象中:

              session.add(p1)
      

* 将session中的对象做commit操作(提交):

              session.commit()
      

* 一次性添加多条数据:

        p1 = Person(name='momo1',age=19,country='china')
p2 = Person(name='momo2',age=20,country='china')
session.add_all([p1,p2])
session.commit()
      


3. 查找对象:

            # 查找某个模型对应的那个表中所有的数据:
    all_person = session.query(Person).all()
    # 使用filter_by来做条件查询
    all_person = session.query(Person).filter_by(name='momo1').all()
    # 使用filter来做条件查询
    all_person = session.query(Person).filter(Person.name=='momo1').all()
    # 使用get方法查找数据,get方法是根据id来查找的,只会返回一条数据或者None
    person = session.query(Person).get(primary_key)
    # 使用first方法获取结果集中的第一条数据
    person = session.query(Person).first()
      

4. 修改对象:首先从数据库中查找对象,然后将这条数据修改为你想要的数据,最后做commit操作就可以修改数据了。

         person = session.query(Person).first()
 person.name = 'lulu'
 session.commit()
      


5. 删除对象:将需要删除的数据从数据库中查找出来,然后使用`session.delete`方法将这条数据从session中删除,最后做commit操作就可以了。

        person = session.query(Person).first()
session.delete(person)
session.commit()
      


四、SQLAlchemy常用数据类型:


1. Integer:整形,映射到数据库中是int类型。

2. Float:浮点类型,映射到数据库中是float类型。他占据的32位。

3. Double:双精度浮点类型,映射到数据库中是double类型,占据64位 (SQLALCHEMY中没有)。

4. String:可变字符类型,映射到数据库中是varchar类型.

5. Boolean:布尔类型,映射到数据库中的是tinyint类型。

6. DECIMAL:定点类型。是专门为了解决浮点类型精度丢失的问题的。在存储钱相关的字段的时候建议大家都使用这个数据类型。并且这个类型使用的时候需要传递两个参数,第一个参数是用来标记这个字段总能能存储多少个数字,第二个参数表示小数点后有多少位。

7. Enum:枚举类型。指定某个字段只能是枚举中指定的几个值,不能为其他值。在ORM模型中,使用Enum来作为枚举,示例代码如下:

            class News(Base):
        __tablename__ = 'news'
        tag = Column(Enum("python",'flask','django'))
      


在Python3中,已经内置了enum这个枚举的模块,我们也可以使用这个模块去定义相关的字段。示例代码如下:

            class TagEnum(enum.Enum):
        python = "python"
        flask = "flask"
        django = "django"


    class News(Base):
        __tablename__ = 'news'
        id = Column(Integer,primary_key=True,autoincrement=True)
        tag = Column(Enum(TagEnum))


    news = News(tag=TagEnum.flask)
      

8. Date:存储时间,只能存储年月日。映射到数据库中是date类型。在Python代码中,可以使用`datetime.date`来指定。

9. DateTime:存储时间,可以存储年月日时分秒毫秒等。映射到数据库中也是datetime类型。在Python代码中,可以使用`datetime.datetime`来指定。

10. Time:存储时间,可以存储时分秒。映射到数据库中也是time类型。在Python代码中,可以使用`datetime.time`来至此那个。示例代码如下:

            class News(Base):
        __tablename__ = 'news'
        create_time = Column(Time)


    news = News(create_time=time(hour=11,minute=11,second=11))
      

11. Text:存储长字符串。一般可以存储6W多个字符。如果超出了这个范围,可以使用LONGTEXT类型。映射到数据库中就是text类型。

12. LONGTEXT:长文本类型,映射到数据库中是longtext类型。


五、Column常用参数:


1. primary_key:True设置某个字段为主键。

2. autoincrement:True设置这个字段为自动增长的。

3. default:设置某个字段的默认值。在发表时间这些字段上面经常用。

4. nullable:指定某个字段是否为空。默认值是True,就是可以为空。

5. unique:指定某个字段的值是否唯一。默认是False。

6. onupdate:在数据更新的时候会调用这个参数指定的值或者函数。在第一次插入这条数据的时候,不会用onupdate的值,只会使用default的值。常用于是`update_time`字段(每次更新数据的时候都要更新该字段值)。

7. name:指定ORM模型中某个属性映射到表中的字段名。如果不指定,那么会使用这个属性的名字来作为字段名。如果指定了,就会使用指定的这个值作为表字段名。这个参数也可以当作位置参数,在第1个参数来指定。

            title = Column(String(50),name='title',nullable=False)
    title = Column('my_title',String(50),nullable=False)
      

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值