开发者社区> 问答> 正文

mysql 外键不能关联到一自增的字段么??报错

我是用django。

先是建立了表A  主键Aid 自增

然后建立表B  主键Bid 自增  外键Aid

构建表结构的时候 报错 说:

error 1075 42000 incorrect table definition there can be only one auto column and it must be defined as a key


我该咋解决呢。。。

展开
收起
爱吃鱼的程序员 2020-06-22 17:01:33 951 0
1 条回答
写回答
取消 提交回答
  • https://developer.aliyun.com/profile/5yerqm5bn5yqg?spm=a2c6h.12873639.0.0.6eae304abcjaIB

    关键问题是出在ForeignKey上,因为我们自定义了BigIntegerAutoField,将其数据类型设为了bigintAUTO_INCREMENT,在建立外键里,默认情况下这个数据类型也会直接返回,因此造成了tucao_reply表里有了两个自增的字段,这是mysql不允许的。因此我们就需要改变这种默认的逻辑,而参考系统中ForeignKey的实现,发现系统其实对于AutoField也是做了特殊处理的,相关代码可以参考Django的源代码,因此我也就照着这样的方式,扩展了ForeignKey,生成的SQL语句就没有问题了回复<aclass='referer'target='_blank'>@渔樵耕读:总体来说,我觉得Django还是非常不错的,如果她还有些不完善,那我们也应该让她完善起来懂了。唉django还是不太完善啊。当然可以啊必须得是索引
    <spanstyle="font-family:微软雅黑,Verdana,sans-serif,宋体;font-size:14px;line-height:22px;background-color:#FFFFFF;">主键Bid没必要自增了吧,你都外键连到aid了外键肯定是可以自增的,这肯定是你的表结构写错了。你检查下你建数据的语句,大概忘了把自增字段设成主键了,也可能你在同一个表内多定义了一个自增字段。确实是一个表里两个自增字段了。一个是主键,一个是外键链接到另一个表里的主键取消B表中的外键aid的自增属性就没问题了,提示已经说得很清楚了嘛Django的话最好上代码,我还没有遇到过这样的情况代码贴上了。请注意TucaoReply中的tcId~<preclass="brush:python;toolbar:true;auto-links:false;">fromdjango.dbimportmodelsfromfieldsimportBigIntegerAutoField#pythonmanage.pyschemamigrationauthoradd_mobile_column--auto执行model修改同步db的命令#pythonmanage.pymigrate提交同步dbclassTucao(models.Model):tcId=BigIntegerAutoField(primary_key=True,max_length=20,db_column='tucao_id',help_text='主键')tcUserId=models.BigIntegerField(blank=False,max_length=11,db_column='tucao_account_id',help_text='吐嘈者帐户id,未登录者为-1')tcAccountName=models.CharField(max_length=50,blank=False,db_column='tucao_account_name',help_text='吐嘈者昵称,匿名显示ip')tcAccountEmail=models.EmailField(max_length=50,blank=False,db_column='tucao_account_email',help_text='吐嘈者email')tcContext=models.TextField(max_length=160,blank=False,db_column='tucao_context',help_text='吐嘈内容')tcPic=models.CharField(max_length=1000,blank=True,db_column='tucao_pic',help_text='吐槽图片链接')classMeta:db_table='tucao'verbose_name='吐槽表'classTucaoReply(models.Model):tcReplyId=BigIntegerAutoField(primary_key=True,max_length=19,db_column='tucao_reply_id',help_text='回复主键')tcId=models.ForeignKey(Tucao,db_column='tucao_id',blank=True,null=True)tcReplyAccountId=models.BigIntegerField(blank=False,max_length=11,db_column='tucao_reply_account_id',help_text='回复者帐户id,未登录为-1')tcReplyAccountName=models.CharField(max_length=50,db_column='tucao_reply_account_name',blank=False,help_text='回复者昵称,匿名的话记录IP')tcReplyAccountEmail=models.EmailField(max_length=50,db_column='tucao_reply_account_email',blank=False,help_text='如果未登录回复,需要记录邮箱')tcReplyContext=models.TextField(max_length=160,blank=False,db_column='tucao_reply_context',help_text='回复内容')tcReplyDate=models.DateTimeField(db_column='tucao_replay_datetime',help_text='回复时间')classMeta:db_table='tucao_reply'verbose_name='吐槽回复表'回复<aclass='referer'target='_blank'>@晴风晓月:把这个类型换成BigInteger也会报错。。。奇了怪了。回复<aclass='referer'target='_blank'>@渔樵耕读:你这个BigIntegerAutoField应该是你自己扩展的吧,我在Django的文档里没有找到,你看一下扩展有没有问题呢?回复<aclass='referer'target='_blank'>@晴风晓月:BigIntegerAutoField只是想让BigInt类型的主键自增。回复<aclass='referer'target='blank'>@渔樵耕读:应该是BigIntegerAutoField有问题回复<aclass='referer'target='blank'>@晴风晓月:难道外键不能指定字段名???

    我想我已经把问题解决了。

    首先我自己将实现的BigIntegerAutoField如下所示:

    <preclass="brush:python;toolbar:true;auto-links:false;">classBigIntegerAutoField(models.BigIntegerField):defdb_type(self,connection):if'mysql'inconnection.class.module:return'bigintAUTO_INCREMENT'returnsuper(BigIntegerAutoField,self).db_type(connection)


    由于改变了相应的数据类型,因此改写ForeignKey为如下代码:

    <preclass="brush:python;toolbar:true;auto-links:false;">classBigIntegerForeignKey(models.ForeignKey):def__init(self,to,to_field=None,**kwargs):super(BigIntegerForeignKey,self). init(to,**kwargs)defdb_type(self,connection):rel_field=self.rel.get_related_field()ifisinstance(rel_field,BigIntegerAutoField):returnmodels.BigIntegerField().db_type(connection=connection)returnrel_field.db_type(connection=connection)

    然后将第19行代码改写如下:

    <preclass="brush:python;toolbar:true;auto-links:false;">tcId=BigIntegerForeignKey(Tucao,db_column='tucao_id',blank=True,null=True)

    这样就没有问题了。


    3Q~~~还帮我写了代码。不过我想弄清楚。我之前那么写为什么不行呢。我的BigIntegerAutoField的代码就是按照你那么写的。最佳答案好评

    嘛,这个应该是数据库设计上的失误啊....
    回复表里加上一个回复的tucao的id?

    回复<aclass='referer'target='_blank'>@伊藤熊吉:应该是回复表增加一个字段作为外键关联吐槽表~我寻思自己加上就得了。。没跟你说。。回复<aclass='referer'target='_blank'>@渔樵耕读:确实是我设计上的失误,看邮件,你看看,如果没问题的话我就改没有失误啊!吐槽-回复是1-N的关系啊。所以回复表里肯定会吐槽的外键啊。不然怎么找到回复是属于哪一个吐槽里的信息。

    2020-06-22 17:01:51
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
One Box: 解读事务与分析一体化数据库 HybridDB for MySQL 立即下载
One Box:解读事务与分析一体化数据库HybridDB for MySQL 立即下载
如何支撑HTAP场景-HybridDB for MySQL系统架构和技术演进 立即下载

相关镜像