您的位置:首页 > 数据库 > SQL

Django遇到的问题----mysql db与models反复修改所牵扯的问题

2018-01-07 19:41 465 查看
1、Django中models.py进行数据库的同步操作:

python manage.py makemigrations  [appname]

python manage.py makemigrations saler这步相当于生成数据库操作日志,在创建app时在文件夹下会自动生成migrations文件夹,当数据库文件model.py发生变化后,执行这个命令都会在这个文件夹内生成一个同步的文件表明对数据库做了什么样的操作。这样方便数据恢复。
python manage.py migrate  [appname]

python manage.py migrate saler这一步就是数据库同步操作,执行后会根据上一步生成的文件记录对数据库进行相应的操作,当然这中间经历了比如转化sql语句等操作,我们不需要过多了解这其中细节,django会为我们自动完成。

2、Django中mysql文件生成models:

python manage.py inspectdb >filename  将数据库以数据模型类的形式生成代码导入到某个文件。

python manage.py inspectdb >saler/models.py
注意:mysql文件生成的models.py ,在修改models.py时,还想执行1、中的命令来同步数据库文件是不行的。因为,mysql文件生成的models.py 在每个类中,

class Venfac(models.Model):
FacId = models.BigAutoField(db_column='FacId', primary_key=True) # Field name made lowercase.
FacName = models.CharField(db_column='FacName', max_length=20) # Field name made lowercase.
FacIntro = models.CharField(db_column='FacIntro', max_length=255) # Field name made lowercase.
class Meta:
managed = False
db_table = 'vd_venfac'managed=False;只有将其删除,或者改为True,models.py中的修改才能同步到数据库表中。
3、其他数据命令:python manage.py flush   清除数据库中的数据

python manage.py dbshell   进入sql语句交互

python manage.py sqlmigrate  appname migrate_num 显示对应日志表的sql语句。

更多命令使用:https://docs.djangoproject.com/en/1.8/ref/django-admin/

4、假如数据库中已经有某sql文件,并且有相应的记录。当你在models.py某个类中添加了一两个字段field,并且想执行1、来同步一下models中的field到数据库表中时,会出现:字段修改属性发生错误

>python manage.py makemigrations

You are trying to add a non-nullable field 'price_monthly' to product without a default; we can't do that (the database needs something to populate existing rows).

Please select a fix:

 1) Provide a one-off default now (will be set on all existing rows)

 2) Quit, and let me add a default in models.py

Select an option:

{这个可能是之前已创建了表中的一条记录,之后模型中增加了一个非空的字段,但是原来已经存在的记录没有这个值}

解决方法:

在类中添加允许为空或者添加默认值


或者:

删除所有migrate文件(不用移除整个文件夹),然后重来,重新执行1、同步数据库。

5、怎么在Django后台筛选出某列中不含重复项的行?

解决方案:利用.values("列名").distinct();找出某列不重复的值的集合,注意其他列都没了。





只要venid=1的所有产品记录:





对应的结果为:



<
4000
/p>
6、异常:

filter不用写try 、catch

vendings=Vendings.objects.filter(Bussin=bussiness)#不存在该类记录时,不会出现异常。返回<QuerySet []>

二、知识点的补充:

摘自:http://blog.csdn.net/lvze0321/article/details/53321728

Models.py数据操作

 

在模块编写上官方提供了教程https://docs.djangoproject.com/en/dev/topics/db/models/,但是官方教程很多地方不太详细。我们分几部分来进行讲解。

 

模块引用

 

在models.py中和模型相关的引用主要有以下两个(其他的引用主要看具体编写需求):

 

from django.db import models

这个引用相当于提供了模型建立的方法,models这个模块中包含了诸多的类一般都是和模型的构建相关。这个模块也是我们最常用的模块。

 

from django.contrib.auth.models import  [需求类]

这个引用中的models模块和上个不同,是系统为我们自动提供的,其中为我们自动编写了像用户,用户组,权限等数据类模型。在我们同步数据库的时候这个模块中的数据模型会自动同步,我们可以使用系统提供的这些模型,当我们觉得原有模型不能满足我们需求的时候可以通过这样的import引入引入具体某个数据模型类,然后进行修改。这部分内容我们在模型的高级操作中会有介绍。

 

数据模型类的编写

 

基本结构:

 

from django.db import models

 

#如果没有models.AutoField,默认会创建一个id的自增列

class userinfo(models.Model):

name = models.CharField(max_length=30)

email =models.EmailField()

memo =models.TextField()

 

