ORM操作
- 数据库数据类型:数字、字符串、时间、二进制,无布尔值
ORM分类
db first
(1)先登录数据库,通过命令创建表结构及对应关系,
(2)再通过工具连接上数据库,通过点操作,通过表结构生成类,不用写sql语句
code first(主流)
通过类创建数据库,即转成sql数据,执行create
(1)先写类
(2)通过类,创建表结构
例如:Django
- 使用场景
- 根据类自动创建数据库表
- 根据类对数据库中的数据,进行各种操作
创建数据库表结构流程
-
写类
app02中的models.py # 创建的数据库表单名:app02_userinfo class UserInfo(models.Model): # 默认创建ID列,自增, 主键 # 用户名列,字符串类型,指定长度 username = models.CharField(max_length=32) #字符长度 password = models.CharField(max_length=64)
-
注册app
工程中的settings.py INSTALLED_APPS中添加app命令,例如 INSTALLED_APPS = [ ‘django.contrib.admin‘, ‘django.contrib.auth‘, ‘django.contrib.contenttypes‘, ‘django.contrib.sessions‘, ‘django.contrib.messages‘, ‘django.contrib.staticfiles‘, ‘app02‘, ]
-
根据情况配置使用数据库
默认数据库(无需修改) DATABASES = { ‘default‘: { ‘ENGINE‘: ‘django.db.backends.sqlite3‘, ‘NAME‘: os.path.join(BASE_DIR, ‘db.sqlite3‘), } } 修改数据库方式,数据名(dbname)需要自己创建 DATABASES = { ‘default‘: { ‘ENGINE‘: ‘django.db.backends.mysql‘, ‘NAME‘:‘dbname‘, ‘USER‘: ‘root‘, ‘PASSWORD‘: ‘xxx‘, ‘HOST‘: ‘‘, ‘PORT‘: ‘‘, } } 注:Django默认使用MySQLdb模块连接mysql数据库,但python 3.x中无该模块 需要改为pymysql:在project同名文件夹下的__init__.py文件中添加代码如下: import pymysql pymysql.install_as_MySQLdb()
-
执行命令,生成表结构
- python manage.py makemigrations
- python manage.py migrate
基本操作
-
增
方式一: models.UserInfo.objects.create(username=‘root‘, password=‘123‘) 方式二: dict_user = {‘username‘: ‘Lucy‘, ‘password‘: ‘123‘} models.UserInfo.objects.create(**dict_user) 方式三: obj = models.UserInfo(username=‘Tom‘, password=‘123‘) obj.save()
-
删
models.UserInfo.objects.filter(username=‘Tom‘).delete() models.UserInfo.objects.filter(id=1).delete() models.UserInfo.objects.all().delete()
-
改
models.UserInfo.objects.all().update(password=999) models.UserInfo.objects.filter(id=7).update(password=666)
-
查
-
单表
select * from tb where id>1 # 对应关系 modles.tb.objects.filter(id__gt=1) #id>1 modles.tb.objects.filter(id=1) modles.tb.objects.filter(id__lt=1) # id<1 modles.tb.objects.filter(id__gte=1) # id>=1 modles.tb.objects.filter(id__lte=1) # id<=1 # result的类型是QuerySet,是Django提供的,类似列表 # 全部 result = models.UserInfo.objects.all() # 查看sql语句 print(result.query) # 过滤全部满足条件的 result = models.UserInfo.objects.filter(username=‘Tom‘) for item in result: print(item.id, item.username, item.password) # 取第一个元素,没有为None obj1 = models.UserInfo.objects.filter(username="root", password="999").first() # 仅获取一条信息,但id不存在,会报错 models.UserInfo.objects.get(id=nid) # 统计个数 obj2 = models.UserInfo.objects.filter(username="root", password="999").count() # QuerySet类型,元素是对象 v1 = models.Business.objects.all() # QuerySet类型,元素是字典 v2 = models.Business.objects.all().values(‘id‘, ‘name‘) # QuerySet类型,元素是元组 v3 = models.Business.objects.all().values_list(‘id‘, ‘name‘)
-
跨表
-
点操作
- 应用场景:获取到QuerySet对象后的操作
-
双下划线操作
- 应用场景:在获取QuerSet对象前的操作,及写在models.Host.objects.xxx 上
QuerySet类型,元素是对象,跨表通过点方式
v1 = models.Host.objects.all() print(v1[0].nid, v1[0].port, v1[0].b_id, v1[0].b.name)
QuerySet类型,元素是字典,跨表通过双下划线
v2 = models.Host.objects.all().values(‘hostname‘, ‘b__name‘) print(v2[0][‘hostname‘], v2[0][‘b__name‘])
QuerySet类型,元素是元组
v3 = models.Host.objects.all().values_list(‘nid‘, ‘hostname‘, ‘b_id‘, ‘b__name‘) for row in v3: print(row[0], row[1], row[2], row[3])
-
-
操作表结构
-
修改表结构
(1)username = models.CharField(max_length=32) 修改为
username = models.CharField(max_length=64)
(2)再执行以下两条命令,重新生成表结构
- python manage.py makemigrations
- python manage.py migrate
注:改小会存在数据丢失风险
-
添加表结构
方式一: (1)email = models.CharField(max_length=64) (2)python manage.py makemigrations 选择1,输入默认值 (3)python manage.py migrate 方式二:(指定默认为NULL) (1)gender = models.CharField(max_length=64, null=True) (2)python manage.py makemigrations (3)python manage.py migrate 方式三:(指定默认值) (1)name_en = models.CharField(max_length=64, default=‘RDD‘) (2)python manage.py makemigrations (3)python manage.py migrate
-
删除表结构
(1)# gender = models.CharField(max_length=64, null=True) (2)python manage.py makemigrations (3)python manage.py migrate
字段类型
-
数据库常见类型:字符串、数字、时间、二进制
-
EmailField、URLField、GenericIPAddressField等类型
- 本质:字符串
- Django特有
- 例如: email = models.EmailField(max_length=64)
- 用途:Django后台管理时,使用,检测数据合法性
-
AutoField类型,用于自增
- uid = models.AutoField(primary_key=True)
字段参数
null -> db是否可以为空
default -> 默认值
primary_key -> 主键
db_column -> 列名
db_index -> 索引
unique -> 唯一索引
unique_for_date 数据库中字段【日期】部分是否可以建立唯一索引
unique_for_month 数据库中字段【月】部分是否可以建立唯一索引
unique_for_year 数据库中字段【年】部分是否可以建立唯一索引
auto_now_add -> 创建时,自动生成时间
例如
app的views.py
def login(request):
models.UserGroup.objects.create(caption="monitor")
app的models.py
class UserGroup(models.Model):
uid = models.AutoField(primary_key=True)
caption = models.CharField(max_length=32)
ctime = models.DateTimeField(auto_now_add=True, null=True)
uptime = models.DateTimeField(auto_now=True, null=True)
auto_now -> 更新时,自动更新为当前时间
例如:
app的models.py
uptime = models.DateTimeField(auto_now=True, null=True)
app的views.py
# 这种方式不支持
obj = UserGroup.objects.filter(id=1).update(caption=‘CEO‘)
# 这种方式:OK
obj = models.UserGroup.objects.filter(uid=1).first()
obj.caption = "CEO"
obj.save()
choices -> django admin中显示下拉框,避免连表查询
例如:
app的models.py
class UserInfo(models.Model):
# 默认创建ID列,自增, 主键
# 用户名列,字符串类型,指定长度
# 字符串、数字、时间、二进制
username = models.CharField(max_length=64)
password = models.CharField(max_length=64)
email = models.EmailField(max_length=64, null=True)
user_type_choices = (
(1, "超级用户"),
(2, "管理员"),
(3, "普通用户"),
)
user_type_id = models.IntegerField(choices=user_type_choices, default=3)
blank -> django admin是否可以为空
verbose_name -> django admin显示字段中文
editable -> django admin是否可以被编辑
error_messages -> 错误信息欠
help_text -> django admin提示
validators -> django form ,自定义错误信息(欠)