1. 程式人生 > 資料庫 >Django3.0.3 版本--SQLite資料庫的建立與資料庫基本操作

Django3.0.3 版本--SQLite資料庫的建立與資料庫基本操作

目錄

 

Django3.0.3 版本--SQLite資料庫的建立與資料庫基本操作

資料庫建立相關

呼叫資料庫API


Django3.0.3 版本--SQLite資料庫的建立與資料庫基本操作

資料庫建立相關

  • 預設的資料庫使用SQLite,若想使用其他的資料庫,就需要在settings.py裡面進行修改
    By default,the configuration uses SQLite. If you’re new to databases,or you’re just interested in trying Django,this is the easiest choice. SQLite is included in Python,so you won’t need to install anything else to support your database. When starting your first real project,however,you may want to use a more scalable database like PostgreSQL,to avoid database-switching headaches down the road.
    If you wish to use another database,install the appropriate database bindings and change the following keys in the DATABASES 'default' item to match your database connection settings:
    * ENGINE – Either 'django.db.backends.sqlite3','django.db.backends.postgresql','django.db.backends.mysql',or 'django.db.backends.oracle'. Other backends are also available.
    * NAME – The name of your database. If you’re using SQLite,the database will be a file on your computer; in that case,NAME should be the full absolute path,including filename,of that file. The default value,os.path.join(BASE_DIR,'db.sqlite3'),will store the file in your project directory.
    
    If you are not using SQLite as your database,additional settings such as USER,PASSWORD,and HOST must be added. For more details,see the reference documentation for DATABASES.

     

  • 建立完App後,根據settings.py裡的設定內容,在資料庫中建立表
1.$ python manage.py migrate       

The migrate command looks at the INSTALLED_APPS setting and creates any necessary database tables according to the database settings in your mysite/settings.py file and the database migrations shipped with the app (we’ll cover those later). You’ll see a message for each migration it applies. If you’re interested,run the command-line client for your database and type \dt (PostgreSQL),SHOW TABLES; (MariaDB,MySQL),.schema (SQLite),or SELECT TABLE_NAME FROM USER_TABLES; (Oracle) to display the tables Django created.
  • Creating models
Now we’ll define your models – essentially,your database layout,with additional metadata.
These concepts are represented by Python classes. Edit the polls/models.py file so it looks like this:

Example:
from django.db import models

class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')

class Choice(models.Model):
    question = models.ForeignKey(Question,on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)
  • Activating models
That small bit of model code gives Django a lot of information. With it,Django is able to:
* Create a database schema (CREATE TABLE statements) for this app.
* Create a Python database-access API for accessing Question and Choice objects.

But first we need to tell our project that the polls app is installed. #首先要告訴你的專案,polls這個app已經註冊了,就是在settings裡面新增過。

mysite/settings.py:

INSTALLED_APPS = [
    'polls.apps.PollsConfig','django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles',]

確認APP已經註冊過的情況下,可以執行:
$ python manage.py makemigrations polls

You should see something similar to the following:
Migrations for 'polls':
  polls/migrations/0001_initial.py:
    - Create model Choice
    - Create model Question
    - Add field question to choice

資料庫有任何修改,都可以執行
By running makemigrations,you’re telling Django that you’ve made some changes to your models (in this case,you’ve made new ones) and that you’d like the changes to be stored as a migration.
  • 資料遷移定義
There’s a command that will run the migrations for you and manage your database schema automatically - that’s called migrate,and we’ll come to it in a moment - but first,let’s see what SQL that migration would run. 
  • The sqlmigrate command takes migration names and returns their SQL: 資料遷移之前,需要執行

$ python manage.py sqlmigrate polls 0001

You should see something similar to the following (we’ve reformatted it for readability):
BEGIN;---- Create model Choice--CREATE TABLE "polls_choice" (
    "id" serial NOT NULL PRIMARY KEY,"choice_text" varchar(200) NOT NULL,"votes" integer NOT NULL);---- Create model Question--CREATE TABLE "polls_question" (
    "id" serial NOT NULL PRIMARY KEY,"question_text" varchar(200) NOT NULL,"pub_date" timestamp with time zone NOT NULL);---- Add field question to choice--ALTER TABLE "polls_choice" ADD COLUMN "question_id" integer NOT NULL;ALTER TABLE "polls_choice" ALTER COLUMN "question_id" DROP DEFAULT;CREATE INDEX "polls_choice_7aa0f6ee" ON "polls_choice" ("question_id");ALTER TABLE "polls_choice"
  ADD CONSTRAINT "polls_choice_question_id_246c99a640fbbd72_fk_polls_question_id"
    FOREIGN KEY ("question_id")
    REFERENCES "polls_question" ("id")
    DEFERRABLE INITIALLY DEFERRED;
