sql >> Base de Datos >  >> RDS >> Oracle

Corrección del error ORA-65096 al crear pruebas automatizadas en Django usando Oracle

Índice

  1. Introducción
  2. Encontrar pistas
  3. Solución
  4. Referencias

Error:ORA-65096:nombre de rol o usuario común no válido en Oracle

Introducción

Hola, chicos,
Soy nuevo en backend y django, así que decidí seguir el tutorial de django

Aquí hay algunos detalles de lo que estaba usando para encontrar y corregir este error:

  • Django versión 3.2.5
  • Base de datos:Oracle Database Express Edition (XE) versión 18.4.0.0.0 (18c)
  • Windows 11

El próximo semestre, tengo un curso que usa Oracle, así que decidí usar Oracle en lugar de usar Sqlite como usó el tutorial de Django
He estado luchando con esta línea 'ORA-65096:usuario común o nombre de rol no válido en Oracle ' por dos días
Así que quiero crear esta publicación como una guía para cualquiera que se encuentre con este problema como yo.

Buscando pistas

python manage.py test polls

Lo que deberíamos conseguir

Creating test database for alias 'default'...
System check identified no issues (0 silenced).
F
======================================================================
FAIL: test_was_published_recently_with_future_question (polls.tests.QuestionModelTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/path/to/mysite/polls/tests.py", line 16, in test_was_published_recently_with_future_question
    self.assertIs(future_question.was_published_recently(), False)
AssertionError: True is not False

----------------------------------------------------------------------
Ran 1 test in 0.001s

FAILED (failures=1)
Destroying test database for alias 'default'...

Lo que realmente obtenemos :(

Creating test database for alias 'default'...
    Failed (ORA-01543: tablespace 'TEST_SYSTEM' already exists)
    It appears the test database, test_system, already exists. Type 'yes' to delete it, or 'no' to cancel: yes
    Destroying old test database for alias 'default'...
    Creating test user...
    Failed (ORA-65096: invalid common user or role name)
    Got an error creating the test user: ORA-65096: invalid common user or role name

Entonces el programa falló al intentar crear un nuevo usuario

Abramos sqlplus para crear un nuevo usuario manualmente, obtengo el mismo error cuando intento crear un nuevo usuario
"ORA-65096:usuario común o nombre de rol no válido"

¿Por qué?
Estoy iniciando sesión como usuario administrador con todos los privilegios

Y así, hago algunas investigaciones y descubro que

SQL> show con_name

CON_NAME
-----------------------------------
CDB$ROOT

Estamos en el contenedor 'CDB$ROOT', que es el guardián de todos los PDB que forman parte de la colección.
PDB es una base de datos conectable
Todos los PDB están conectados a CDB$ROOT, esta estructura se llama base de datos contenedora (CDB)
aprender más

Aparte de ese tipo de dolor de cabeza, todo lo que necesitamos saber es

99.9% of the time the error ORA-65096: invalid common user or role name means you are logged into the CDB when you should be logged into a PDB.
  • Entonces, necesitamos que un usuario tenga con_name es PDB para crear un usuario en ese PDB
SQL> show pdbs;

    CON_ID CON_NAME                       OPEN MODE  RESTRICTED
--------------- ------------------------------ ---------- ----------
         2 PDB$SEED                       READ ONLY  NO
         3 XEPDB1                         READ WRITE NO

Aquí puede ver que hay una base de datos conectable llamada XEPDB1, porque estoy usando Oracle XE
Si está utilizando Oracle 12, será ORCLPDB

Vaya a la solución para ver cómo crear un usuario con PDB

Aquí vamos de nuevo, apareció un nuevo error

django.db.utils.DatabaseError:ORA-12505:TNS:el oyente actualmente no conoce el SID proporcionado en el descriptor de conexión

Compruebe el archivo settings.py

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.oracle',
        'NAME': 'mydatabase',
        'USER': 'mydatabaseuser',
        'PASSWORD': 'mypassword',
        'HOST': '127.0.0.1',
        'PORT': '1521',
    }
}

Intenta iniciar sesión en sqlplus con el usuario que acabamos de crear

PS D:\Workplace\Backend\mysite> sqlplus django/django

SQL*Plus: Release 18.0.0.0.0 - Production on Wed Jul 28 15:56:57 2021
Version 18.4.0.0.0

Copyright (c) 1982, 2018, Oracle.  All rights reserved.

ERROR:
ORA-01017: invalid username/password; logon denied

Hmm, ¿por qué?

He intentado crear un usuario con ese mismo nombre de usuario, dice

ORA-01920: user name 'DJANGO' conflicts with another user or role name

¿Por qué???????

investiga un poco
Descubrí que no podemos usar usuarios en la base de datos conectable para conectarse al contenedor raíz

¿Y cómo nos conectamos a un PDB específico?

