0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

マイクロソフト Access を利用した、Djangoの学習入門(モデル操作編その4):データベースのテーブル名と列名の宣言について

0
Posted at

この記事では、Django 6.0 から、マイクロソフト Access のデータベースファイル(.accdbファイル)を操作しております。
django-msaccess パッケージを使います。settings.pyDATABASES の変更が必要です。

settings.py
DATABASES = {
    'default': {  
        'ENGINE': 'django-msaccess',  
        'ODBC': '{Microsoft Access Driver (*.mdb, *.accdb)}',  
        'PATH': 'C:\\Work\\MyNewDatabase.accdb(Accessデータベースファイルのフルパス)',  
        'DEBUG': False,  
        'TRUNCATENAME': True,  
    },
}

このような設定にしてください。

1.はじめに(Djangoの使用目的とは?)

本記事ではPython言語を使って、Webアプリケーションを開発するときに利用するDjangoについて学習をしています。そのDjangoをどのような場面で使うのか、その目的を知りたいと思っている方もおられるのではないでしょうか。
簡単に説明をしますと、マイクロソフト Access で開発された Windows上で動作している デスクトップ データベース アプリケーション を、マイクロソフト Edge などのブラウザ内で動作する Webアプリケーションに置き換える作業において、そのデータベース サーバー 側のシステム開発でDjangoを使います。つまり、Access アプリケーションDX化という開発作業で、Django が必要不可欠になります。
マイクロソフト Access で作られたフォーム(画面上の入出力)は、ブラウザの中で表示されるWebアプリケーションに変換をします。この部分は、ReactMaterial-UI の Web-GUI技術を使用します。使用する言語は、JavaScriptになります。
マイクロソフト Access で作られたレポート(プリンタの帳票印刷)は、Python言語から利用できる ReportLabオープンソースReportLab PDF library を使用して、PDFに変換を行います。PDFの情報は、Djangoview機能によってブラウザ側に送信され、ブラウザの画面内でPDFの内容が表示されます。
Djangoは、データベースからテーブルのレコードを読み出したり、レコードを保存する部分でも使用されます。 ブラウザの中で動くJavaScriptプログラムから、REST API(Representational State Transfer API)を通してDjangoと通信を行います。
PDFの作成はDjangoの中で動くため、Djangoのモデル操作を通して、ReportLab PDF libraryを使いながらPDFを作成し、作成したPDFをブラウザ側に送信します。
そして上記の動作のほとんどはデータベース操作になりますので、Djangoモデル操作方法がその中心になります。

 Djangoには多くの機能が含まれていますが、マイクロソフト Access で開発されたデスクトップ データベース アプリケーションWebアプリケーション に変換する開発では、Djangoモデル操作プログラムがその中心と言っても良い重要な要素になります。もちろんブラウザ内ではJavaScriptを活用していますので、Pythonだけではなく、JavaScriptの知識も必要です。
重要なことは、Djangoモデル操作プログラムで、直接SQL文を操作しない限り、データベースの製品に関してはあまり意識をしなくて済むようになります。このため、Accessを使ってDjangoを学習して得られた知識は、他社のデータベースをDjangoから使うときでもそのまま役立つことになります。

2.復習を兼ねて、テーブルを作成してみます

 Django から使用するデータベースのテーブルは、そのテーブルの列構成などの情報を事前に、Djangomodels.py プログラムの中に宣言をします。

models.py
from django.db import models

# Create your models here.
class Person(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)

このような models.py があるとします。

class Person(models.Model): の宣言によって、このデータベースのテーブルは、Person テーブルと表現されます。この Person という名前は、Django のPythonプログラムの中からこのテーブルを操作するときに使われる名前であり、実際のデータベースに作成されているテーブルとは名前が異なる場合があるので、注意しておきます。
このテーブル宣言では2つの列があり、1つはfirst_name列、もう1つはlast_name列の名前です。この名前も、実際のデータベースに作成されているテーブルの列名とは名前が異なる場合があるので、注意しておきます。なお主キー列の宣言が省略された場合は、Djangoによってオートナンバー型の名前idの列が追加されますので、このPersonテーブルは、主キーを含めて全部で3列構成になります。主キーの宣言方法などに関しては、次回以降に説明を致します。

