创建ROM映射
ORM:Object Relationship Mapping
创建一个类,一个类对应了一个数据库中的一张表,类的数据属性对应了表中的字段名,这个类称为映射类。
根据映射类创建出一个一个的对象,每个对象对应了表中的一条实际的数据。
1.主动创建映射
Class Users(Base):
name = ''
age = ''
obj1 = User('zhangsan', 18)
obj2 = User('lisi', 20)
Users
表中的内容
id | name | age |
---|---|---|
1 | zhangsan | 18 |
2 | lisi | 20 |
使用Declarative
系统映射的类是根据基类定义的,换句话说每个映射类需要继承这个基类。
我们使用declarative_base()
函数可以创建这个基类,如下所示:
# -*- coding: utf-8 -*-
# @File : db.py
# @author: 北极的三哈
# @email : Flymeawei@163.com
# @Time : 2022/12/17 0:06
""""""
from sqlalchemy import create_engine, Column, Integer, String, Float, ForeignKey
from sqlalchemy.ext.declarative import declarative_base
engine = create_engine('mysql+pymysql://root:root@localhost:3306/flask_db?charset=utf8mb4', echo=True)
# 1.创建基类(所有ORM中的o,对象模型的超级父类
Base = declarative_base(engine)
# 2.定义Python类和表的映射
# 用‘Base’类作为基类来写自己的ORM类
# 要定义`__tablename__`类属性,来指定这个模型映射到数据库中的表名。
"""
class Person(Base):
__tablename__ = 't_person'
"""
# 3.创建属性性来映射到表中的字段,
# 所有需要映射到表中的属性都应该为Column类型:
class Person(Base):
__tablename__ = 't_person'
# 在这个ORM模型中创建一些属性,来跟表中的字段进行 一一 映射。
# 这些属性必须是sqlalchemy给我们提供好的数据类型
id = Column(name='id', type_=Integer, primary_key=True, autoincrement=True)
name = Column(name='name', type_=String(255))
age = Column(name='age', type_=Integer)
address = Column(String(255))
country = Column(String(50))
# 4.使用`Base.metadata.create_all()`来将模型映射到数据库中。
# 5. 一旦使用`Base.metadata.create_all()`将模型映射到数据库中后,即使改变了模型的字段,也不会重新映射了。
# 删除表
Base.metadata.drop_all()
# 创建表
Base.metadata.create_all()
SQLAlchemy常用数据类型
Integer
:整形,映射到数据库中是int类型。Float
:浮点类型,映射到数据库中是float类型。他占据的32位。Double
:双精度浮点类型,映射到数据库中是double类型,占据64位 (SQLALCHEMY中没有)。String
:可变字符类型,映射到数据库中是varchar类型.Boolean
:布尔类型,映射到数据库中的是tinyint类型。DECIMAL
:定点类型。是专门为了解决浮点类型精度丢失的问题的。在存储钱相关的字段的时候建议大家都
使用这个数据类型。并且这个类型使用的时候需要传递两个参数,第一个参数是用来标记这个字段总能能存
储多少个数字,第二个参数表示小数点后有多少位。Enum
:枚举类型。指定某个字段只能是枚举中指定的几个值,不能为其他值。在ORM模型中,使用Enum来
作为枚举。Date
:存储时间,只能存储年月日。映射到数据库中是date类型。在Python代码中,可以使用
datetime.date 来指定。DateTime
:存储时间,可以存储年月日时分秒毫秒等。映射到数据库中也是datetime类型。在Python代码
中,可以使用 datetime.datetime 来指定。Time
:存储时间,可以存储时分秒。映射到数据库中也是time类型。在Python代码中,可以使用
datetime.time 来创建值。Text
:存储长字符串。一般可以存储6W多个字符。如果超出了这个范围,可以使用LONGTEXT类型。映射到数据库中就是text类型。LONGTEXT
:长文本类型,映射到数据库中是longtext类型。
注意:这个类型属于Mysql
方言里面的
# 定义一个枚举类
class TagEnum(enum.Enum):
python = "PYHTON"
flask = "FLASK"
django = "DJANGO"
# 创建一个ORM模型 说明基于sqlalchemy 映射到mysql数据库的常用字段类型有哪些?
class News(Base):
__tablename__ = 'news'
id = Column(Integer, primary_key=True, autoincrement=True)
price1 = Column(Float) # 存储数据时存在精度丢失问题
price2 = Column(DECIMAL(10, 4))
title = Column(String(50))
is_delete = Column(Boolean)
tag1 = Column(Enum('PYTHON', 'FLASK', 'DJANGO')) # 枚举常规写法
tag2 = Column(Enum(TagEnum)) # 枚举另一种写法
create_time1 = Column(Date)
create_time2 = Column(DateTime)
create_time3 = Column(Time)
content1 = Column(Text)
content2 = Column(LONGTEXT)
# 使用`Base.metadata.create_all()`来将模型映射到数据库中。
Base.metadata.drop_all()
Base.metadata.create_all()
# 新增数据到表news中
a1 = News(price1=1000.0078, price2=1000.0078, title='测试数据',
is_delete=True, tag1="PYTHON", tag2=TagEnum.flask,
create_time1=date(2018, 12, 12),
create_time2=datetime(2019, 2, 20, 12, 12, 30),
create_time3=time(hour=11, minute=12, second=13),
content1="hello", content2="hello hi nihao")
Column常用参数
primary_key
:True设置某个字段为主键。autoincrement
:True设置这个字段为自动增长的。default
:设置某个字段的默认值。在发表时间这些字段上面经常用。nullable
:指定某个字段是否为空。默认值是True,就是可以为空。unique
:指定某个字段的值是否唯一。默认是False。onupdate
:在数据更新的时候会调用这个参数指定的值或者函数。在第一次插入这条数据的时候,不会用onupdate
的值,只会使用default的值。常用于是update_time
字段(每次更新数据的时候都要更新该字段值)。name
:指定ORM模型中某个属性映射到表中的字段名。如果不指定,那么会使用这个属性的名字来作为字段名。如果指定了,就会使用指定的这个值作为表字段名。这个参数也可以当作位置参数,在第1个参数来指定。
案例:
class News(Base):
__tablename__='news'
id = Column(Integer,primary_key=True,autoincrement=True)
price1 = Column(Float) #存储数据时存在精度丢失问题
price2 = Column(DECIMAL(10,4))
title = Column(String(50))
is_delete =Column(Boolean)
tag1 =Column(Enum('PYTHON','FLASK','DJANGO')) #枚举常规写法
2.自动从数据库中映射
# -*- coding: utf-8 -*-
"""
@file: 自动创建OPM映射.py
@author: 北极的三哈
@time: 2022/12/22 20:30
@software: PyCharm2022.3
"""
from sqlalchemy import *
from sqlalchemy.ext.automap import automap_base
# 创建数据库引擎
engine = create_engine('mysql+pymysql://root:root@localhost:3306/flask_db?charset=utf8mb4', echo=True)
# 自动映射
Base = automap_base()
Base.prepare(engine)
# 获取所有表的映射
# 注意:自动映射的表名和类名一样
tables = Base.classes.keys()
print(tables)
# 可重新定义类名
Person = Base.classes.t_person
# 得到桑倩类中所有的属性
keys = Person.__table__.columns.keys()
print(keys)