Django 自定义表名和字段名

通过db_table和db_column自定义数据表名和字段名

假如你的数据库里已经有了一张数据表,且该表包含多个字段,你希望通过Django直接访问该数据表的各个字段而不是重新建立新表,你这时可以通过db_table指定数据表名,还可以通过db_column指定希望访问的字段名。

在我们创建一个模型时,Django的ORM会根据应用名(app name), 模型名(model name)和字段名(field name)自动在数据库中创建数据表。比如我们有一个Blog的应用,里面有Article模型, 其中Article模型有title这个字段,那么Django默认会创建一个名为blog_article的数据表,其中有title这个字段。假如我们希望把表名改为article,标题改为article_title,以便与已经存在的数据表或字段建立映射关系,我们可以按如下代码操作。

class Article(models.Model):
    """文章模型"""
  
    # 通过db_column自定义数据表中字段名
   title = models.CharField(‘标题‘, max_length=200, db_column=‘article_title‘)
    slug = models.SlugField(‘slug‘, max_length=60, blank=True)
    
    def __str__(self):
        return self.title
        
    class Meta:
        db_table = ‘article‘ # 通过db_table自定义数据表名

通过db_index和Meta index选项给数据表字段建立索引

使用索引可快速访问数据库表中的特定信息。数据库索引好比是一本书前面的目录,没有索引目录的话,你访问书中某个页面需要从第1页遍历到最后一页,如果有目录,你可以快速地根据目录查找到所需要的页面。Django项目中如果你需要频繁地对数据表中的某些字段(如title)使用filter(), exclude()和order_by()方法进行查询,我们强烈建议你对这些字段建议索引(index), 提升查询效率。

要对模型中的某个字段建立数据库索引,你可以使用db_index选项,也可以使用Meta选项建立索引。使用Meta选项的好处是你可以一次性对多个字段建立索引,还可以对多个字段建立组合索引。

方法一: 使用db_index选项

class Article(models.Model):
    """文章模型"""

    # 使用db_index=True对title建立索引
    title = models.CharField(‘标题‘, max_length=200, db_index=True)
方法二: 使用Meta选项

class Article(models.Model):
    """文章模型"""
   title = models.CharField(‘标题‘, max_length=200,)

    class Meta:
        indexes = [
            models.Index(fields=[‘title‘]),
        ]

Django主从数据库配置

当你刚刚开始建立一个网站时,可能每天只有数十到上百人访问。这时你只有一个数据库,所有APP的数据表也都放一起的,一台普通的服务器能够应付, 也便于维护。但是当访问量上来后,你会发现一台服务器和一个数据库会根本应付不了这个压力。这时你可能希望实现数据库的主从配置,读写分离,把各个数据库放在不同的服务器上,有的专门负责写入,有的专门负责读取,这时你就要学会使用Django同时连接多个数据库,并自定义读写操作。

第一步 修改项目的 settings 配置

在 settings.py 中配置需要连接的多个数据库名称和登录信息。在下例中我们自定义了3个数据库,1个主数据库(primary), 2个从数据库(replica)。

#project/settings.py

DATABASES = {
    ‘default‘: {},
    ‘primary‘: {
        ‘NAME‘: ‘primary‘,
        ‘ENGINE‘: ‘django.db.backends.mysql‘,
        ‘HOST‘: ‘xxxx‘,
        ‘PORT‘: ‘xxxx‘,
        ‘USER‘: ‘mysql_user‘,
        ‘PASSWORD‘: ‘spam‘,
    },
    ‘replica1‘: {
        ‘NAME‘: ‘replica1‘,
        ‘ENGINE‘: ‘django.db.backends.mysql‘,
        ‘HOST‘: ‘xxxx‘,
        ‘PORT‘: ‘xxxx‘,
        ‘USER‘: ‘mysql_user‘,
        ‘PASSWORD‘: ‘eggs‘,
    },
    ‘replica2‘: {
        ‘NAME‘: ‘replica2‘,
        ‘ENGINE‘: ‘django.db.backends.mysql‘,
        ‘HOST‘: ‘xxxx‘,
        ‘PORT‘: ‘xxxx‘,
        ‘USER‘: ‘mysql_user‘,
        ‘PASSWORD‘: ‘bacon‘,
    },
}