COMMIT;
  • Now,run migrate again to create those model tables in your database:再次執行migrate,用於建立模型對應的資料庫庫表。The migrate command takes all the migrations that haven’t been applied (Django tracks which ones are applied using a special table in your database called django_migrations) and runs them against your database - essentially,synchronizing the changes you made to your models with the schema in the database.
$ python manage.py migrate
Operations to perform:  Apply all migrations: admin,auth,contenttypes,polls,sessionsRunning migrations:  Rendering model states... DONE  Applying polls.0001_initial... OK
  • 後續資料庫有任何改動,需要牢記以下三個步驟:
    We’ll cover them in more depth in a later part of the tutorial,remember the three-step guide to making model changes:
    * Change your models (in models.py).
    * Run python manage.py makemigrations to create migrations for those changes
    * Run python manage.py migrate to apply those changes to the database.

     

呼叫資料庫API

  •  開啟shell互動介面,可以呼叫資料庫API,實現資料庫內資料的增刪改查:

我根據這個連結中的步驟,建立賬戶,呼叫API,但是開啟shell介面,新增資料的時候,遇到了一點問題:https://www.zmrenwu.com/courses/hellodjango-blog-tutorial/materials/62/

  • 建立賬戶:
(Python36) [root@8ee837cc23a4 myblog]# python manage.py createsuperuser
鐢ㄦ埛鍚� (leave blank to use 'root'): Katelyn
Error: That 鐢ㄦ埛鍚� is already taken.
鐢ㄦ埛鍚� (leave blank to use 'root'): ZW
鐢靛瓙閭歡鍦板潃: [email protected]
Password:
Password (again):
Superuser created successfully.
  • 開啟shell:
(Python36) [root@8ee837cc23a4 myblog]# python manage.py shell
Python 3.6.2 |Continuum Analytics,Inc.| (default,Jul 20 2017,13:51:32)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-1)] on linux
Type "help","copyright","credits" or "license" for more information.
(InteractiveConsole)
>>> from blog.models import Category,Tag,Post                    //需要匯入在models.py中定義過的類,每次進入都需要重新匯入
>>> from django.utils import timezone
>>> from django.contrib.auth.models import User
>>> user = User.object.get(username='myuser')
Traceback (most recent call last):
  File "<console>",line 1,in <module>
AttributeError: type object 'User' has no attribute 'object'      //這裡是因為輸入的命令有錯誤,是User.objects.get()

//但是這裡我遇到的真正問題是,沒有執行    python manage.py sqlmigrate blog 0001

>>> user = User.object.get(username='Katelyn')
Traceback (most recent call last):
  File "<console>",in <module>
AttributeError: type object 'User' has no attribute 'object'
>>> user = User.object.get(username='test')
Traceback (most recent call last):
  File "<console>",in <module>
AttributeError: type object 'User' has no attribute 'object'
>>> from django.contrib.auth.models import User
>>> user =User.object.get(username = 'test')
Traceback (most recent call last):
  File "<console>",in <module>
AttributeError: type object 'User' has no attribute 'object'                   //這三個使用者名稱都註冊過,但是就是顯示type object 'User' has no attribute 'object'
>>> quit()

後續,查閱文件後:
(Python36) [root@8ee837cc23a4 myblog]# python manage.py migrate
Operations to perform:
  Apply all migrations: admin,blog,sessions
Running migrations:
  No migrations to apply.
(Python36) [root@8ee837cc23a4 myblog]#  python manage.py sqlmigrate blog 0001
BEGIN;
--
-- Create model Category
--
CREATE TABLE "blog_category" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,"name" varchar(256) NOT NULL);
--
-- Create model Tag
--
CREATE TABLE "blog_tag" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,"name" varchar(70) NOT NULL);
--
-- Create model Post
--
CREATE TABLE "blog_post" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,"title" varchar(128) NOT NULL,"body" text NOT NULL,"created_time" datetime NOT NULL,"modified_time" datetime NOT NULL,"excerpt" varchar(200) NOT NULL,"author_id" integer NOT NULL REFERENCES "auth_user" ("id") DEFERRABLE INITIALLY DEFERRED,"category_id" integer NOT NULL REFERENCES "blog_category" ("id") DEFERRABLE INITIALLY DEFERRED);
CREATE TABLE "blog_post_tags" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,"post_id" integer NOT NULL REFERENCES "blog_post" ("id") DEFERRABLE INITIALLY DEFERRED,"tag_id" integer NOT NULL REFERENCES "blog_tag" ("id") DEFERRABLE INITIALLY DEFERRED);
CREATE INDEX "blog_post_author_id_dd7a8485" ON "blog_post" ("author_id");
CREATE INDEX "blog_post_category_id_c326dbf8" ON "blog_post" ("category_id");
CREATE UNIQUE INDEX "blog_post_tags_post_id_tag_id_4925ec37_uniq" ON "blog_post_tags" ("post_id","tag_id");
CREATE INDEX "blog_post_tags_post_id_a1c71c8a" ON "blog_post_tags" ("post_id");
CREATE INDEX "blog_post_tags_tag_id_0875c551" ON "blog_post_tags" ("tag_id");
COMMIT;
//到這裡才算是激活了