这是一个最基本的数据表类,数据表类需要继承models.Model ,这其中每个属性表示一个字段Field为字段类型,字段函数内的参数是对字段的描述(大小,默认值,可否为空等)。Django的模型中几乎支持了所有的数据库数据类型,关于更多类型的讲解可以查看上面提到的官方教程,在这里为大家简单列出:

 

字段:
1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42
1、models.AutoField 自增列= int(11)

如果没有的话,默认会生成一个名称为 id 的列,如果要显示的自定义一个自增列,必须将给列设置为主键 primary_key=True。

2、models.CharField 字符串字段

必须 max_length 参数

3、models.BooleanField 布尔类型=tinyint(1)

不能为空,Blank=True

4、models.ComaSeparatedIntegerField 用逗号分割的数字=varchar

继承CharField,所以必须 max_lenght 参数

5、models.DateField 日期类型 date

对于参数,auto_now =True则每次更新都会更新这个时间;auto_now_add 则只是第一次创建添加,之后的更新不再改变。

6、models.DateTimeField 日期类型 datetime

同DateField的参数

7、models.Decimal 十进制小数类型= decimal

必须指定整数位max_digits和小数位decimal_places

8、models.EmailField 字符串类型(正则表达式邮箱)=varchar

对字符串进行正则表达式

9、models.FloatField 浮点类型= double

10、models.IntegerField 整形

11、models.BigIntegerField 长整形

integer_field_ranges ={

'SmallIntegerField':(-32768,32767),

'IntegerField':(-2147483648,2147483647),

'BigIntegerField':(-9223372036854775808,9223372036854775807),

'PositiveSmallIntegerField':(0,32767),

'PositiveIntegerField':(0,2147483647),

}

12、models.IPAddressField 字符串类型(ip4正则表达式)

13、models.GenericIPAddressField 字符串类型(ip4和ip6是可选的)

参数protocol可以是:both、ipv4、ipv6

验证时,会根据设置报错

14、models.NullBooleanField 允许为空的布尔类型

15、models.PositiveIntegerFiel 正Integer

16、models.PositiveSmallIntegerField 正smallInteger

17、models.SlugField 减号、下划线、字母、数字

18、models.SmallIntegerField 数字

数据库中的字段有:tinyint、smallint、int、bigint

19、models.TextField 字符串=longtext

20、models.TimeField 时间 HH:MM[:ss[.uuuuuu]]

21、models.URLField 字符串,地址正则表达式

22、models.BinaryField 二进制

23、models.ImageField图片

24、models.FilePathField文件
 

 

 

 

参数
1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27
1、null=True

数据库中字段是否可以为空

2、blank=True

django的Admin中添加数据时是否可允许空值

3、primary_key =False

主键,对AutoField设置主键后,就会代替原来的自增 id 列

4、auto_now 和 auto_now_add

auto_now 自动创建---无论添加或修改,都是当前操作的时间

auto_now_add 自动创建---永远是创建时的时间

5、choices

GENDER_CHOICE =(

(u'M', u'Male'),

(u'F', u'Female'),

)

gender = models.CharField(max_length=2,choices = GENDER_CHOICE)

6、max_length

7、default 默认值

8、verbose_name Admin中字段的显示名称

9、name|db_column 数据库中的字段名称

10、unique=True 不允许重复

11、db_index =True 数据库索引

12、editable=True 在Admin里是否可编辑

13、error_messages=None 错误提示

14、auto_created=False 自动创建

15、help_text 在Admin中提示帮助信息

16、validators=[]

17、upload-to
 

数据库的同步

 

当我们创建好数据类后就可以进行数据库的同步操作了。这依赖于manage.py命令。

 

1.      同步数据

在django1.7以前使用的命令是 python manage.py syncdb 但是在1.7以后就不再支持这个命令了,现在分为两步进行

 

Python manage.py makemigrations  [
1b633
appname]

这步相当生成数据库操作日志,在创建app时在文件夹下会自动生成migrations文件夹,当数据库文件model.py发生变化后,执行这个命令都会在这个文件夹内生成一个同步的文件表明对数据库做了什么样的操作。这样方便数据恢复。

 

Python manage.py migrate  [appname]

这一步就是数据库同步操作,执行后会根据上一步生成的文件记录对数据库进行相应的操作,当然这中间经历了比如转化sql语句等操作,我们不需要过多了解这其中细节,django会为我们自动完成

 

其他数据命令:

Python manage.py flush   清除数据库中的数据

Python manage.py dbshell   进入sql语句交互

Python manage.py sqlmigrate  appname migrate_num 显示对应日志表的sql语句