我们还需要在 settings.py 添加我们手动编写的数据库路由Router。路由的作用是为数据库的读写制定规则。

DATABASE_ROUTERS = [‘Project.database_router.PrimaryReplicaRouter‘]

注意: 主从数据库的同步是通过MySQL配置实现的,而不是Django实现的。Django只负责多个数据库的访问,不负责各个数据库的同步工作。如果你定义了多个路由,请一定注意路由的执行顺序。

第二步 自定义数据库路由Router

在Django项目的根目录下创建 database_router.py 文件, 添加如下代码,自定义数据库路由。该路由规定了读取数据时将随机从replica1和replica2数据库中读取,而写入数据总是写入主数据库primary。该路由还允许三个数据库中的字段建立联系。

class PrimaryReplicaRouter(object):
    def db_for_read(self, model, **hints):
        """
        Reads go to a randomly-chosen replica.
        """
        return random.choice([‘replica1‘, ‘replica2‘])

    def db_for_write(self, model, **hints):
        """
        Writes always go to primary.
        """
        return ‘primary‘

    def allow_relation(self, obj1, obj2, **hints):
        """
        Relations between objects are allowed if both objects are
        in the primary/replica pool.
        """
        db_list = (‘primary‘, ‘replica1‘, ‘replica2‘)
        if obj1._state.db in db_list and obj2._state.db in db_list:
            return True
        return None

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        """
        All models end up in this pool.
        """
        return True

一个数据库路由是一个类,这个类最多有四个方法:

db_for_read(model, **hints)

建议 model 对象进行读操作时使用的数据库。如果一个数据库操作可以提供对选择数据库有用的附加信息,那么可以通过 hints 字典提供。如果没有建议则返回 None 。

db_for_write(model, **hints)

建议 model 对象进行写操作时使用的数据库。如果一个数据库操作可以提供对选择数据库有用的附加信息,那么可以通过 hints 字典提供。如果没有建议则返回 None 。

allow_relation(obj1, obj2, **hints)

当 obj1 和 obj2 之间允许有关系时返回 True ,不允许时返回 False ,或者没有意见时返回 None 。这是一个纯粹的验证操作,用于外键和多对多操作中,两个对象的关系是否被允许。

allow_migrate(db, app_label, model_name)

决定 model 是否可以和 db 为别名的数据库同步。如果可以返回True , 如果不可以返回 False ,或者没有意见时返回 None 。

Django项目按APP分库

在大型web项目中,我们常常会创建多个app来处理不同的业务,如果希望实现app之间的数据库分离,比如app01走数据库db1,app02走数据库db2,而不是实现读写分离。我们可以定义如下所示的数据库路由, 然后将其加入settings.py 。

class AppDBRouter:
    def db_for_read(self, model, **hints):
        if model._meta.app_label == ‘app01‘:
            return ‘db1‘
        if model._meta.app_label == ‘app02‘:
            return ‘db2‘

    def db_for_write(self, model, **hints):
       if model._meta.app_label == ‘app01‘:
            return ‘db1‘
       if model._meta.app_label == ‘app02‘:
            return ‘db2‘

由于manage.py一次只能创建一个数据库,我们可以使用--database选项来依次创建我们需要的数据库。例如:

将app01下models中的表创建到db01的数据库”db1”中

python manage.py  migrate  --database=db1

将app02下models中的表创建到db02的数据库”db2”中

python manage.py  migrate  --database=db2

在使用多数据库时,我们可以使用using方法来手动选择需要读写的数据库,如下所示:

Aricle.objects.using(‘db1‘).all()
article_object.save(using=‘db2‘)

Django中使用多数据库注意事项:

django 目前不为跨多个数据库的外键关系(ForeinKey)或多对多关系提供任何支持。模型定义的任何外键和多对多关系字段都必须存在一个数据库内。

原文地址:https://www.cnblogs.com/gwklan/p/11140079.html

时间: 2024-10-09 08:24:29

Django 自定义表名和字段名的相关文章

Oracle 查询库中所有表名、字段名、表名说明、字段名说明(原创)

查询所有表名:select t.table_name from user_tables t;查询所有字段名:select t.column_name from user_col_comments t;查询指定表的所有字段名:select t.column_name from user_col_comments t where t.table_name = 'BIZ_DICT_XB';查询指定表的所有字段名和字段说明:select t.column_name, t.column_name from