CharFieldは列のデータ型を表しており、引数のmax_length=30によって最大30文字を覚える文字列型となります。列の型に関しては、次回以降に説明をします。

それでは、テーブルを作成してみましょう。

マイクロソフト Access の空のデータベースファイルを準備してください。ここでは、
C:\Work\MyNewDatabase.accdb に、空のデータベースファイルが置かれています。

Pythonの仮想環境を起動して、Djangoのプロジェクトを次のように新規に作成をします(多くの方はすでに作られているのでこの操作は不要ですが、今回この記事を初めて目にする方はプロジェクトを作ってください)。

※Python仮想環境は py -m venv venv コマンドで作成済です。それを使います。

C:\Work>venv\scripts\activate

※DJLearnプロジェクトの作成を行います
(venv) C:\Work>django-admin.exe startproject DJLearn

DJLearnプロジェクトを作成したら、C:\Work\DJLearn\DJLearn\settings.pyファイルの以下の部分を修正してください。

settings.py の DATABASE宣言部分の修正
DATABASES = {  
    'default': {  
        'ENGINE': 'django-msaccess',  
        'ODBC': '{Microsoft Access Driver (*.mdb, *.accdb)}',  
        'PATH': 'C:\\Work\\MyNewDatabase.accdb',  
        'DEBUG': False,  
        'TRUNCATENAME': True,  
    },
}
settings.py の LANGUAGE_CODE宣言部分の修正
LANGUAGE_CODE = 'ja'
settings.py の TIME_ZONE宣言部分の修正
TIME_ZONE = 'Asia/Tokyo'

settings.pyファイルの、3か所の修正を行います。

C:\Work\MyNewDatabase.accdbに、空のaccdbファイルが置かれていることを確認して、DjangoのL01アプリケーションを作成します。

DjangoのL01アプリケーションを作成する
(venv) C:\Work>cd DJLearn

(venv) C:\Work\DJLearn>python manage.py startapp L01

(venv) C:\Work\DJLearn>dir
2026/02/16  13:14    <DIR>          .
2026/02/16  13:14    <DIR>          ..
2026/02/16  13:14    <DIR>          DJLearn
2026/02/16  13:14    <DIR>          L01
2026/02/16  12:58               685 manage.py

L01アプリケーションを作成したら、settings.pyに、そのアプリケーションの登録を行います。次の個所を追加します。

settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    
    'L01.apps.L01Config'   この行を追加する

]

L01ディレクトリ内のapps.pyファイルに、次のような宣言があります。

apps.py
from django.apps import AppConfig

class L01Config(AppConfig):
    name = 'L01'

このclass L01Config(AppConfig):の参照を、settings.pyの中に追加しました。

また、L01ディレクトリの中の、models.pyファイルの内容を、冒頭のPersonテーブル定義に修正しておきます。

(venv) C:\Work\DJLearn>cd L01

(venv) C:\Work\DJLearn\L01>dir
2026/02/16  13:14    <DIR>          .
2026/02/16  13:14    <DIR>          ..
2026/02/16  13:14                66 admin.py
2026/02/16  13:14                86 apps.py
2026/02/16  13:14    <DIR>          migrations
2026/02/16  13:14               188 models.py  ※このファイルを修正します
2026/02/16  13:14                63 tests.py
2026/02/16  13:14                66 views.py
2026/02/16  13:14                 0 __init__.py

以上の事前環境を作業していれば、次のコマンドで、マイクロソフト Access の空のデータベースファイルの中に、テーブルを作成することができます。

マイクロソフト Accessのデータベースにテーブルを作成する
(venv) C:\Work\DJLearn>python manage.py makemigrations
Migrations for 'L01':
  L01\migrations\0001_initial.py
    + Create model Person