Python manage.py inspectdb >filename  将数据库以数据模型类的形式生成代码导入到某个文件

更多命令使用:https://docs.djangoproject.com/en/1.8/ref/django-admin/

 

当数据库的同步操作完成后可以进入数据库查看数据表发现就有我们在模型中所写的类对应的数据表了。除此之外还有一些表并不是我们写的。这是系统为我们自动生成的一些功能表。在settings中我们使用了系统自动提供的模块的引入才会产生这些数据表,具体声明在INSTALLED_APPS中,我们也可以根据自己的需求选择留下哪些表。

 

INSTALLED_APPS= [

    'django.contrib.admin',

    'django.contrib.auth',

    'django.contrib.contenttypes',

    'django.contrib.sessions',

    'django.contrib.messages',

    'django.contrib.staticfiles',

    'blog'

]

 

数据库表结构修改

 

表结构修改后,原来表中已存在的数据,就会出现结构混乱,在以前的django版本中比较麻烦。新版本的django解决了这个问题。在models更新后直接使用上面我们学习的命令进行同步即可。但是需要注意:

1、新增加的字段,设置允许为空。生成表的时候,之前数据新增加的字段就会为空。(null=True允许数据库中为空,blank=True允许admin后台中为空)

2、新增加的字段,设置一个默认值。生成表的时候,之前的数据新增加字段就会应用这个默认值

 

数据操作

 

这里先介绍数据的增删改查操作。这个操作一般在veiws文件中完成,即达到对数据库操作的目的。

 



models.UserInfo.objects.create(user='lvze',pwd='123')

或者

obj = models.UserInfo(user='lvze',pwd='123')

obj.save()

或者

dic = {'user':'lvze','pwd':'123'}

models.UserInfo.objects.create(**dic)

 



models.UserInfo.objects.filter(user='lvze').delete()

 



 

models.UserInfo.objects.filter(user='lvze').update(pwd='321')

或者

obj = models.UserInfo.objects.get(user='lvze')

obj.pwd = '321'

obj.save()

 



models.UserInfo.objects.all()

models.UserInfo.objects.all().values('user')    #只取user列

models.UserInfo.objects.all().values_list('id','user')    #取出id和user列,并生成一个列表

models.UserInfo.objects.get(id=1)

models.UserInfo.objects.get(user='lvze')

或者我们还可以用filter查找,进行更丰富的匹配。filter查找的常用匹配方法:

 
1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34
# 获取个数

#

# models.Tb1.objects.filter(name='seven').count()

# 大于,小于

#

# models.Tb1.objects.filter(id__gt=1) # 获取id大于1的值

# models.Tb1.objects.filter(id__lt=10) # 获取id小于10的值

# models.Tb1.objects.filter(id__lt=10, id__gt=1) # 获取id大于1 且 小于10的值

# in

#

# models.Tb1.objects.filter(id__in=[11, 22, 33]) # 获取id等于11、22、33的数据

# models.Tb1.objects.exclude(id__in=[11, 22, 33]) # not in

# contains

#

# models.Tb1.objects.filter(name__contains="ven")

# models.Tb1.objects.filter(name__icontains="ven") # icontains大小写不敏感

# models.Tb1.objects.exclude(name__icontains="ven")

# range

#

# models.Tb1.objects.filter(id__range=[1, 2]) # 范围bettwen and

# 其他类似

#

# startswith,istartswith, endswith, iendswith,

# order by

#

# models.Tb1.objects.filter(name='seven').order_by('id') # asc

# models.Tb1.objects.filter(name='seven').order_by('-id') # desc

# limit 、offset

#

# models.Tb1.objects.all()[10:20]

# group by

from django.db.models import Count, Min, Max, Sum

# models.Tb1.objects.filter(c1=1).values('id').annotate(c=Count('num'))

# SELECT "app01_tb1"."id", COUNT("app01_tb1"."num") AS "c" FROM "app01_tb1" WHERE "app01_tb1"."c1" = 1 GROUP BY "app01_tb1"."id"
三、django数据库错误相关问题
摘自:http://blog.csdn.net/pipisorry/article/details/45727309

django数据库错误相关问题

问题:字段修改属性发生错误

1>
>python manage.py makemigrations
You are trying to add a non-nullable field 'price_monthly' to product without a default; we can't do that (the database needs something to populate existing rows).
Please select a fix:
1) Provide a one-off default now (will be set on all existing rows)
2) Quit, and let me add a default in models.py
Select an option:


{这个可能是之前已创建了表中的一条记录,之后模型中增加了一个非空的字段,但是原来已经存在的记录没有这个值}