oracle表名、字段名等对象的命名长度限制

原创作品,出自 "深蓝的blog" 博客,欢迎转载,转载时请务必注明出处,否则追究版权法律责任. 深蓝的blog:http://blog.csdn.net/huangyanlong/article/details/45854385 今天在为某系统数据库结构整理升级脚本时,遇到了"命名字节过长的错误",类似于下面的截图语句: 由于升级的结构中对于字段名的命名根据业务进行了修改,出现了命名过长的情况. 这里想说一下,对于oracle,表名.字段名等对象命名字节个数限制在

Oracle中使用游标获取指定数据表的所有字段名对应的字符串

操作步骤:打开PLSQL Developer后,直接执行下面的语句就可以出来 --Oracle中使用游标获取指定数据表的所有字段名对应的字符串 declare mytablename VARCHAR(255):='STAFFDOC'; --定义要查询的数据表名变量,STAFFDOC为我测试用的数据表名,请修改成您的数据库中的对应数据表名字mystring NVARCHAR2(4000):=''; --定义要输出的字符串变量 cursor mycursor is --定义游标          s

SQLSERVER和ORACLE批量处理表名和字段名大写

在sql移植到oracle过程中,都会遇到表名和字段名大写的问题,因为在oracle中默认表名和字段名都是大写的,虽然可以通过使用双引号的方式进行操作,如select * from "testtable"但是很多情况下,这样做的代价很大,因为很多程序的代码是早已经写好的,而要修改oracle系统配置又不安全,一个比较稳妥的办法是批量修改表名和文件名. 先说在SQL中修改表名和字段名的办法:虽然在sql中默认是不区分表名和字段名的大小写的,但是通过sql的DTS进行数据导出导入的时候,如

SQL语句修改表名和字段名

今天有个临时任务,修改生产环境的数据库表名和字段名.以前要修改表名字段名都是在开发环境,直接打开 SQL Server找到对应的表或字段重命名就OK啦,可是这是线上数据库,再想直接F2修改是不可能的啦.怎么办?乖 乖写脚本呗.上网了解了一些相关资料,结合我自己操作过程中出现的一些实际问题简单作个总结,再次加深下印 象. SQL自带了一系列的系统存储过程.其中sp_rename就具有修改表名和列名的功能.对于sp_rename是这样定 义的:更改当前数据库中用户创建对象(如表.列或用户定义数据类型

Oracle 查询库中所有表名、字段名、字段名说明,查询表的数据条数、表名、中文表名、

查询所有表名:select t.table_name from user_tables t;查询所有字段名:select t.column_name from user_col_comments t;查询指定表的所有字段名:select t.column_name from user_col_comments t where t.table_name = 'BIZ_DICT_XB';查询指定表的所有字段名和字段说明:select t.column_name, t.column_name from

SQLServer2005,2000获取表结构:字段名、类型、长度、主键、非空、注释

SQLServer 2005 SELECT d.name N'TableName', d.xtype N'TableType', a.colorder N'ColumnIndex', a.name N'ColumnName', (case when COLUMNPROPERTY( a.id,a.name,'IsIdentity')=1 then '1'else '0' end) N'IdnetityFG', (case when (SELECT count(*) FROM sysobjects

查询所有表名、字段名、类型、长度 和 存储过程、视图 的创建语句

-- 获得存储过程创建语句 select o.xtype,o.name,cm.text from syscomments cm inner join sysobjects o on o.id=cm.id where xtype ='p' order by o.xtype,o.name,cm.text -- 获得视图程创建语句 select o.xtype,o.name,cm.text from syscomments cm inner join sysobjects o on o.id=cm.i

ASP获取数据库表名,字段名以及对字段的一些操作

最近,在ASP论坛上看到很多网友问怎么获取数据库表名,字段名以及如何对字段进行删除,增添的操作故写此文. 本人对SQLServer比较熟一些,故以SQLServer为列: <% SET Conn=Server.CreateObject("ADODB.Connection") Conn.Open "Server=IP地址;Provider=sqloledb;Database=库名称;UID=用户名;PWD=密码;" %> 读SqlServer库中的表名: