基于django2.2連oracle11g解決版本沖突的問(wèn)題
上次用django2.2和oracle11g,在migrate的時(shí)候發(fā)生了版本沖突,最終將Oracle升級(jí)到了12c才解決問(wèn)題
那么到底能不能用別的方法來(lái)解決這個(gè)沖突呢?想了個(gè)解決思路,實(shí)踐一下:
用django2.2連Oracle12c環(huán)境下做migrate,創(chuàng)建基礎(chǔ)表
將基礎(chǔ)表導(dǎo)出,再導(dǎo)入到Oracle11g數(shù)據(jù)庫(kù)中
用django2.2連Oracle11g
實(shí)施步驟
1、用django2.2連Oracle12c環(huán)境下做migrate,創(chuàng)建基礎(chǔ)表
在前文中已經(jīng)完成,連接到數(shù)據(jù)庫(kù),可以看到有10張基礎(chǔ)表

看一張表,比如AUTH_GROUP表,發(fā)現(xiàn)有個(gè)ID字段是用了12c特有的generated語(yǔ)法,除了DJANGO_SESSION外,其他每張表都有一個(gè)自增序列的id字段作為主鍵。
-- Create table create table AUTH_GROUP ( id NUMBER(11) generated by default on null as identity, name NVARCHAR2(150) ) tablespace DJANGO; -- Create/Recreate primary, unique and foreign key constraints alter table AUTH_GROUP add primary key (ID) using index tablespace DJANGO; alter table AUTH_GROUP add unique (NAME) using index tablespace DJANGO;
2. 將基礎(chǔ)表導(dǎo)出,再導(dǎo)入到Oracle11g數(shù)據(jù)庫(kù)中
導(dǎo)出django用戶數(shù)據(jù)庫(kù),注意使用11g版本

接著導(dǎo)入到11g數(shù)據(jù)庫(kù)中,非常順利

再看AUTH_GROUP表,發(fā)現(xiàn)表結(jié)構(gòu)是一樣的,但是id上面自增序列的默認(rèn)值沒(méi)有了。
-- Create table create table AUTH_GROUP ( id NUMBER(11) not null, name NVARCHAR2(150) ) tablespace DJANGO; -- Create/Recreate primary, unique and foreign key constraints alter table AUTH_GROUP add primary key (ID) using index tablespace DJANGO; alter table AUTH_GROUP add unique (NAME) using index tablespace DJANGO;
3、用django2.2連Oracle11g
修改settings文件,連Oracle11g,然后啟動(dòng)django服務(wù),果然成功啟動(dòng)


