• oracle-django总结


    参考:

    https://stackoverflow.com/questions/54294114/django-inspectdb-ora-00904-identity-column

    背景:单位运行一批系统,数据库是oracle11g,java开发,比较老的框架,代码看不懂。我想到用django作为补丁语言,开发一些微服务接口。

    一、技术调查

    1. django继承数据遗产(legacy database),用 python manage.py inspectdb [tablename] ,反向生成model.py

    2.Django==1.11.22 可以用inspectdb,反向生成oracle11g的model.py

         django2.x以上,若想对oracle migrate操作,只能针对oracle12c以上。不能作用于oracle11g

            django1.11.22 migrate oracle11g

               django 2.x migrate oracle12c

        参考:https://stackoverflow.com/questions/48002977/how-to-make-django-2-0-to-use-oracle-11g-syntax-instead-of-12c

    3. ubuntu linux上,访问oracle需要2点

     (1)cx_oracle

          (2) oracle instant client

    4.最终的解决方案

     (1)安装2套virtualenv, 一个是django==1.11.22,专门用于反向oracle11g 的table,生成model.py

        另一套venv是生产环境,django>2.x

    (2)单位oracle是11g,用django2.x不能migrate, 因为dj2.0是按oracle12c定制的backends, migrate会产生

      (ORA-02000: missing ALWAYS keyword)错误。

      那么这些legacy data,

      DDL:手工操作,create table ,add column 等。

      CRUD data: insert table , delete ,update table 等, queryset是支持的。

    (3) 建设multiple database ,django运行的表(user, session等)用sqlite, 数据遗产不做migrate,主要用于业务查询和crud

      参考:https://docs.djangoproject.com/en/3.0/topics/db/multi-db/


    二、环境安装设置记录
    环境问题复杂,不同软件是否适配需要按官方说明或自己测试。 我按以下测试通过

    os:ubuntu 16.04
    django==2.2.4(produce) #用于服务运行
    django====1.11.22(tmp) #用于inspectdb oracle 11g

    1. 安装cx_oracle
    pip install cx-Oracle==6.0 (最新版本也可以cx_oracle==7.3)
    2. 安装Oracle Instant Client RPM
    参考:
     https://help.ubuntu.com/community/Oracle%20Instant%20Client
     https://oracle.github.io/odpi/doc/installation.html#linux

    下载:oracle-instantclient19.6-basic-19.6.0.0.0-1.x86_64.rpm
     https://www.oracle.com/database/technologies/instant-client/linux-x86-64-downloads.html

       

     3.安装,设置

     sudo apt-get install alien
     sudo alien -i oracle-instantclient19.6-basic-19.6.0.0.0-1.x86_64.rpm
     

      安装完成后,在/usr/lib/oracle/19.6/client64/lib/network/admin目录下,制作tnsnames.ora文件,内容如下:

    lxg@lxg-opt:/usr/lib/oracle/19.6/client64/lib/network/admin$ cat tnsnames.ora 
    234 =
    (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = 202.205.180.234)(PORT = 1521))
    (CONNECT_DATA =
    (SERVER = DEDICATED)
    (SERVICE_NAME = orcl)
    )
    )

    注意内容要可读

    lxg@lxg-opt:/usr/lib/oracle/19.6/client64/lib/network/admin$ sudo chmod -R 777 oracle

    设置oracle_home

    sudo gedit /etc/profile

    export ORACLE_HOME=/usr/lib/oracle/19.6/client64
    export LD_LIBRARY_PATH=/usr/lib/oracle/19.6/client64/lib:$LD_LIBRARY_PATH

    生效

    source /etc/profile

    三、程序运行测试

     1.普通python连接oracle

    import cx_Oracle
    
    def test1():
        print('开始。。。。。')
        connection = cx_Oracle.connect("jssq/js@234")
        print (connection.version)
        connection.close()
    
    if __name__ == '__main__':
        test1()

    输出:
    开始。。。。。
    11.2.0.1.0
     

    2.django测试

    (1)setting.py

    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.sqlite3',
            'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        },
    
        'oracle': {
            'ENGINE': 'django.db.backends.oracle',
            'NAME': 'orcl',(数据库的service_name,默认是orcl)
            'USER': 'jssq',
            'PASSWORD': 'js',
            'HOST': 'xxx.xxx.xxx.234',(数据库服务器ip)
            'PORT': '1521',
        }
    }

    (2)  oracle数据库 

     CREATE TABLE "JSSQ"."JS_MINZU" 

    ( "BM" VARCHAR2(10),
    "MC" VARCHAR2(60),
    CONSTRAINT "PK1" PRIMARY KEY ("BM"))

     这是pl/sql工具查看的结果

    用django1.11.22,反向生成model.py

    (py3.6env) lxg@lxg-opt:~/98receive/pystudy/g_oracle$ python manage.py inspectdb  js_minzu > js_minzu.py

    生成的model如下,简单改一下model名称变成Product(为了使用原来的跑在sqlite的程序)

    要在django中正常使用反向生成的model,要求oracle table有且有唯一column的primary key ,不支持联合主键。

    from django.db import models
    
    class Product(models.Model):
        bm = models.CharField(primary_key=True, max_length=10)
        mc = models.CharField(max_length=60, blank=True, null=True)
    
        class Meta:
            managed = False
            db_table = 'js_minzu'
    managed= False ,Django 将不会为当前 model 创建或者删除数据库表。 
    通常在表示某个 通过其他方法创建的现有数据表时这会非常有用。这是当 
    managed=False 时 仅有 的不同之 处。

    以下,migrate oracle数据库会失败,因为django2针对oracle12c 有效。我用的orcle11g。
    所以,我用双数据库,ddl用sqlite,对业务数据oracle只进行crud,不migrage.
    (py3.6env) lxg@lxg-opt:~/98receive/pystudy/g_oracle$ python manage.py migrate --database=oracle
    System check identified some issues:
    cx_Oracle.DatabaseError: ORA-02000: missing ALWAYS keyword

    view.py

    class ProductList(ListView):
        paginate_by = 6
        model = MYTABLE
    
        def get_template_names(self):
            template_name = '{}/{}List.html'.format(APPNAME,MYTABLE.__name__)
            return template_name
    
        def get_queryset(self):
            # user_id = self.request.user.id
            queryset = MYTABLE.objects.using('oracle').all()
    
            self.filter = ProductFilter(self.request.GET, queryset=queryset)
            return self.filter.qs
    
        def get_context_data(self, **kwargs):
            context = super().get_context_data(**kwargs)
    
            context['filter'] = self.filter
            context['model'] = self.model
            return context
    using('oracle') ,表示使用oracle数据库,否则会用default数据库。

  • 相关阅读:
    《那些年啊,那些事——一个程序员的奋斗史》——81
    《那些年啊,那些事——一个程序员的奋斗史》——83
    《那些年啊,那些事——一个程序员的奋斗史》——80
    《那些年啊,那些事——一个程序员的奋斗史》——82
    《那些年啊,那些事——一个程序员的奋斗史》——81
    《那些年啊,那些事——一个程序员的奋斗史》——82
    《那些年啊,那些事——一个程序员的奋斗史》——82
    网络学习杂七杂八
    字典类的代码的学习
    SNMP++ 编译记录
  • 原文地址:https://www.cnblogs.com/lxgbky/p/13038404.html
Copyright © 2020-2023  润新知