※sqlmigrateコマンドで、変更箇所をデータベースに反映させるためのSQL文を表示します
(venv) C:\Work\DJLearn>python manage.py sqlmigrate L01 0001
--
-- Create model Person
--
CREATE TABLE [L01_person] ([id] COUNTER NOT NULL PRIMARY KEY, [first_name] varchar(30) NOT NULL, [last_name] varchar(30) NOT NULL);


※migrateコマンドで、変更箇所をデータベースに反映させます
(venv) C:\Work\DJLearn>python manage.py migrate
Operations to perform:
  Apply all migrations: L01, admin, auth, contenttypes, sessions
Running migrations:
  Applying L01.0001_initial... OK
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying contenttypes.0002_remove_content_type_name...


vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
                    Ignore SQL Statement.
              [CursorWrapper.execute(base.py)]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[EXECUTE_SQL]sql=SAVEPOINT [s10740_x1]
This SQL statement cannot be executed in Microsoft Access.
The execution of this SQL statement will be ignored.


vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
                    Ignore SQL Statement.
              [CursorWrapper.execute(base.py)]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[EXECUTE_SQL]sql=RELEASE SAVEPOINT [s10740_x1]
This SQL statement cannot be executed in Microsoft Access.
The execution of this SQL statement will be ignored.

 OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying auth.0010_alter_group_name_max_length... OK
  Applying auth.0011_update_proxy_permissions...


vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
                    Ignore SQL Statement.
              [CursorWrapper.execute(base.py)]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[EXECUTE_SQL]sql=SAVEPOINT [s10740_x2]
This SQL statement cannot be executed in Microsoft Access.
The execution of this SQL statement will be ignored.


vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
                    Ignore SQL Statement.
              [CursorWrapper.execute(base.py)]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[EXECUTE_SQL]sql=RELEASE SAVEPOINT [s10740_x2]
This SQL statement cannot be executed in Microsoft Access.
The execution of this SQL statement will be ignored.


 OK
  Applying auth.0012_alter_user_first_name_max_length... OK
  Applying sessions.0001_initial... OK

(venv) C:\Work\DJLearn>

以上の操作によって、
C:\Work\MyNewDatabase.accdb
のファイルの中に、L01_personテーブルが作成されたことがわかります。

L01_personテーブル
L01_personテーブル.png

3.テーブルの名前を宣言しましょう

3.1 Djangoが付けるデフォルトのテーブル名

Accessに作成されたテーブル名は、L01_personという名前で作成されました。左側のL01は、
Djangoに作成したアプリケーションの名前L01のことです。右側のpersonは、models.pyの中で宣言を行った class Person(models.Model): の名前です。英字の大小の違いはありますが、データベースに作成されるテーブル名の定義を省略した場合は、このように、アプリケーションの名前_modelsの中のクラス名 となって、実際のテーブル名が採用されます。

3.2 テーブルの名前に使用できる文字の中には、特殊な文字も許される

 あまりおすすめはできませんが、データベースのテーブルの名前に使用できる文字の中には、空白文字や記号文字など、そのデータベースで使用できる文字が決められています。少なくとも、Python言語で決められているclass宣言のクラス名で使用できる文字よりは、はるかに多くの特殊な文字が、テーブルの名前には使用できるようになっています。
このようなクラス宣言(class Person(models.Model):)では、 空白文字が含まれているテーブル名を定義することはできません。

 このように、Python言語で使用できるクラス名に使用できる文字の種類よりも、はるかに多くの文字の種類が、データベースのテーブル名に使用できる文字として許されています。

3.3 Metaクラスのdb_table定義を行う

そこでこのような特殊な文字を使用したり、あるいは(実際はこちらの理由が多いですが)、データベースのテーブル名を正しく定義したりする目的で、Metaクラスを宣言します。

models.py(Person宣言の中にMetaクラス宣言を追加した)
from django.db import models

# Create your models here.
class Person(models.Model):
    class Meta:
        db_table='個人管理'
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)

class Person(models.Model): 宣言の中に、class Meta: 宣言を埋め込みます。そのMetaクラス宣言の中に、db_table='テーブルの名前' を定義します。この例では、データベースの中に作成されるテーブルの名前は、個人管理としました。

