單獨立使用Django ORM

一、常用的ORM框架簡介

Python下的ORM庫不少,同樣介紹類似的博文也不少,但是是我非常規的用法,順便做做筆記。這裏參考Python 常用的ORM框架簡介文章列出幾個, 這個幾個我都使用過,但是我還是更喜歡Django ORM, 被它的API慣壞了再也不想使用別的了,於是有種數據庫操作都想用它的想法,所以纔有了這篇筆記。

  • Django's ORM 是緊嵌到web框架的ORM,一個最流行的Python web框架, 有它獨有的ORM。 相比 SQLAlchemy, Django 的 ORM 更吻合於直接操作SQL對象,操作暴露了簡單直接映射數據表和Python類的SQL對象, 接口豐富易用 。

    優點:易用,學習曲線短 和Django緊密集合,用Django時使用約定俗成的方法去操作數據庫
    缺點:不好處理複雜的查詢,強制開發者回到原生SQL緊密和Django集成,使得在Django環境外很難使用

  • peewee 整個庫是單個文件, 看源碼費勁(我個人偏見了)

    優點:Django式的API,使其易用 輕量實現,很容易和任意web框架集成
    缺點:不支持自動化 schema 遷移 多對多查詢寫起來不直觀

  • SQLAlchemy 採用了數據映射模式,其工作單元 主要使得 有必要限制所有的數據庫操作代碼到一個特定的數據庫session,在該session中控制每個對象的生命週期 。

    優點:企業級 API,使得代碼有健壯性和適應性靈活的設計,使得能輕鬆寫複雜查詢
    缺點:工作單元概念不常見 重量級 API,導致長學習曲線

二、單獨使用Django ORM功能

而這篇筆記的主角是DjangoORM, 它一般都是在web項目上使用的, 很少有領出來單獨使用的,這裏就提煉出一個小的Demo 展示獨立使用Django ORM, 即非Web項目上使用ORM, 代碼目錄接口如下:

1.目錄結構

│  demox.py
│  main.py
│
├─django_orm
│  │  settings.py
│  │  __init__.py
│  │
│  ├─app01
│  │  │  models.py
│  │  │  __init__.py

2.用代碼main.py

在入口處配置Django的設置文件系統環境變量DJANGO_SETTINGS_MODULE值爲設置文件的目錄django_orm.settings, 這取值跟目錄結構有關,加載Django ORM 是讀取配和這個配置問文件。

import os

# 行是必須的
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "django_orm.settings")

from django_orm import migrate, make_migrations
from django_orm.app01 import models
from demox import do_demo

import time
import random
import threading


def update():
    while True:
        try:
            obj = models.User.objects.first()
            obj.name = obj.name + 1
            obj.save()
            print("update:", object)
            # time.sleep(random.random()*0.5)
        except Exception as err:
            print("update:", "-" * 40)
            print(err)
        break


def create():
    while True:
        try:
            obj = models.User.objects.create(name=random.randint(0, 100))
            print("create:", obj)
            # time.sleep(random.random() * 0.5)
        except Exception as err:
            print("create:", "-" * 40)
            print(err)


def select():
    while True:
        try:
            print("select:", models.User.objects.all()[:5])
            # time.sleep(0.5)
        except Exception as err:
            print("select:", "-" * 40)
            print(err)
        break


def delete():
    while True:
        try:
            obj = models.User.objects.first()
            print("delete:", obj)
            obj.delete()
            # time.sleep(0.5)
        except Exception as err:
            print("delete:", "-" * 40)
            print(err)
        break


if __name__ == '__main__':
    do_demo()
    make_migrations("app01")
    migrate("app01")
    u = models.User.objects.create(name=2)
    u.save()
    print(len(models.User.objects.all()))
    # # threading.Thread(target=update).start()
    # # threading.Thread(target=create).start()
    threading.Thread(target=select).start()
    # # threading.Thread(target=delete).start()

3. 應用的models

方便管理創建一個目錄django_orm專門放置Django models項目的數據庫表結構文件, 目錄__init__.py文件中把所有的app加載到Django裏, 並提供migratemake_migrations方法用於數據庫遷移。

from django.apps import apps
from django.conf import settings
from django.core.management import call_command

apps.populate(settings.INSTALLED_APPS)
print("----------apps.populate----------")


def migrate(app_name: str):
    call_command("migrate", app_name)


def make_migrations(app_name: str):
    call_command("makemigrations", app_name)

settings.py 配置文件,即在main.py 最開始的入口加載的系統環境變量值

# !/usr/bin/env python
# -*- coding: utf-8 -*-
#
# @project : demo2
# @file    : settings.py
# @time    : 2019/11/8 22:28
# @author  : GuangLin
# @version : 0.01
# @desc    :


"""
Django settings for demo2 project.

Generated by 'django-admin startproject' using Django 2.1.

For more information on this file, see
https://docs.djangoproject.com/en/2.1/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/2.1/ref/settings/
"""

import os
import sys

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, os.path.join(BASE_DIR, ".."))

print(__file__)
print(BASE_DIR)
print(os.path.join(BASE_DIR, 'db.sqlite3'))


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.1/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'lyv+won7%7!=ra!nc160o-x1yz+m%n1jxm)wtw_y1r3%shh@-%'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True


# Application definition

INSTALLED_APPS = [
    'django_orm.app01',
]


# Database
# https://docs.djangoproject.com/en/2.1/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

app01/models.py 應用表結構

from django.db import models


class User(models.Model):
    name = models.CharField(max_length=10)

在實踐實用中發現Sqlite3在多線程下會鎖庫,這個是Sqlite內部機制導致的,在Peewee和裸跑多線程也是一樣的鎖庫,特別是配置低的機器下,IO讀寫速度慢的時候。處理的機制是db操作放到獨立的線程下操作,下篇筆記裏記錄。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章