You are connecting to root container by using sqlplus testtest/password where the user doesn't exist.
Instead, you can use EZConnect or you can create a TNS name to connect to the PDB.

Ok, entonces aprende algo sobre la sintaxis de ezconnect
sqlplus nombre de usuario/contraseña@nombre de host:puerto/pdbname

PS D:\Workplace\Backend\mysite> sqlplus django/django@localhost:1521/XEPDB1

SQL*Plus: Release 18.0.0.0.0 - Production on Wed Jul 28 16:05:09 2021
Version 18.4.0.0.0

Copyright (c) 1982, 2018, Oracle.  All rights reserved.

Last Successful login time: Wed Jul 28 2021 14:18:57 +07:00

Connected to:
Oracle Database 18c Express Edition Release 18.0.0.0.0 - Production
Version 18.4.0.0.0

SQL>

Intenta crear un usuario

SQL> create user test identified by test;

User created.

Perfecto

Pero, ¿cómo le decimos a Django que usa este tipo de sintaxis? Sigue arrojándome errores a la cara.

The HOST and PORT keys need to be left out of the dictionary - else Django will try connecting with the complete "NAME" as an SID.

OK entonces
Intente iniciar sesión con el nombre del servicio en su lugar
Intente iniciar sesión con el nombre del servicio en sqlplus

PS D:\Workplace\Backend\mysite> sqlplus -L "django/django@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=XEPDB1)))"

SQL*Plus: Release 18.0.0.0.0 - Production on Wed Jul 28 12:06:33 2021
Version 18.4.0.0.0

Copyright (c) 1982, 2018, Oracle.  All rights reserved.

Last Successful login time: Wed Jul 28 2021 12:02:04 +07:00

Connected to:
Oracle Database 18c Express Edition Release 18.0.0.0.0 - Production
Version 18.4.0.0.0

Cambiar settings.py un poco

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.oracle',
        'NAME': 'localhost:1521/XEPDB1',
        'USER': 'django',
        'PASSWORD': 'django',
    }
}

Solución

  • Conéctese a sqlplus como sys
PS D:\Workplace\Backend\mysite> sqlplus "sys AS SYSDBA"

SQL*Plus: Release 18.0.0.0.0 - Production on Wed Jul 28 12:47:31 2021
Version 18.4.0.0.0

Copyright (c) 1982, 2018, Oracle.  All rights reserved.

Enter password:

Connected to:
Oracle Database 18c Express Edition Release 18.0.0.0.0 - Production
Version 18.4.0.0.0
  • Crear cuenta PDB
SQL> alter session set container = XEPDB1;

Session altered.

SQL> create user django identified by django;

User created.

SQL> grant all privileges to django;

Grant succeeded.
  • Crear/Editar la conexión de la base de datos con ese usuario Recuerde cambiar el nombre del servicio al contenedor que hemos usado arriba Si está usando Oracle 12, el contenedor será ORCLPDB , pulsa el botón de conexión
  • Abra el archivo susitio/susitio/settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.oracle',
        'NAME': 'localhost:1521/XEPDB1',
        'USER': 'django',
        'PASSWORD': 'django',
    }
}

Si te encuentras con este error, sigue mi guía aquí.
django.db.utils.DatabaseError:ORA-12505:TNS:el oyente actualmente no conoce el SID proporcionado en el descriptor de conexión

  • Aplicar las migraciones para la aplicación (nuevamente porque nos hemos conectado a una nueva base de datos)
python manage.py migrate
  • Ejecutar prueba
PS D:\Workplace\Backend\mysite> python manage.py test polls
Creating test database for alias 'default'...
Creating test user...
System check identified no issues (0 silenced).
F
======================================================================
FAIL: test_was_published_recently_with_future_question (polls.tests.QuestionModelTests)
---------------------------------------------------------------------------
Traceback (most recent call last):
  File "D:\Workplace\Backend\mysite\polls\tests.py", line 12, in test_was_published_recently_with_future_question
    self.assertIs(future_question.was_published_recently(), False)
AssertionError: True is not False

---------------------------------------------------------------------------
Ran 1 test in 0.006s

FAILED (failures=1)
Destroying test database for alias 'default'...
Destroying test user...
Destroying test database tables...
  • Exitoso, gracias por leer

Referencias

Enlace tutorial
Blogs y stackoverflow-s que me ayudaron a superar este error:

  • https://stackoverflow.com/questions/33330968/error-ora-65096-invalid-common-user-or-role-name-in-oracle
  • https://logicalread.com/oracle-pluggable-databases-mc05/#.YQES444za3A
  • https://dba.stackexchange.com/questions/196780/no-puedo-iniciar-sesion-a-un-usuario-acabo-de-crear-en-un-pdb
  • https://stackoverflow.com/questions/19246643/how-do-i-force-django-to-connect-to-oracle-using-service-name