非django项目中使用django的ORM

习惯了使用django的orm,再使用其他的orm感觉都没有django的orm香,最近发现了一个可以脱离diango项目单独使用djangoorm的方法,原理是指定django的setting配置文件,让model可以找到数据库配置信息,这样就可以操作了。 

     

一、安装依赖

pip install django==2.1 #高级版本的django需要的mysql版本比较高,所以使用2.1版本的
pip install pymysql #django连mysql需要使用

二、简单使用

2.1 选择已有数据库,生成对应的model文件

如果要使用django的model,需要有model类,这里表已经存在了,直接生成一个表对应的model类

import pymysql
pymysql.install_as_MySQLdb()


from django.conf import settings
from django.core.management.commands.inspectdb import Command

settings.configure(
    DATABASES={
            'default': {
                'ENGINE': 'django.db.backends.mysql',
                'NAME': 'db_name',
                'USER': 'db_user',
                'PASSWORD': 'db_password',
                'HOST': 'db_host',
                'PORT': '3306'
            },
        }

)#设置数据库信息,和django的settings中一样的

def create_model(tables,file_name,db):
    with open(file_name,'w',encoding='utf-8') as fw:
        #下面这个代码是把django生成model文件的代码复制出来的
        command = Command()
        table_dict = {'table': tables, 'database': db}
        for line in command.handle_inspection(table_dict):
            fw.write('%s\n'%line)
    print('生成models完成')

if __name__ == '__main__':
    tables = ['product', 'user', 'account']  # 生成哪些表的model类

    file_name = 'models.py'  # 生成的文件名

    db = 'default'  # 使用哪个数据库,就是上面setting里面配置的
    
    create_model(tables,file_name,db)

 

2.2使用生成的model,进行增删改查

现在目录结构如下图

 

models.py 是上面代码生成的model文件

test.py 是咱们写代码操作数据库的

 

 

 代码如下:

import pymysql
pymysql.install_as_MySQLdb()


from django.conf import settings
import django
settings.configure(
    DATABASES={
            'default': {
                'ENGINE': 'django.db.backends.mysql',
                'NAME': 'db_name',
                'USER': 'db_user',
                'PASSWORD': 'db_password',
                'HOST': 'db_host',
                'PORT': '3306'
            },
        },
    INSTALLED_APPS=('biz',)#这个是必须要指定的,models文件在biz目录下,这个install app就写biz

)#设置数据库信息,和django的settings中一样的
django.setup()
from biz import models

user = models.AppMyuser.objects.get(id=1)
print(user.username)

user_obj = models.AppMyuser(username='haha',password='1234566')
user_obj.save()

user_haha = models.AppMyuser.objects.get(username='haha')
print(user_haha.username)

 

三、进阶使用

3.1 分表操作

 如果某张表存在分表,比如分了8张/16张表,如果按照django的model来,就得生成8/16个类,就太麻烦了,而且查询的时候也得先算出来在哪个表中,再导入对应的类,这样用起来就很不方便。

 比如user表,分了8张表,分别是 user_0、user_1、....、user_8,那我们就生成一个User的model类,在操作数据库的时候再根据分表规则动态计算出来在哪个表中。

 下面是生成的一个model类,可以看到,django在通过model类操作表的时候,是通过model类中的class Meta下面的db_table来确定具体访问哪个表的,这样我们就可以通过动态的更改db_table就可以了。

 

from django.db import models


class AppMyuser(models.Model):
    username = models.CharField(unique=True, max_length=30)
    passwd = models.CharField(max_length=32)
    is_admin = models.SmallIntegerField(blank=True, null=True)
    error_count = models.IntegerField(blank=True, null=True)
    balance = models.FloatField(blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'app_myuser'

 

 下面是计算分表规则的函数

    @classmethod
    def get_table(cls,id,table_number=8):
        '''
        :param id:按照哪个id进行分表的,需要传进来
        :param table_number: 分了几张表
        :return:
        '''
        table_index = id % table_number #这个是分表规则,这个是按照某个id模8,分8张表
        cls._meta.db_table = '%s_%s' % (cls._meta.db_table,table_index)
        #cls._meta 就是model类里面的class Meta
        #原来是app_myuser,经过计算后,咱们改成了 app_myuser_1这样
        return cls.objects
        #操作model的时候是xx.objects.get(id=1)这样
        #咱们这个方法就直接返回这个objects

 

下面咱们在生成model文件的时候,把这个函数给他加到类里面就行了,需要修改一下之前写的生成model文件的代码

 

import pymysql

pymysql.install_as_MySQLdb()

from django.conf import settings
from django.core.management.commands.inspectdb import Command

settings.configure(
    DATABASES={
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 'db_name',
            'USER': 'db_user',
            'PASSWORD': 'db_password',
            'HOST': 'db_host',
            'PORT': '3306'
        },
    }

)  # 设置数据库信息,和django的settings中一样的

code='''
    @classmethod
    def get_table(cls,id,table_number=8):
        table_index = id % table_number #这个是分表规则,这个是按照某个id模8,分8张表
        cls._meta.db_table = '%s_%s' % (cls._meta.db_table,table_index)
        return cls.objects
        
'''
#要写到model里面的函数,因为model文件是咱们自己生成的,就是往里面写一个字符串

def create_model(tables, file_name, db):
    with open(file_name, 'w', encoding='utf-8') as fw:
        # 下面这个代码是把django生成model文件的代码复制出来的
        command = Command()
        table_dict = {'table': tables, 'database': db}
        for line in command.handle_inspection(table_dict):
            if 'class Meta' in line:#判断如果是class Meta,在它前面加个函数
                line = code + line
            fw.write('%s\n' % line)
    print('生成models完成')


if __name__ == '__main__':
    tables = ['product', 'user', 'account']  # 生成哪些表的model类

    file_name = 'models.py'  # 生成的文件名

    db = 'default'  # 使用哪个数据库,就是上面setting里面配置的

    create_model(tables, file_name, db)

 

重新运行代码,可以看到生成的model类中,已经有get_table函数

 

 

 

3.2 分表数据操作

数据操作和上面的增删改查基本一样,多了需要计算分表的操作,当然如果有不分表的,也不影响,和以前用法一样,这里还有bug,如果先操作user_1表,然后再操作user_2表这样就不行了,还没想到解决方案

import pymysql
pymysql.install_as_MySQLdb()


from django.conf import settings
import django
settings.configure(
    DATABASES={
            'default': {
                'ENGINE': 'django.db.backends.mysql',
                'NAME': 'db_name',
                'USER': 'db_user',
                'PASSWORD': 'db_password',
                'HOST': 'db_host',
                'PORT': '3306'
            },
        },
    INSTALLED_APPS=('biz',)#这个是必须要指定的,models文件在biz目录下,这个install app就写biz

)#设置数据库信息,和django的settings中一样的
django.setup()
from biz import models

table = models.AppMyuser.get_table(23532532521) #传入id,计算分表号码
print(models.AppMyuser._meta.db_table) #打印db_table的值,可以看出来表已经是1这张表了
new_user = table.get(pk=1)
print(new_user.username)

 

 

 

 

 

 

 

 

posted @ 2020-10-14 15:32  朝花夕拾_nn  阅读(835)  评论(0编辑  收藏  举报