基于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出现segfault错误解决方法
Apr 16 Python
python实现简单socket通信的方法
Apr 19 Python
Python调用ctypes使用C函数printf的方法
Aug 23 Python
Python聊天室程序(基础版)
Apr 01 Python
Win8.1下安装Python3.6提示0x80240017错误的解决方法
Jul 31 Python
django之跨表查询及添加记录的示例代码
Oct 16 Python
Python实现密码薄文件读写操作
Dec 16 Python
BeautifulSoup获取指定class样式的div的实现
Dec 07 Python
python实现双人五子棋(终端版)
Dec 30 Python
Python+uiautomator2实现自动刷抖音视频功能
Apr 29 Python
Python一些基本的图像操作和处理总结
Jun 23 Python
基于Python实现将列表数据生成折线图
Mar 23 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 spl_autoload_register实现自动加载研究
2011/12/06 PHP
php实现的简易扫雷游戏实例
2015/07/09 PHP
PHP实现登录搜狐广告获取广告联盟数据的方法【附demo源码】
2016/10/14 PHP
CI(CodeIgniter)框架实现图片上传的方法
2017/03/24 PHP
Laravel中服务提供者和门面模式的入门介绍
2017/11/06 PHP
DOM 基本方法
2009/07/18 Javascript
6个DIV 135或246间隔一秒轮番显示效果
2010/07/24 Javascript
读jQuery之四(优雅的迭代)
2011/06/20 Javascript
单击按钮显示隐藏子菜单经典案例
2013/01/04 Javascript
Json和Jsonp理论实例代码详解
2013/11/15 Javascript
js的正则test,match,exec详细解析
2014/01/29 Javascript
jQuery插件bgStretcher.js实现全屏背景特效
2015/06/05 Javascript
动态加载jQuery的方法
2015/06/16 Javascript
js贪吃蛇游戏实现思路和源码
2016/04/14 Javascript
Bootstrap 轮播(Carousel)插件
2016/12/26 Javascript
Bootstrap源码解读媒体对象、列表组和面板(10)
2016/12/26 Javascript
ReactJS实现表单的单选多选和反选的示例
2017/10/13 Javascript
用最少的JS代码写出贪吃蛇游戏
2018/01/12 Javascript
Vue props用法详解(小结)
2018/07/03 Javascript
Python实现遍历windows所有窗口并输出窗口标题的方法
2015/03/13 Python
轻松实现python搭建微信公众平台
2016/02/16 Python
说说如何遍历Python列表的方法示例
2019/02/11 Python
PyQt5 QTable插入图片并动态更新的实例
2019/06/18 Python
python的slice notation的特殊用法详解
2019/12/27 Python
Python requests模块基础使用方法实例及高级应用(自动登陆,抓取网页源码)实例详解
2020/02/14 Python
python实现逢七拍腿小游戏的思路详解
2020/05/26 Python
使用Python操作MySQL的小技巧
2020/09/10 Python
美国手机支架公司:PopSockets
2019/11/27 全球购物
宣传策划类求职信范文
2014/01/31 职场文书
幼儿园中秋节活动总结
2015/03/23 职场文书
读《教育心理学》心得体会
2016/01/22 职场文书
2016年幼儿园教研活动总结
2016/04/05 职场文书
2019年员工晋升管理制度范本!
2019/07/08 职场文书
mybatis中sql语句CDATA标签的用法说明
2021/06/30 Java/Android
SQL Server中T-SQL标识符介绍与无排序生成序号的方法
2022/05/25 SQL Server
Win11 Beta 22621.601 和 22622.601今日发布 KB5017384修复内容汇总
2022/09/23 数码科技