但是,但是,創(chuàng)建admin用戶密碼的時(shí)候就報(bào)錯(cuò)了,ORA-01400: cannot insert NULL into (“DJANGO”.“AUTH_USER”.“ID”)
PS D:\parttime\python\django\guanxiangzhiji> python manage.py createsuperuser
用戶名 (leave blank to use 'administrator'):
電子郵件地址:
Password:
Password (again):
密碼長(zhǎng)度太短。密碼必須包含至少 8 個(gè)字符。
這個(gè)密碼太常見(jiàn)了。
Bypass password validation and create user anyway? [y/N]: y
Traceback (most recent call last):
File "D:\app\anaconda\lib\site-packages\django\db\backends\utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "D:\app\anaconda\lib\site-packages\django\db\backends\oracle\base.py", line 510, in execute
return self.cursor.execute(query, self._param_generator(params))
cx_Oracle.IntegrityError: ORA-01400: cannot insert NULL into ("DJANGO"."AUTH_USER"."ID")
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "manage.py", line 21, in <module>
main()
File "manage.py", line 17, in main
execute_from_command_line(sys.argv)
File "D:\app\anaconda\lib\site-packages\django\core\management\__init__.py", line 381, in execute_from_command_line
utility.execute()
File "D:\app\anaconda\lib\site-packages\django\core\management\__init__.py", line 375, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "D:\app\anaconda\lib\site-packages\django\core\management\base.py", line 323, in run_from_argv
self.execute(*args, **cmd_options)
File "D:\app\anaconda\lib\site-packages\django\contrib\auth\management\commands\createsuperuser.py", line 61, in execute
return super().execute(*args, **options)
File "D:\app\anaconda\lib\site-packages\django\core\management\base.py", line 364, in execute
output = self.handle(*args, **options)
File "D:\app\anaconda\lib\site-packages\django\contrib\auth\management\commands\createsuperuser.py", line 156, in handle
self.UserModel._default_manager.db_manager(database).create_superuser(**user_data)
File "D:\app\anaconda\lib\site-packages\django\contrib\auth\models.py", line 162, in create_superuser
return self._create_user(username, email, password, **extra_fields)
File "D:\app\anaconda\lib\site-packages\django\contrib\auth\models.py", line 145, in _create_user
user.save(using=self._db)
File "D:\app\anaconda\lib\site-packages\django\contrib\auth\base_user.py", line 66, in save
super().save(*args, **kwargs)
File "D:\app\anaconda\lib\site-packages\django\db\models\base.py", line 741, in save
force_update=force_update, update_fields=update_fields)
File "D:\app\anaconda\lib\site-packages\django\db\models\base.py", line 779, in save_base
force_update, using, update_fields,
File "D:\app\anaconda\lib\site-packages\django\db\models\base.py", line 870, in _save_table
result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
File "D:\app\anaconda\lib\site-packages\django\db\models\base.py", line 908, in _do_insert
using=using, raw=raw)
File "D:\app\anaconda\lib\site-packages\django\db\models\manager.py", line 82, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "D:\app\anaconda\lib\site-packages\django\db\models\query.py", line 1186, in _insert
return query.get_compiler(using=using).execute_sql(return_id)
File "D:\app\anaconda\lib\site-packages\django\db\models\sql\compiler.py", line 1335, in execute_sql
cursor.execute(sql, params)
File "D:\app\anaconda\lib\site-packages\django\db\backends\utils.py", line 99, in execute
return super().execute(sql, params)
File "D:\app\anaconda\lib\site-packages\django\db\backends\utils.py", line 67, in execute
return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
File "D:\app\anaconda\lib\site-packages\django\db\backends\utils.py", line 76, in _execute_with_wrappers
return executor(sql, params, many, context)
File "D:\app\anaconda\lib\site-packages\django\db\backends\utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "D:\app\anaconda\lib\site-packages\django\db\utils.py", line 89, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "D:\app\anaconda\lib\site-packages\django\db\backends\utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "D:\app\anaconda\lib\site-packages\django\db\backends\oracle\base.py", line 510, in execute
return self.cursor.execute(query, self._param_generator(params))
django.db.utils.IntegrityError: ORA-01400: cannot insert NULL into ("DJANGO"."AUTH_USER"."ID")
原因分析
很明顯,插入到AUTH_USER表時(shí),沒(méi)有指定ID的值,而ID是主鍵,非空。
因?yàn)樵?2c的環(huán)境下,這個(gè)ID是自增序列,insert語(yǔ)句中不需要指定這個(gè)值。
解決方案
解決方案也應(yīng)運(yùn)而出了,只要為每個(gè)ID列創(chuàng)建一個(gè)11g的序列,創(chuàng)建觸發(fā)器,在插入數(shù)據(jù)時(shí)補(bǔ)上id值就行了。
(1)生成序列。
用sql語(yǔ)句
select 'create sequence seq_'||table_name||' minvalue 1 maxvalue 999999999 start with 1 increment by 1 cache 20;' from user_tab_columns where column_name='ID';
生成創(chuàng)建序列的批量執(zhí)行語(yǔ)句,并執(zhí)行。
create sequence seq_DJANGO_ADMIN_LOG minvalue 1 maxvalue 999999999 start with 1 increment by 1 cache 20; create sequence seq_AUTH_USER minvalue 1 maxvalue 999999999 start with 1 increment by 1 cache 20; create sequence seq_AUTH_USER_GROUPS minvalue 1 maxvalue 999999999 start with 1 increment by 1 cache 20; create sequence seq_DJANGO_CONTENT_TYPE minvalue 1 maxvalue 999999999 start with 1 increment by 1 cache 20; create sequence seq_AUTH_GROUP minvalue 1 maxvalue 999999999 start with 1 increment by 1 cache 20; create sequence seq_AUTH_GROUP_PERMISSIONS minvalue 1 maxvalue 999999999 start with 1 increment by 1 cache 20; create sequence seq_DJANGO_MIGRATIONS minvalue 1 maxvalue 999999999 start with 1 increment by 1 cache 20; create sequence seq_AUTH_PERMISSION minvalue 1 maxvalue 999999999 start with 1 increment by 1 cache 20; create sequence seq_AUTH_USER_USER_PERMISSIONS minvalue 1 maxvalue 999999999 start with 1 increment by 1 cache 20;
(2)創(chuàng)建觸發(fā)器
用SQL語(yǔ)句
select 'create or replace trigger tri_'||table_name||' before insert on '||table_name||' for each row declare begin :new.id:=seq_'||table_name||'.nextval; end tri_'||table_name||'; /' from user_tab_columns where column_name='ID';
生成觸發(fā)器腳本:
create or replace trigger tri_DJANGO_MIGRATIONS before insert on DJANGO_MIGRATIONS for each row declare begin :new.id:=seq_DJANGO_MIGRATIONS.nextval; end tri_DJANGO_MIGRATIONS; / create or replace trigger tri_DJANGO_CONTENT_TYPE before insert on DJANGO_CONTENT_TYPE for each row declare begin :new.id:=seq_DJANGO_CONTENT_TYPE.nextval; end tri_DJANGO_CONTENT_TYPE; / create or replace trigger tri_AUTH_PERMISSION before insert on AUTH_PERMISSION for each row declare begin :new.id:=seq_AUTH_PERMISSION.nextval; end tri_AUTH_PERMISSION; / create or replace trigger tri_AUTH_GROUP before insert on AUTH_GROUP for each row declare begin :new.id:=seq_AUTH_GROUP.nextval; end tri_AUTH_GROUP; / create or replace trigger tri_AUTH_GROUP_PERMISSIONS before insert on AUTH_GROUP_PERMISSIONS for each row declare begin :new.id:=seq_AUTH_GROUP_PERMISSIONS.nextval; end tri_AUTH_GROUP_PERMISSIONS; / create or replace trigger tri_AUTH_USER before insert on AUTH_USER for each row declare begin :new.id:=seq_AUTH_USER.nextval; end tri_AUTH_USER; / create or replace trigger tri_AUTH_USER_GROUPS before insert on AUTH_USER_GROUPS for each row declare begin :new.id:=seq_AUTH_USER_GROUPS.nextval; end tri_AUTH_USER_GROUPS; / create or replace trigger tri_AUTH_USER_USER_PERMISSIONS before insert on AUTH_USER_USER_PERMISSIONS for each row declare begin :new.id:=seq_AUTH_USER_USER_PERMISSIONS.nextval; end tri_AUTH_USER_USER_PERMISSIONS; / create or replace trigger tri_DJANGO_ADMIN_LOG before insert on DJANGO_ADMIN_LOG for each row declare begin :new.id:=seq_DJANGO_ADMIN_LOG.nextval; end tri_DJANGO_ADMIN_LOG; /
(3)此時(shí)再創(chuàng)建admin用戶,就成功了