models.py を、上記のように修正を行ってください。修正したら、マイグレーションファイルの作成を行います。今までアプリケーションの名前を省略してmakemigrationsコマンドを実行していましたが、アップリケーションの名前を指定します。

(venv) C:\Work\DJLearn>python manage.py makemigrations L01
Migrations for 'L01':
  L01\migrations\0002_alter_person_table.py
    ~ Rename table for person to 個人管理

(venv) C:\Work\DJLearn>dir L01\migrations
2026/02/16  17:31    <DIR>          .
2026/02/16  17:31    <DIR>          ..
2026/02/16  13:25               580 0001_initial.py
2026/02/16  17:31               335 0002_alter_person_table.py
2026/02/16  13:14                 0 __init__.py
2026/02/16  13:26    <DIR>          __pycache__

(venv) C:\Work3\DJLearn>python manage.py sqlmigrate L01 0002
※これは実行できません。エラーになります。またmigrateコマンドも実行できません。

本来であれば、python manage.py sqlmigrate L01 0002によって、0002_alter_person_table.pyで実行されるSQL文が表示されるのですが、エラーになります。
AccessのSQL文の文法では、テーブルの名前を変更するSQL文が存在しないのです。すでに作成済みのテーブルの名前を変更することができません。

このため、Djangoの中でAccessデータベースを使用するときは、最初からMetaクラスのdb_table定義を行うようにしてください。

なお、どうしてもAccessのテーブルの名前を変更する場合は、次のようなVBScriptを実行します。

Accessのテーブルの名前を変更するVBScript
rename.vbs(ファイルの文字コードはシフトJIS系で保存してください)
Dim dbPath, oldName, newName
dbPath  = "C:\Work\MyNewDatabase.accdb"
oldName = "L01_person"
newName = "個人管理"

Dim daoEngine, db, tdf

On Error Resume Next

Set daoEngine = CreateObject("DAO.DBEngine.120")
Set db = daoEngine.OpenDatabase(dbPath, True)

If Err.Number <> 0 Then
    MsgBox "データベースを開けませんでした: " & Err.Description
    WScript.Quit
End If

' テーブル名の変更
Set tdf = db.TableDefs(oldName)

If Err.Number = 0 Then
    tdf.Name = newName
    MsgBox "テーブル名を '" & oldName & "' から '" & newName & "' に変更しました。"
Else
    MsgBox "テーブルが見つかりません: " & oldName
End If

' 終了処理
db.Close
Set tdf = Nothing
Set db = Nothing
Set daoEngine = Nothing

ANSI(シフトJIS,CP932系の文字コード)でファイルを作成し、32ビット版(c:\windows\syswow64\cscript)または64ビット版(c:\windows\system32\cscript)のVBScriptで実行します(インストールされたAccessのビット数に合わせてください)。

4.列の名前を宣言しましょう

4.1 Djangoが付けるデフォルトの列の名前

列の名前は、class Person(models.Model):の中で宣言された変数名が、そのまま列の名前に採用されます。

  first_name = models.CharField(max_length=30)
  last_name = models.CharField(max_length=30)

左辺の変数名first_namelast_nameが、列の名前になります。

4.2 列の名前に使用できる文字の中には、特殊な文字も許される

テーブルの名前に使用できる文字の種類が、Python言語のクラス名に使用できる文字の種類より多いのと同様に、列の名前に関しても、同じです。このため空白や特殊な記号文字などが列の名前に使用されている場合は、CharFieldなどのデータ型宣言の引数の中に、テーブルの列の名前を定義するオプション(db_column)があります。

4.3 列の名前を定義するdb_columnオプションを使う

models.py
from django.db import models

# Create your models here.
class Person(models.Model):
    class Meta:
        db_table='個人管理'
    first_name = models.CharField(db_column='下の名前',max_length=30)
    last_name = models.CharField(db_column='苗字', max_length=30)

first_name列は、実際のテーブルの列名は、

db_column='下の名前'

によって、下の名前という列名になっています。
同様にlast_name列は、

db_column='苗字'

