基于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实现按行切分文本文件的方法
Apr 18 Python
python web框架学习笔记
May 03 Python
Python中用psycopg2模块操作PostgreSQL方法
Nov 28 Python
对python 多线程中的守护线程与join的用法详解
Feb 18 Python
python小程序实现刷票功能详解
Jul 17 Python
Python Dataframe常见索引方式详解
May 27 Python
读取nii或nii.gz文件中的信息即输出图像操作
Jul 01 Python
详解pytorch中squeeze()和unsqueeze()函数介绍
Sep 03 Python
Django-silk性能测试工具安装及使用解析
Nov 28 Python
Python扫描端口的实现
Jan 25 Python
10个顶级Python实用库推荐
Mar 04 Python
python神经网络 tf.name_scope 和 tf.variable_scope 的区别
May 04 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在XP下IIS和Apache2服务器上的安装
2006/09/05 PHP
深入php list()函数的详解
2013/06/05 PHP
一个漂亮的php验证码类(分享)
2013/08/06 PHP
php实现Mysql简易操作类
2015/10/11 PHP
php 利用socket发送GET,POST请求的实例代码
2020/07/04 PHP
一个对于Array的简单扩展
2006/10/03 Javascript
jquery HotKeys轻松搞定键盘事件代码
2008/08/30 Javascript
基于pthread_create,readlink,getpid等函数的学习与总结
2013/07/17 Javascript
动态加载jQuery的方法
2015/06/16 Javascript
JS使用正则表达式除去字符串中重复字符的方法
2015/11/05 Javascript
jquery使用Cookie和JSON记录用户最近浏览历史
2016/04/19 Javascript
Node.js返回JSONP详解
2016/05/18 Javascript
js实现html table 行,列锁定的简单实例
2016/10/13 Javascript
深入理解angular2启动项目步骤
2017/07/15 Javascript
基于jstree使用AJAX请求获取数据形成树
2017/08/29 Javascript
vue js秒转天数小时分钟秒的实例代码
2018/08/08 Javascript
vue移动端微信授权登录插件封装的实例
2018/08/28 Javascript
Vue 框架之动态绑定 css 样式实例分析
2018/11/14 Javascript
JS实现li标签的删除
2019/04/12 Javascript
vue.js click点击事件获取当前元素对象的操作
2020/08/07 Javascript
Python中endswith()函数的基本使用
2015/04/07 Python
用Python计算三角函数之atan()方法的使用
2015/05/15 Python
Python实现爬取需要登录的网站完整示例
2017/08/19 Python
基于scrapy的redis安装和配置方法
2018/06/13 Python
利用Django提供的ModelForm增删改数据的方法
2019/01/06 Python
由Python编写的MySQL管理工具代码实例
2019/04/09 Python
python 字符串追加实例
2019/07/20 Python
python GUI库图形界面开发之PyQt5日期时间控件QDateTimeEdit详细使用方法与实例
2020/02/27 Python
《雷雨》教学反思
2014/02/20 职场文书
计算机应届毕业生自荐信范文
2014/02/23 职场文书
职员竞岗演讲稿
2014/05/14 职场文书
校园文明倡议书
2014/05/16 职场文书
介绍信格式
2015/01/30 职场文书
河童之夏观后感
2015/06/11 职场文书
学校扫黄打非工作总结
2015/10/15 职场文书
pytorch 梯度NAN异常值的解决方案
2021/06/05 Python