新增用戶lurenjia成功!

以上這篇基于django2.2連oracle11g解決版本沖突的問(wèn)題就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
在SAE上部署Python的Django框架的一些問(wèn)題匯總
這篇文章主要介紹了在SAE上部署Python的Django框架的一些問(wèn)題匯總,SAE是新浪的一個(gè)在線APP部署平臺(tái),并且對(duì)Python應(yīng)用提供相關(guān)支持,需要的朋友可以參考下2015-05-05
如何處理json中不帶雙引號(hào)的key的問(wèn)題
這篇文章主要介紹了如何處理json中不帶雙引號(hào)的key的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09
對(duì)Python中plt的畫(huà)圖函數(shù)詳解
今天小編就為大家分享一篇對(duì)Python中plt的畫(huà)圖函數(shù)詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-11-11
Python?lambda函數(shù)保姆級(jí)使用教程
本文和你一起探索Python中的lambda函數(shù),讓你以最短的時(shí)間明白這個(gè)函數(shù)的原理。也可以利用碎片化的時(shí)間鞏固這個(gè)函數(shù),讓你在處理工作過(guò)程中更高效2022-06-06
Python基礎(chǔ)進(jìn)階之海量表情包多線程爬蟲(chóng)功能的實(shí)現(xiàn)
這篇文章主要介紹了Python基礎(chǔ)進(jìn)階之海量表情包多線程爬蟲(chóng),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12