之後開啟shell:

>>> from blog.models import Category,Post
>>> c=Category.objects.get(id=1)                     //可以用get.(id=1)查詢到第一個建立成功的資料
>>> p =Post(title='title test',body='body test',created_time=timezone.now(),modified_time=timezone.now(),category=c,author=user)
>>> p.save()                                         //每一次建立的時候都需要儲存
>>> Post.objects.all()                               //可以通過 Post(類名).objects.all()查詢所有資料
<QuerySet [<Post: title test>]>
>>> Tag.objects.all()
<QuerySet [<Tag: tag test>,<Tag: tag test>]>
>>> Category.objects.all()
<QuerySet [<Category: category test>,<Category: category test>]>
>>> c= Category.objects.get(id=1)
>>> c.name = 'category test new'
>>> c.save()
>>> Category.objects.all()
<QuerySet [<Category: category test new>,<Category: category test>]>
>>> a =Category.objects.get(id=2)
>>> a
<Category: category test>
>>> a.delete()
(1,{'blog.Category': 1})
>>> Category.objects.all()
<QuerySet [<Category: category test new>]>

//嘗試在建立語句中不使用剛建立的變數,發現不行:
>>> from blog.models import Category,Post
>>> from django.utils import timezone                          
>>> p = Post(title='title test',modified_time=timezone.now().category=Category.objects.get(id=1),author=User.objects.get(id=1))
  File "<console>",line 1
    p = Post(title='title test',author=User.objects.get(id=1))                                                                                                                  ^
SyntaxError: invalid syntax
只能通過先取出值,存在變數裡面的方式:
>>> c=User.objects.get(id=3)
>>> c
<User: test>
>>> c.delete()                          //刪除資料
(2,{'admin.LogEntry': 0,'auth.User_groups': 0,'auth.User_user_permissions': 0,'blog.Post_tags': 0,'blog.Post': 1,'auth.User': 1})  //會連帶將包含該資料的其他資料也刪掉,比如這裡的Post:'blog.Post': 1
>>> c
<User: test>
>>> user = User.objects.all()     
>>> user                             //可以直接檢視變數值
<QuerySet [<User: Katelyn>]>
>>> c = Category.objects.get(name='category test')   //查詢類中name='category test' 的資料
Traceback (most recent call last):
  File "<console>",in <module>
  File "/root/anaconda3/envs/Python36/lib/python3.6/site-packages/django/db/models/manager.py",line 82,in manager_method
    return getattr(self.get_queryset(),name)(*args,**kwargs)
  File "/root/anaconda3/envs/Python36/lib/python3.6/site-packages/django/db/models/query.py",line 417,in get
    self.model._meta.object_name
blog.models.Category.DoesNotExist: Category matching query does not exist.    //不存在時候會直接提示
>>> Category.objects.all()
<QuerySet [<Category: category test new>]>
>>> c=Category.objects.get(id=1)
>>> c
<Category: category test new>
>>> p =Post(title='title test',author=user)
Traceback (most recent call last):
  File "<console>",in <module>
  File "/root/anaconda3/envs/Python36/lib/python3.6/site-packages/django/db/models/base.py",line 482,in __init__
    _setattr(self,field.name,rel_obj)
  File "/root/anaconda3/envs/Python36/lib/python3.6/site-packages/django/db/models/fields/related_descriptors.py",line 219,in __set__
    self.field.remote_field.model._meta.object_name,ValueError: Cannot assign "<QuerySet [<User: Katelyn>]>": "Post.author" must be a "User" instance.  //這裡的user沒有定義過,所以需要重新獲取一下
>>> p
Traceback (most recent call last):
  File "<console>",in <module>
NameError: name 'p' is not defined

//成功的操作:
c已經在上面獲取過了
>>> user=User.objects.get(id=1)   
>>> user
<User: Katelyn>
>>> p =Post(title='title test',author=user)
>>> p
<Post: title test>
>>> p.save()
>>> Post.objects.all()
<QuerySet [<Post: title test>]>