Skip to content

Fixed #33817 -- Added support for python-oracledb and deprecated cx_Oracle. #15841

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 10, 2023

Conversation

petronny
Copy link
Contributor

@petronny petronny commented Jul 12, 2022

cx_Oracle has a major new release under a new name and homepage python-oracledb.

The python-oracledb driver is a Python programming language extension module allowing Python programs to connect to Oracle Database. Python-oracledb is the new name for Oracle's popular cx_Oracle driver.

Tested on an Oracle Autonomous Database with TLSv1 connection.

Ticket: https://code.djangoproject.com/ticket/33817

@github-actions
Copy link

Hello @petronny! Thank you for your contribution 💪

As it's your first contribution be sure to check out the patch review checklist.

If you're fixing a ticket from Trac make sure to set the "Has patch" flag and include a link to this PR in the ticket!

If you have any design or process questions then you can ask in the Django forum.

Welcome aboard ⛵️!

@felixxm felixxm changed the title added oracledb support Fixed #33817 -- Used python-oracledb and deprecate cx_Oracle. Jul 27, 2022
@petronny petronny force-pushed the main branch 2 times, most recently from 8e4f1fb to 528b938 Compare July 30, 2022 06:33
@petronny petronny requested a review from felixxm July 30, 2022 06:35
@felixxm
Copy link
Member

felixxm commented Jul 30, 2022

@petronny We should change tests/requirements/oracle.txt.

@petronny petronny force-pushed the main branch 8 times, most recently from 76b898b to 970e291 Compare August 1, 2022 13:47
@petronny petronny force-pushed the main branch 6 times, most recently from 072a48d to 729dcbf Compare August 3, 2022 10:31
@felixxm
Copy link
Member

felixxm commented Aug 5, 2022

buildbot, test on oracle.

@felixxm
Copy link
Member

felixxm commented Aug 5, 2022

@petronny Please push fixes in separate commits. It's hard to review after force-push.

@petronny
Copy link
Contributor Author

petronny commented Aug 5, 2022

Please push fixes in separate commits.

OK.

The last change only replaces oracledb.OBJECT with oracle.DB_TYPE_OBJECT. These two are same but the first one is deprecated.

This won't fix the failed test in oragis. I've created an issue oracle/python-oracledb#43 for it on oracledb.

@felixxm
Copy link
Member

felixxm commented Aug 8, 2023

view_tests.tests.test_debug.DebugViewQueriesAllowedTests.test_handle_db_exception crashes when we introspect traceback frames after catching DatabaseError. Precisely when we try to get f_back (the next outer frame) and assign it to the current_frame:

current_frame = current_frame.f_back

On Jenkins f_back is missing after ThinCursorImpl.execute and it crashes when assigning current_frame = current_frame.f_back:

0: <frame at 0x7f1774ed3e20, file 'src/oracledb/impl/thin/cursor.pyx', line 138, code oracledb.thin_impl.ThinCursorImpl.execute>
1: None

on my local machine:

0: <frame at 0x7f234f53ad40, file 'src/oracledb/impl/thin/cursor.pyx', line 138, code oracledb.thin_impl.ThinCursorImpl.execute>
1: <frame at 0x7f234e91d300, file '/lib/python3.10/site-packages/oracledb/cursor.py', line 378, code execute>
2: <frame at 0x7f234ea2ebc0, file '/django/db/backends/oracle/base.py', line 553, code execute>
...

@ngnpope
Copy link
Member

ngnpope commented Aug 8, 2023

So it looks like Python 3.11 changed stuff with the frame object:

https://docs.python.org/3/whatsnew/3.11.html#pyframeobject-3-11-hiding

It also looks like python-oracledb is using cython for which there is the following issue: cython/cython#5222

@anthony-tuininga
Copy link

Yes, python-oracledb is using cython. So does this mean something needs to change in Django to handle the changes to the frames? Is this specific to Python 3.11 then?

@apollo13
Copy link
Member

apollo13 commented Aug 8, 2023 via email

@anthony-tuininga
Copy link

I tried running the test suite on my machine using a local database (running 21.3) and it raised a number of exceptions but didn't segfault. I don't know precisely how you are running the test suite and what you have in your settings file. If you are able to share that information I can try replicate the issue here. Currently I see the following results:

Ran 16529 tests in 2056.447s

FAILED (failures=44, errors=3, skipped=1255, expected failures=6)

This is the contents of my settings file:

# This is an Oracle test settings file for use with the Django test suite.
#

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.oracle',
        'NAME': 'localhost/DB21PDB1',
        'USER': 'django',
        'PASSWORD': 'dev',
        'TEST': {
            'USER': 'default_django_test',
            'TBLSPACE': 'default_django_test_ts',
            'TBLSPACE_TMP': 'default_django_temp_ts'
        }
    },
    'other': {
        'ENGINE': 'django.db.backends.oracle',
        'NAME': 'localhost/DB21PDB1',
        'USER': 'django',
        'PASSWORD': 'dev',
        'TEST': {
            'USER': 'other_django_test',
            'TBLSPACE': 'other_django_test_ts',
            'TBLSPACE_TMP': 'other_django_temp_ts'
        }
    },
}