2>

>python manage.py migrate
... ...
raise errorclass(errno, errorvalue)django.db.utils.ProgrammingError: (1146, "Table 'lab_data.bigdata_postgraduate_research_directions' doesn't exist")
{这个是因为在字段中添加了blank=True或者 null=True引起的}

3>

>python manage.py makemigrations
You are trying to change the nullable field 'job_title' on professor to non-nullable without a default; we can't do that (the database needs something to populate existing rows).

Please select a fix:

 1) Provide a one-off default now (will be set on all existing rows)

 2) Ignore for now, and let me handle existing rows with NULL myself (e.g. adding a RunPython or RunSQL operation in the new migration file before the AlterField operation)

 3) Quit, and let me add a default in models.py

Select an option:

{这个是将模型中的null=True删除了之后产生的错误}

1>原因解释:


1. The migrations system is designed so that a single migration can be applied to more than one database. For example, you could have a development version, a staging version, and one or more production versions. That's whymaking the migration is a
distinct step from applying the migration, and why
makemgirations
 can't just look at the currently active database to see that it doesn't have any rows. What if you then try to apply the migration to a database that does?

The solution in your case is simple: since there are no rows, option 1 (setting a default on all existing rows) won't do anything at all. So choose option 1, and any value you like.

[Django
1.7.1 requires a Default value for field - but no entry is in database. Why?]

2. Django adds a default "id" field to every model, you don't need an extra "twitbot_id" in your model. If a surrogate primary key is all you need, forget about "twitbot_id" because it will be a duplicate of the auto-generated "id". Seehttps://docs.djangoproject.com/en/dev/topics/db/models/#automatic-primary-key-fields

If you add this and you already have TwitterBot objects in your database you must provide a default value to populate this column for existing rows in the database.

[Can't
seem to lose this error: “You are trying to add a non-nullable field”]

3. 如果你跟我一样是因为之前建好表a后,又创建一个表b作为a的父类,a中只有pass,那么因为表a已经创建,其中有数据,当a迁移时就会出现新表不能为null且没有指定默认值时就会出现这种错误。

解决方案:

1>在基类b中添加允许为空或者添加默认值,并设置b不建表(meta中的abstract = true)
class Base(models.Model):
'''
基类
'''
title = models.CharField(max_length=150, null=True)
content = models.TextField(null=True)
time_stamp = models.DateTimeField(auto_now_add=True, default=timezone.now())
link = models.URLField(blank=True, verbose_name='url_link')

class Meta:
abstract = True

Note:DataTimeField好像与其它的不一样,不好改!

1>2>3>

删除所有migrate文件(不用移除整个文件夹),然后重来

问题:manytomanyfeild没有默认值


django
admin gives warning “Field 'X' doesn't have a default value”

问题:添加元属性发生错误

raise InternalError(errno, errorvalue)
django.db.utils.InternalError: (1017, "Can't find file: '.\\lab_data\\people_patent_prizes.frm' (errno: 2 -No such file or directory)")
{模型类中增加class Meta:db_table='People'使数据库中对应的表名修改成了People,原来的表间联系可能破坏了}
解决方案:

删除所有migrate文件(不用移除整个文件夹),然后重来
http://blog.csdn.net/pipisorry/article/details/45727309

问题:表中字段不存在

"Unknown column 'name' in 'field list'"


django中创建了表professor继承了表people的字段,并且在后台可以看到,但实际在数据库中不存在(数据库中查询可看到)

出现问题原因:

1. model中编辑的字段没有在数据库对应的表里创建(原因可能是字段是继承自父类,出现的什么问题?)

数据库中查看表中的字段:



2. migration文件出了什么问题?导致没有同步到数据库(表都没创建)

解决方案1:

在数据库中手动添加没有创建的字段

alter table bigdata_professor add column name varchar(6);

再次查看表中字段:



再次运行django服务器,后台添加name字段时就不会出错了。

解决方案2:

先删除整个migrations文件夹,再python manage.py makemigrations,再python manage.py migrate



这样表就可以重新建立成功了!(可以查询到django中新建的表bigdata_professor....)



Note:

1. 成功后最好把之前删除的文件夹migrations重新建一个(app中的)

2. 只删除migration文件可能不会出现这个问题:

No migrations to apply.   Your models have changes that are not yet reflected in a migration, and so won't be applied. Run 'manage.py makemigrations' to make new migrations, and then re-run 'manage.py migrate' to apply them.

我了个去,都不知道为啥migration文件会出问题,删除后再操作就没事了,可能是(在makemigrations)之前先进行了migrate操作?

