Oracle
 sql >> Base de données >  >> RDS >> Oracle

Correction de l'erreur ORA-65096 lors de la création de tests automatisés dans Django à l'aide d'Oracle

Table des matières

  1. Présentation
  2. Trouver des indices
  3. Solution
  4. Références

Erreur :ORA-65096 :nom d'utilisateur ou de rôle commun non valide dans Oracle

Introduction

Bonjour gars,
Je suis nouveau sur le backend et Django, j'ai donc décidé de suivre le tutoriel Django

Voici quelques détails sur ce que j'utilisais pour rencontrer et corriger cette erreur :

  • Django 3.2.5
  • Base de données :Oracle Database Express Edition (XE) version 18.4.0.0.0 (18c)
  • Windows 11

Le semestre prochain, j'ai un cours utilisant Oracle, j'ai donc décidé d'utiliser Oracle au lieu d'utiliser Sqlite comme le tutoriel Django utilisé
J'ai eu du mal avec cette ligne 'ORA-65096 :nom d'utilisateur ou de rôle commun invalide dans oracle ' pendant deux jours
Je souhaite donc créer ce message comme guide pour tous ceux qui rencontrent ce problème comme moi.

Trouver des indices

python manage.py test polls

Ce que nous devrons avoir

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

Ce que nous obtenons réellement :(

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

Le programme a donc échoué lors de la tentative de création d'un nouvel utilisateur

Ouvrons sqlplus pour créer un nouvel utilisateur manuellement, j'obtiens la même erreur lorsque j'essaie de créer un nouvel utilisateur
"ORA-65096 :nom d'utilisateur ou de rôle commun non valide"

Pourquoi?
Je me connecte en tant qu'utilisateur administrateur avec tous les privilèges

Et donc, je fais quelques recherches et découvre que

SQL> show con_name

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

Nous sommes dans le conteneur 'CDB$ROOT', qui est le gardien de tous les PDB qui font partie de la collection
PDB est une base de données enfichable
Tous les PDB sont branchés sur CDB$ROOT, cette structure s'appelle une base de données de conteneurs (CDB)
en savoir plus

Mis à part ce genre de maux de tête, tout ce que nous devons savoir, c'est

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.
  • Nous avons donc besoin qu'un utilisateur ait con_name est PDB pour créer un utilisateur sur ce PDB
SQL> show pdbs;

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

Ici, vous pouvez voir qu'il existe une base de données Pluggable nommée XEPDB1, car j'utilise Oracle XE
Si vous utilisez Oracle 12, ce sera ORCLPDB

Accédez à la solution pour voir comment créer un utilisateur avec PDB

C'est reparti, une nouvelle erreur est apparue

django.db.utils.DatabaseError :ORA-12505 :TNS :l'auditeur ne connaît pas actuellement le SID indiqué dans le descripteur de connexion

Vérifier le fichier settings.py

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

Essayez de vous connecter à sqlplus avec l'utilisateur que nous venons de créer

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

Hum, pourquoi ???

J'ai essayé de créer un utilisateur avec le même nom d'utilisateur, il dit

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

Pourquoi ?????????

Fais quelques recherches
Nous avons découvert que nous ne pouvons pas utiliser les utilisateurs de Pluggable Database pour se connecter au conteneur racine

Et comment se connecte-t-on à un PDB spécifique ?

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 alors apprenez quelque chose sur la syntaxe ezconnect
sqlplus username/password@hostname:port/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>

Essayez de créer un utilisateur

SQL> create user test identified by test;

User created.

Parfait

Mais comment pouvons-nous dire à Django en utilisant ce type de syntaxe, cela continue de me lancer des erreurs au visage

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.

Alors ok
Essayez plutôt de vous connecter avec le nom du service
Essayez de vous connecter avec le nom du service dans 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

Modifiez un peu settings.py

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

Solution

  • Se connecter à sqlplus en tant que 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
  • Créer un compte 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.
  • Créer/Modifier une connexion à la base de données avec cet utilisateur N'oubliez pas de remplacer le nom du service par le conteneur que nous avons utilisé ci-dessus Si vous utilisez Oracle 12, le conteneur sera ORCLPDB , appuyez sur le bouton de connexion
  • Ouvrir le fichier votresite/votresite/settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.oracle',
        'NAME': 'localhost:1521/XEPDB1',
        'USER': 'django',
        'PASSWORD': 'django',
    }
}

Si vous rencontrez cette erreur, suivez mon guide ici
django.db.utils.DatabaseError :ORA-12505 :TNS :l'auditeur ne connaît pas actuellement le SID indiqué dans le descripteur de connexion

  • Appliquer les migrations pour l'application (encore une fois parce que nous nous sommes connectés à une nouvelle base de données)
python manage.py migrate
  • Exécuter le test
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...
  • Bonne lecture, merci d'avoir lu

Références

Lien vers le tutoriel
Blogs et stackoverflow-s qui m'ont aidé à surmonter cette erreur :

  • 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/i-cannot-login-to-a-user-i-just-created-in-a-pdb
  • https://stackoverflow.com/questions/19246643/how-do-i-force-django-to-connect-to-oracle-using-service-name