によって、苗字という列名になっています。

このようにmodels.pyを変更して、マイグレーションファイルを作成します。

(venv) C:\Work\DJLearn>python manage.py makemigrations L01
Migrations for 'L01':
  L01\migrations\0003_alter_person_first_name_alter_person_last_name.py
    ~ Alter field first_name on person
    ~ Alter field last_name on person

0003番の実行されるSQL文を表示してみます。

(venv) C:\Work\DJLearn>python manage.py sqlmigrate L01 0003
--
-- Alter field first_name on person
--
ALTER TABLE [個人管理] RENAME COLUMN [first_name] TO [下の名前];
--
-- Alter field last_name on person
--
ALTER TABLE [個人管理] RENAME COLUMN [last_name] TO [苗字];

※`L01_person`テーブルの名前は、VBScriptなどによって`個人管理`というテーブル名に変更済みになっています。

一見正しそうなSQL文に見えますが、これは間違っています。
AccessのSQL文を使って列名を変更するためには、その列名を削除した後に、新しい列名で再作成を行うという手順を取ります。このため、migrateコマンドを使って列名を変更することはできません。
もし列名を変更する場合は、次のようなVBScriptを実行します。

Accessのテーブルの列の名前を変更するVBScript
列名を変更するプログラム.vbs(ファイルの文字コードはシフトJIS系で保存してください)
Option Explicit
Dim dbPath, tableName, i, oldColName(1), newColName(1)
dbPath     = "C:\Work\MyNewDatabase.accdb"
tableName  = "個人管理"                      ' 対象のテーブル名
oldColName(0) = "first_name"                ' 変更前の列名
newColName(0) = "下の名前"                   ' 変更後の列名

oldColName(1) = "last_name"                 ' 変更前の列名
newColName(1) = "苗字"                      ' 変更後の列名

Dim engine, db, tdf, fld

On Error Resume Next

Set engine = CreateObject("DAO.DBEngine.120")
If Err.Number <> 0 Then
    MsgBox "DAOエンジンがインストールされていないか、バージョンが異なります。" & vbCrLf & Err.Description, 16
    WScript.Quit
End If

' データベースをオープン (共有モード、読み書き可能)
Set db = engine.OpenDatabase(dbPath)

If Err.Number <> 0 Then
    MsgBox "データベースを開けませんでした。パスを確認してください。" & vbCrLf & Err.Description, 16
    WScript.Quit
End If

' テーブル定義(TableDef)を取得
Set tdf = db.TableDefs(tableName)

' フィールド名を変更
' Fieldsコレクションから既存の列名を指定して書き換える
For i = 0 To UBound(oldColName)
    Set fld = tdf.Fields(oldColName(i))
    If Err.Number = 0 Then
        fld.Name = newColName(i)
        MsgBox "列名 '" & oldColName(i) & "' を '" & newColName(i) & "' に変更しました。", 64
    Else
        MsgBox "指定された列名が見つかりませんでした。", 48
    End If
    Set fld = Nothing
Next


' 後処理
db.Close
Set tdf = Nothing
Set db = Nothing
Set engine = Nothing
On Error GoTo 0

上記のVBScriptを実行して、列名を変更します。

5.まとめ

models.pyの中のclass Person(models.Model):テーブル宣言は、あくまでもPython言語のプログラムの中から使用するテーブルの名前であり、実際のデータベースの中に作成されたテーブル名とは異なります。
その実際のテーブル名は、

class Meta:
    db_table='個人管理'

のように、Metaクラスのdb_table宣言を行います。
同様に列の宣言についても、db_column='苗字'のように、db_column引数で実際のテーブルの中の列名を宣言します。
そして何よりも重要なことは、マイクロソフト Access のデータベースでは、すでに存在するテーブルや列の名前を変更するためのSQL文は、存在しないということです。
このため、AccessのデータベースをDjangoから使用するときは、最初のmodels.pyを作成する時点で、実際のテーブル名や列名を宣言しておくことが必要になります。この点に注意しながら、マイクロソフト Access のデータベースを、Djangoから使いましょう。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?