[Django Models (1054, “Unknown column in 'field list'”)]

问题:表不存在或者No migrations to apply

"Table 'lab_data.bigdata_resdir' doesn't exist"


模型中建立新表后,makemigrations成功,但是migrate出现错误:

python manage.py migrate
Operations to ...:
Apply all migrations: ...

[/code]No migrations to apply.(即使实际上明明makemigrations成功,并且有许多migrations可以应用)

  Your models have changes that are not yet reflected in a migration, and so won't be applied.  Run 'manage.py makemigrations' to make new migrations, and then re-run 'manage.py migrate' to apply them.

按照提示重新makemigration后migration文件就不会创建新表了,在数据库中表也的确没有新建。

原因:

1. Sounds like your initial migration was faked because the table already existed (probably with an outdated schema):

https://docs.djangoproject.com/en/1.7/topics/migrations/#adding-migrations-to-apps

"This will make a new initial migration for your app. Now, when you run migrate,Django will detect that you have an initial migration and that the tables it wants to create already exist, and will mark the migration as already applied."
Otherwise you would get an no-such-table error.

[No migrations to apply, even though there are migrations
to apply]

2. 也可能是之前按照某个说明执行了一次
python manage.py migrate --fake
导致的。
--fake
 的含义是不执行该迁移脚本但是标记该脚本已经被执行过。导致之后无法正常进行迁移。

[Django 1.7 中 migrate 无法执行而且表不存在的解决方案]

解决方案:

方法1.

1> In MySQL Database delete row 
'app_name'
 from the table 
'django_migrations'
.

打开mysql command line client, 进入创建好的数据库use databasename; 查看表select * from django_migration; 发现将要执行的迁移脚本的 id 已经添加在表中了,将其删除即可,即删除最新一次app_name对就的id行。



2> Delete all migration files in migrations folder.

3> Try again 
python manage.py makemigrations
 and 
python manage.py migrate
 command.

[Django 1.7 - “No migrations to apply” when
run migrate after makemigrations]

方法2:

移除整个migrations文件夹,重新makemigrations和migrate。之后就会自动创建了:



方法3:

实在不行,只能drop database,再重新建立了。

http://blog.csdn.net/pipisorry/article/details/45727309

问题:外键修改成多对多错误
ValueError: Cannot alter field bigdata.Postgraduate.publisher into bigdata.Postgraduate.publisher - they are not compatible types (you cannot alter to or from M2M fields
, or add or remove through= on M2M fields)
{这个错误是由将模型Postgraduate中的publisher字段从ForeignKey修改成ManyToManyField引起的}

解决方案:

删除所有migrations文件,重新makemigrations和migrate

[foreignkey error: Django migration
error :you cannot alter to or from M2M fields, or add or remove through= on M2M fields]

数据库注册到site管理错误

TypeError: __init__() missing 2 required positional arguments : 'model' and 'admin_site'

class DirectionsInline(inlineBase, admin.ModelAdmin):
model = Directions
inlines = [ImagesInline, ]
admin.site.register(Directions, DirectionsInline)

解决:原因可能是继承admin.ModelAdmin的类中不能有model = ***

数据库权限错误

django.db.utils.operationalerror:<1045,"access denied for user root@localhost using password yes>

解决方案1:django setting.py文件中设置的database用户名或者密码错了,修改一下就可以了

或者是django运行项目时用的不是settings.py文件,这个在os.environ.setdefault("DJANGO_SETTINGS_MODULE", "labsite.settings")中设置

其它方案


Access denied for user 'root'@'localhost' (using password: YES)

mysql Access denied for user root@localhost错误解决方法总结(转)

ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)

MySQL Forums ::Install & Repo ::ERROR
1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)

django.db.utils.operationalerror:<2003, "can't connect to mysql server on '127.0.0.1'(winerror 10061] No connection could be made because the target machine actively refused it)")

settings.py中设置的host和port如下

'HOST': '127.0.0.1','PORT': '3306'

如改动port为其它,可能导致该问题

其它问题:

1.Error: Tablespace for table xxx exists.
Please DISCARD the tablespace before IMPORT

2. django.db.utils.ProgrammingError: (1146, "Table 'lab_data.django_migrations' doesn't exist")

3.django.db.utils.InternalError: (1050, "Table '`l ab_data`.`django_migrations`'already exists")

1>两个模型的数据库表名设置成一样的了
class Meta:
db_table = 'WorkExp1'


2>python manage.py migrate --fake
from:http://blog.csdn.net/pipisorry/article/details/45727309

ref:[Django 问题收集]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: