Add JSON type support for Oracle dialect, addresses #10375#13065
Add JSON type support for Oracle dialect, addresses #10375#130657adidaz wants to merge 1 commit intosqlalchemy:mainfrom
Conversation
zzzeek
left a comment
There was a problem hiding this comment.
hey there -
this looks very nice, everything is there. just need to see if it actually works ! :) since oracle can be very difficult. will add to CI (now that we have oracle 23 running)
sqla-tester
left a comment
There was a problem hiding this comment.
OK, this is sqla-tester setting up my work on behalf of zzzeek to try to get revision f5fdd03 of this pull request into gerrit so we can run tests and reviews and stuff
|
New Gerrit review created for change f5fdd03: https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/6547 |
I use this: $ docker pull gvenzl/oracle-free:latest
$ docker run -d \
--name oracle-free \
-p 1521:1521 \
-e ORACLE_PASSWORD=STRONGpassword123 \
-e APP_USER=scott \
-e APP_USER_PASSWORD=tiger \
gvenzl/oracle-free:latest
And I added this link to my test.cfg And I ran the following and the newly added tests turned green:) |
|
so we have some pep484 failures, and the main failure for Oracle is that the JSON suite doesnt include IDENTITY for the table, so we need to add this: diff --git a/lib/sqlalchemy/testing/suite/test_types.py b/lib/sqlalchemy/testing/suite/test_types.py
index bf720d919..c8714d5ed 100644
--- a/lib/sqlalchemy/testing/suite/test_types.py
+++ b/lib/sqlalchemy/testing/suite/test_types.py
@@ -1318,7 +1318,9 @@ class JSONTest(_LiteralRoundTripFixture, fixtures.TablesTest):
Table(
"data_table",
metadata,
- Column("id", Integer, primary_key=True),
+ Column(
+ "id", Integer, primary_key=True, test_needs_autoincrement=True
+ ),
Column("name", String(30), nullable=False),
Column("data", cls.datatype, nullable=False),
Column("nulldata", cls.datatype(none_as_null=True)),
@@ -1936,7 +1938,9 @@ class JSONLegacyStringCastIndexTest(
Table(
"data_table",
metadata,
- Column("id", Integer, primary_key=True),
+ Column(
+ "id", Integer, primary_key=True, test_needs_autoincrement=True
+ ),
Column("name", String(30), nullable=False),
Column("data", cls.datatype),
Column("nulldata", cls.datatype(none_as_null=True)),
|
465c52d to
f69051f
Compare
sqla-tester
left a comment
There was a problem hiding this comment.
Hi, this is sqla-tester and I see you've pinged me for review. However, user 7adidaz is not authorized to initiate CI jobs. Please wait for a project member to do this!
sqla-tester
left a comment
There was a problem hiding this comment.
OK, this is sqla-tester setting up my work on behalf of zzzeek to try to get revision f69051f of this pull request into gerrit so we can run tests and reviews and stuff
|
Patchset f69051f added to existing Gerrit review https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/6547 |
|
this is unfortunately quite complicated. the "supports_json" qualifier for oracle needs to be limited to the oracledb driver and not the older cx_oracle driver, which is why most of those failures are occurring. it might be for all of them so we would start by limiting to oracledb it might work like this diff --git a/test/requirements.py b/test/requirements.py
index dbeb287c3..39b1fcd95 100644
--- a/test/requirements.py
+++ b/test/requirements.py
@@ -1194,8 +1194,9 @@ class DefaultRequirements(SuiteRequirements):
"postgresql >= 9.3",
self._sqlite_json,
"mssql",
+ "oracle>=21",
]
- )
+ ) + skip_if("oracle+cx_oracle")
@property
def json_index_supplementary_unicode_element(self):
also it would be helpful if you could run these tests locally, you can get an Oracle db running using the instructions in https://github.com/sqlalchemy/sqlalchemy/blob/main/README.unittests.rst for "Oracle" shows how to run a container and set up the DB |
I have run when i rn the same on my branch, I also get the same: I can attach the full logs if it will be useful, but I have attached sample from the errors. When I run Please let me know if I need to add more tests or if I am missing something. |
|
the full test suite isn't set up to work with Oracle because many table fixtures lack a sequence or identity column to create new primary key values. if you're running the whole suite (which I dont think is needed here) you would run with the etc |
|
While working on this PR, I noticed that the Oracle driver returns JSON columns as dictionaries. Going back to the driver documentation, I didn't find any interface where I can pass my own serializer. Because of that, I have decided to skip the' test_round_trip_custom_json' test if it's Oracle. Please let me know what you think about this. Another approach would be to serialize and then deserialize or vice versa, but i dont think it's a good idea to do this. |
|
from a quick look it may be achieved using inputtypehandler and outputtypehandler |
Signed-off-by: abdallah elhdad <abdallahselhdad@gmail.com>
|
Agree, the type objects can include outputtypehandlers in the oracle dialect which is generally how we do this. |
|
I will check it out and update my approach, thank you both! |
|
We can ping the oracledb developted if needed to see if there is something a bit more centralized. I think that if json encoder / decoder are provided we may add functions on the connections to handle the input - output data conversions. The input/outputtypehandler seem to be present both in the connection and in the curstor, so I would expect that setting on the connection will make is useful from them on: |
I followed the convention used by other dialects while implementing this. One key difference is that in JSON queries, Oracle uses literal JSON paths, not parameterized ones.
This pull request is: