基于django2.2连oracle11g解决版本冲突的问题


Posted in Python onJuly 02, 2020

上次用django2.2和oracle11g,在migrate的时候发生了版本冲突,最终将Oracle升级到了12c才解决问题

那么到底能不能用别的方法来解决这个冲突呢?想了个解决思路,实践一下:

用django2.2连Oracle12c环境下做migrate,创建基础表

将基础表导出,再导入到Oracle11g数据库中

用django2.2连Oracle11g

实施步骤

1、用django2.2连Oracle12c环境下做migrate,创建基础表

在前文中已经完成,连接到数据库,可以看到有10张基础表

基于django2.2连oracle11g解决版本冲突的问题

看一张表,比如AUTH_GROUP表,发现有个ID字段是用了12c特有的generated语法,除了DJANGO_SESSION外,其他每张表都有一个自增序列的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. 将基础表导出,再导入到Oracle11g数据库中

导出django用户数据库,注意使用11g版本

基于django2.2连oracle11g解决版本冲突的问题

接着导入到11g数据库中,非常顺利

基于django2.2连oracle11g解决版本冲突的问题

再看AUTH_GROUP表,发现表结构是一样的,但是id上面自增序列的默认值没有了。

-- 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,然后启动django服务,果然成功启动

基于django2.2连oracle11g解决版本冲突的问题

基于django2.2连oracle11g解决版本冲突的问题

但是,但是,创建admin用户密码的时候就报错了,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):
密码长度太短。密码必须包含至少 8 个字符。
这个密码太常见了。
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表时,没有指定ID的值,而ID是主键,非空。

因为在12c的环境下,这个ID是自增序列,insert语句中不需要指定这个值。

解决方案

解决方案也应运而出了,只要为每个ID列创建一个11g的序列,创建触发器,在插入数据时补上id值就行了。

(1)生成序列。

用sql语句

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';

生成创建序列的批量执行语句,并执行。

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)创建触发器

用SQL语句

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';

生成触发器脚本:

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)此时再创建admin用户,就成功了

基于django2.2连oracle11g解决版本冲突的问题

新增用户lurenjia成功!

基于django2.2连oracle11g解决版本冲突的问题

以上这篇基于django2.2连oracle11g解决版本冲突的问题就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python语言技巧之三元运算符使用介绍
Mar 04 Python
Python 分析Nginx访问日志并保存到MySQL数据库实例
Mar 13 Python
详解Python中with语句的用法
Apr 15 Python
Python 专题四 文件基础知识
Mar 20 Python
Python3中正则模块re.compile、re.match及re.search函数用法详解
Jun 11 Python
python: 自动安装缺失库文件的方法
Oct 22 Python
Python登录系统界面实现详解
Jun 25 Python
使用Python进行防病毒免杀解析
Dec 13 Python
Python pip配置国内源的方法
Feb 14 Python
Python导入模块包原理及相关注意事项
Mar 25 Python
python读取hdfs上的parquet文件方式
Jun 06 Python
只用Python就可以制作的简单词云
Jun 07 Python
解决django migrate报错ORA-02000: missing ALWAYS keyword
Jul 02 #Python
使用PyWeChatSpy自动回复微信拍一拍功能的实现代码
Jul 02 #Python
使用Keras建立模型并训练等一系列操作方式
Jul 02 #Python
python解释器安装教程的方法步骤
Jul 02 #Python
Python分析最近大火的网剧《隐秘的角落》
Jul 02 #Python
keras训练浅层卷积网络并保存和加载模型实例
Jul 02 #Python
Python RabbitMQ实现简单的进程间通信示例
Jul 02 #Python
You might like
PHP设计模式之代理模式的深入解析
2013/06/13 PHP
深入分析PHP引用(&amp;)
2014/09/04 PHP
php 如何获取文件的后缀名
2016/06/05 PHP
jquery.cvtooltip.js 基于jquery的气泡提示插件
2010/11/19 Javascript
js切换div css注意的细节
2012/12/10 Javascript
javascript+xml实现简单图片轮换(只支持IE)
2012/12/23 Javascript
js 数组操作之pop,push,unshift,splice,shift
2014/01/29 Javascript
JavaScript中创建对象和继承示例解读
2014/02/12 Javascript
sliderToggle在写jquery的计时器setTimeouter中不生效
2014/05/26 Javascript
js实现hashtable的赋值、取值、遍历操作实例详解
2016/12/25 Javascript
jQuery插件HighCharts绘制2D柱状图、折线图的组合双轴图效果示例【附demo源码下载】
2017/03/09 Javascript
AngularJS的脏检查深入分析
2017/04/22 Javascript
Vue-路由导航菜单栏的高亮设置方法
2018/03/17 Javascript
vue 之 .sync 修饰符示例详解
2018/04/21 Javascript
WebSocket的通信过程与实现方法详解
2018/04/29 Javascript
微信sdk实现禁止微信分享(使用原生php实现)
2019/11/15 Javascript
extjs图形绘制之饼图实现方法分析
2020/03/06 Javascript
JavaScript实现简单贪吃蛇效果
2020/03/09 Javascript
详解javascript脚本何时会被执行
2021/02/05 Javascript
[20:57]Ti4主赛事第三天开幕式
2014/07/21 DOTA
Python深入学习之特殊方法与多范式
2014/08/31 Python
Python各类图像库的图片读写方式总结(推荐)
2018/02/23 Python
Python实现的简单线性回归算法实例分析
2018/12/26 Python
AUC计算方法与Python实现代码
2020/02/28 Python
使用tensorflow框架在Colab上跑通猫狗识别代码
2020/04/26 Python
HTML5+css3:3D旋转木马效果相册
2017/01/03 HTML / CSS
德国自行车商店:Tretwerk
2019/06/21 全球购物
介绍一下linux的文件权限
2012/02/15 面试题
葡萄牙语专业个人求职信
2013/12/10 职场文书
千元咖啡店的创业计划书范文
2013/12/29 职场文书
生产部岗位职责范文
2014/02/07 职场文书
2014年精神文明建设工作总结
2014/11/19 职场文书
教师个人培训总结
2015/02/11 职场文书
工厂清洁工岗位职责
2015/02/14 职场文书
2019最新版劳务派遣管理制度
2019/08/16 职场文书
刚学完怎么用Python实现定时任务,转头就跑去撩妹!
2021/06/05 Python