Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Corrigindo o erro ORA-65096 ao criar testes automatizados no Django usando Oracle

Índice

  1. Introdução
  2. Encontrando pistas
  3. Solução
  4. Referências

Erro:ORA-65096:nome de usuário ou função comum inválido no oracle

Introdução


Olá, pessoal,
Eu sou novo no backend e no django, então decidi seguir com o tutorial do django

Aqui estão alguns detalhes do que eu estava usando para atender e corrigir esse erro:
  • Django versão 3.2.5
  • Banco de dados:Oracle Database Express Edition (XE) Versão 18.4.0.0.0 (18c)
  • Windows 11

No próximo semestre, tenho um curso usando Oracle, então decidi usar Oracle em vez de usar SQLite como o tutorial do Django usado
Eu tenho lutado com esta linha 'ORA-65096:nome de usuário ou função comum inválido no oracle ' por dois dias
Então eu quero criar este post como um guia para quem encontrar esse problema como eu.

Encontrando pistas

python manage.py test polls

O que devemos obter

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

O que realmente temos :(

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

Então o programa falhou ao tentar criar um novo usuário

Vamos abrir o sqlplus para criar um novo usuário manualmente, recebo o mesmo erro ao tentar criar um novo usuário
"ORA-65096:usuário comum inválido ou nome de função"

Por quê?
Estou entrando como usuário administrador com privilégios totais

E assim, eu faço algumas pesquisas e descubro que

SQL> show con_name

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

Estamos no container 'CDB$ROOT', que é o guardião de todos os PDBs que fazem parte da coleção
PDB é um banco de dados plugável
Todos os PDBs são plugados em CDB$ROOT, essa estrutura é chamada de banco de dados de contêiner (CDB)
Saber mais

Além desse tipo de dor de cabeça, tudo o que precisamos saber é

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.
  • Então, precisamos que um usuário tenha con_name is PDB para criar um usuário nesse PDB
SQL> show pdbs;

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

Aqui você pode ver que existe um banco de dados Pluggable chamado XEPDB1, porque estou usando o Oracle XE
Se você estiver usando o Oracle 12, será ORCLPDB

Vá para solução para ver como criar usuário com PDB

Aqui vamos nós de novo, novo erro apareceu

django.db.utils.DatabaseError:ORA-12505:TNS:listener atualmente não conhece o SID fornecido no descritor de conexão

Verifique o arquivo settings.py

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

Tente fazer login no sqlplus com o usuário que acabamos de criar

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 porque???

Eu tentei criar um usuário com esse mesmo nome de usuário, ele diz

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

Por que ????????

Pesquise
Descobrimos que não podemos usar usuários no Pluggable Database conectar ao contêiner root

E como nos conectamos a um 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, então aprenda algo sobre a sintaxe do ezconnect
sqlplus nome de usuário/senha@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>

Tente criar usuário

SQL> create user test identified by test;

User created.

Perfeito

Mas como podemos dizer ao django usando esse tipo de sintaxe, ele continua jogando erros na minha 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 então
Vamos tentar fazer login com o nome do serviço
Tente fazer login com o nome do serviço no 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

Altere um pouco o settings.py

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

Solução

  • Conectar ao 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
  • Criar conta 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.
  • Criar/editar conexão de banco de dados com esse usuário Lembre-se de alterar o nome do serviço para o contêiner que usamos acima Se você estiver usando Oracle 12, o contêiner será ORCLPDB , aperte o botão conectar
  • Abra o arquivo seusite/seusite/settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.oracle',
        'NAME': 'localhost:1521/XEPDB1',
        'USER': 'django',
        'PASSWORD': 'django',
    }
}

Se você encontrar esse erro, siga meu guia aqui
django.db.utils.DatabaseError:ORA-12505:TNS:listener atualmente não sabe do SID fornecido no descritor de conexão
  • Aplique as migrações para o aplicativo (novamente porque nos conectamos a um novo banco de dados)
python manage.py migrate
  • Executar teste
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...
  • Sucesso, obrigado por ler

Referências


Link do tutorial
Blogs e stackoverflow-s que me ajudaram com este erro:
  • 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