DEFAULT_AUTO_FIELD='django.db.models.BigAutoField'
USE_TZ=False
SECRET_KEY="my_secret"

If any of this is incorrect (for example, a lot of failures are about the "wrong" AutoField) then please advise. I'd like to get to the bottom of this issue if at all possible!

@anthony-tuininga
Copy link

Ok. I tweaked the settings file to follow the suggested file from @petronny. I now get this:

Ran 16529 tests in 1947.899s

FAILED (failures=23, errors=1, skipped=1255, expected failures=6)

Running the test that causes the segfault runs just fine on my machine. This is on Linux x86_64, Python 3.11.4 with the python-oracledb 1.3.2 prebuilt binary that was released publicly. Adding print statements in the get_traceback_frame_variables() method shows that it is indeed being called without any difficulty. @felixxm, what platform does the CI use, what environment does it set, etc. Is there a configuration file somewhere? I'll see if I can find it myself but I am not familiar with Django build procedures.

@ngnpope
Copy link
Member

ngnpope commented Aug 8, 2023

You can see the CI job here: django-oracle

The configuration of interest would be database=oracle19,label=oracle,python=python3.11.

And looking at the latest build, specifically the full console output, we can see that it uses:

  • Ubuntu 20.04 LTS (Focal Fossa)
  • CPython 3.11.1
  • x86-64

It may be that this has been fixed in 3.11.2 - see release notes. This sounds suspiciously relevant:

  • gh-99110: Initialize frame->previous in frameobject.c to fix a segmentation fault when accessing frames created by PyFrame_New().

If you can install Python 3.11.1 and reproduce and then see if 3.11.2 fixes the issue it'd be helpful to confirm.

@anthony-tuininga
Copy link

I could download and install 3.11.1 but is there a reason why the CI job doesn't get upgraded to 3.11.4? I am unable to replicate with 3.11.4 and your releaase notes reference does indeed seem quite relevant. Cython is likely using PyFrame_New() to build its frames.

@felixxm
Copy link
Member

felixxm commented Aug 9, 2023

I bumped Python versions on CI nodes, we will see.

@petronny
Copy link
Contributor Author

petronny commented Aug 9, 2023

All tests have passed with python 3.11.4. 🎉

  1. Do we need to make a note stating that version 3.11.1 should not be used?
  2. Do we need to also test the thick mode?

@felixxm
Copy link
Member

felixxm commented Aug 9, 2023

Do we need to make a note stating that version 3.11.1 should not be used?

No, we only officially supports the latest version.

Do we need to also test the thick mode?

TBH, we don't have the time and resources to extensively test for Oracle drivers.

@petronny
Copy link
Contributor Author

petronny commented Aug 9, 2023

TBH, we don't have the time and resources to extensively test for Oracle drivers.

Then do we need to note that we only support the thin mode?

@cjbj
Copy link

cjbj commented Aug 9, 2023

Then do we need to note that we only support the thin mode?

It should work fine in Thick mode (as it has been doing so for many years), so I don't think the word 'support' is useful to add. You could say it was tested with Thin mode if you want to say anything. If any Thick mode issues are logged we can address them.

@@ -1 +1 @@
cx_oracle >= 7.0
oracledb >= 1.2.0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to set oracledb >= 1.3.3 as the minimum supported version. @anthony-tuininga When we can expect the next bugfix release?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current release is 1.3.2. Version 1.4 will come out in a few weeks.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can wait a bit, the feature freeze for Django 5.0 is on September, 18th.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would set 1.3.2 as minimum supported. This will give maximum testing time before Django 5.0. The changes in 1.4 are around areas that won't impact Django users.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes in 1.4 are around areas that won't impact Django users.

Some bugfixes are related, e.g. oracle/python-oracledb#211.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Un)fortunately, I'm on vacation next week. We can try after August, 21st or you can contact directly with the DSF board. I'm sure they would love to chat (\cc @django/dsf-board).

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@felixxm next week is busy for me too, so I can wait until you return.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@felixxm next week is busy for me too, so I can wait until you return.

I'm available for a call if you still want to catch up (daily from 6 am UTC to 12 o'clock UTC). We can figure out another time-slot if it doesn't work for you.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@felixxm I've sent a calendar invitation to meet tomorrow.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sarahboyce I only used this conversion as a reference for the version bump.

@felixxm felixxm self-assigned this Aug 9, 2023
@felixxm
Copy link
Member

felixxm commented Aug 9, 2023

Rebased.

@felixxm felixxm changed the title Fixed #33817 -- Used python-oracledb and deprecate cx_Oracle. Fixed #33817 -- Added support for python-oracledb and deprecated cx_Oracle. Aug 10, 2023
@felixxm
Copy link
Member

felixxm commented Aug 10, 2023

@petronny Thanks 👍 Welcome aboard ⛵ I pushed small edits.

@felixxm felixxm merged commit 9946f0b into django:main Aug 10, 2023
@cjbj
Copy link

cjbj commented Aug 10, 2023

Yay! A big thanks to all.

@felixxm felixxm temporarily deployed to schedules August 11, 2023 02:44 — with GitHub Actions Inactive
@krismohan
Copy link

Superb. Let us (@oracle) know if there are features that require attention.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.