|
| 1 | += Upgrade from older versions |
| 2 | + |
| 3 | +This page contains the list of new features and breaking changes that happened in the driver from version 4.4 to 5.x. + |
| 4 | +For a full list of changes, see the link:https://github.com/neo4j/neo4j-python-driver/wiki/5.x-changelog[Driver -> Changelog]. |
| 5 | + |
| 6 | +The link:https://github.com/neo4j/drivers-migration-assistant[Neo4j Drivers Migration Assistant] simplifies the upgrade process, by contextualizing the changelog to your codebase. |
| 7 | +It scans your codebase for usage of deprecations and removals, and brings them up to you. |
| 8 | +The tool doesn't automatically rewrite your code; it only points at where action is needed, providing in-context information on how each hit should be addressed. |
| 9 | + |
| 10 | +Any of the 5.x versions of the driver is compatible both with Neo4j server 4.4 and 5.x, so you can upgrade the driver before you upgrade the server. |
| 11 | +The driver version 4.4 is forward compatible with Neo4j server 5.x as well, so you could also upgrade the server before the driver; however, given that it's easier to roll back an application upgrade than a server upgrade, it's recommended to start with the driver. |
| 12 | + |
| 13 | +[TIP] |
| 14 | +When upgrading the Neo4j server to a newer version, the Cypher queries in your application may also need updating. + |
| 15 | +See link:https://neo4j.com/docs/cypher-manual/current/deprecations-additions-removals-compatibility/[Cypher -> Deprecations, additions, and compatibility]. |
| 16 | + |
| 17 | + |
| 18 | +[[recommended-steps]] |
| 19 | +== Recommended steps |
| 20 | + |
| 21 | +Using the migration assistant, the recommended upgrade steps are: |
| 22 | + |
| 23 | +1. Set up the environment for the assistant to work in. |
| 24 | +Download the link:https://github.com/neo4j/drivers-migration-assistant/archive/refs/heads/dev.zip[Drivers Migration Assistant zip], extract it, and locate yourself in its directory. |
| 25 | +Then, assuming `python3` and `pip3` are already installed, |
| 26 | ++ |
| 27 | +[source, bash] |
| 28 | +---- |
| 29 | +python3 -m venv virtualenvs/neo4j-migration |
| 30 | +source virtualenvs/neo4j-migration/bin/activate |
| 31 | +pip3 install -r requirements.txt |
| 32 | +---- |
| 33 | + |
| 34 | +2. Run the migration assistant with its default configuration and address all the issues that it surfaces. The `path` argument supports link:https://www.man7.org/linux/man-pages/man7/glob.7.html[globbing], and can be repeated. + |
| 35 | ++ |
| 36 | +[source, bash] |
| 37 | +---- |
| 38 | +python3 main.py -l python /path/*.py /path-recursive/**/*.py |
| 39 | +---- |
| 40 | + |
| 41 | +3. Re-run the assistant with the regex parser and check if any more legit issues are raised. + |
| 42 | ++ |
| 43 | +[source, bash] |
| 44 | +---- |
| 45 | +python3 main.py -l python --regex-parser /path/*.py /path-recursive/**/*.py |
| 46 | +---- |
| 47 | ++ |
| 48 | +The regex parser can detect implicit function calls and other hard-to-parse expressions, but is likely to surface more false positives (for more information, see link:https://github.com/neo4j/drivers-migration-assistant?tab=readme-ov-file#accuracy[Neo4j Drivers Migration Assistant -> Accuracy]). |
| 49 | +You can add any spurious entry to the ignored list, so that the assistant won't bring them up in future runs. |
| 50 | + |
| 51 | +4. Although the assistant can detect most of the locations where action is needed, a few changelog entries can't be surfaced in this form, so you should still revise the xref:breaking-changes[breaking changes] section and audit your codebase for the changes marked with {cross-mark} in the table. |
| 52 | + |
| 53 | +5. You are ready to upgrade the driver package to the new version. For example, using `pip`: + |
| 54 | ++ |
| 55 | +[source, bash] |
| 56 | +---- |
| 57 | +pip3 install -U neo4j==5.27 |
| 58 | +---- |
| 59 | + |
| 60 | + |
| 61 | +[[new-features]] |
| 62 | +== New features |
| 63 | + |
| 64 | +[cols="1a,1a"] |
| 65 | +|=== |
| 66 | + |
| 67 | +| |
| 68 | +.Support for Python 3.13 |
| 69 | +[%collapsible] |
| 70 | +==== |
| 71 | +The driver is compatible with any Python version starting from 3.7 up to 3.13. |
| 72 | +==== |
| 73 | +| |
| 74 | +.`asyncio` support |
| 75 | +[%collapsible] |
| 76 | +==== |
| 77 | +For using the driver's features asynchronously via the link:https://docs.python.org/3/library/asyncio.html[asyncio] package. |
| 78 | +
|
| 79 | +See xref:concurrency.adoc[]. |
| 80 | +==== |
| 81 | + |
| 82 | +| |
| 83 | +.`Driver.execute_query()` to run transactions with less knowledge of driver's internals |
| 84 | +[%collapsible] |
| 85 | +==== |
| 86 | +The new function is a wrapper for `Session.execute_read/write()`, but it abstracts away the result processing part and returns a list of records to the caller directly. |
| 87 | +
|
| 88 | +See xref:query-simple.adoc[]. |
| 89 | +==== |
| 90 | +| |
| 91 | +.Rust extension for performance |
| 92 | +[%collapsible] |
| 93 | +==== |
| 94 | +The link:https://github.com/neo4j-drivers/neo4j-python-driver-rust-ext[Rust extension to the Python driver] is an alternative driver package that can yield a speedup up to 10x compared to the pure-Python driver. |
| 95 | +
|
| 96 | +You can install it with `pip install neo4j-rust-ext`, either alongside the `neo4j` package or as a replacement to it. |
| 97 | +Usage-wise, the drivers are identical. |
| 98 | +==== |
| 99 | + |
| 100 | +| |
| 101 | +.Export to Pandas Dataframe |
| 102 | +[%collapsible] |
| 103 | +==== |
| 104 | +`Result.to_df()` allows for exporting a `Result` object into a Pandas DataFrame. |
| 105 | +
|
| 106 | +See xref:transformers.adoc#_transform_to_pandas_dataframe[Manipulate query results -> Transform to Pandas Dataframe]. |
| 107 | +==== |
| 108 | +| |
| 109 | +.Type hints for all public APIs |
| 110 | +[%collapsible] |
| 111 | +==== |
| 112 | +All public objects have type annotations via the link:https://docs.python.org/3/library/typing.html[typing] package. For (optional) use with type checkers and linters. |
| 113 | +==== |
| 114 | + |
| 115 | +| |
| 116 | +.Re-authentication |
| 117 | +[%collapsible] |
| 118 | +==== |
| 119 | +Allows for xref:connect-advanced.adoc#rotating-tokens[rotating authentication tokens] as well as xref:transactions.adoc#impersonation[session-scoped] and xref:query-simple.adoc#impersonation[query-scoped] authentication. |
| 120 | +==== |
| 121 | +| |
| 122 | +.Mutual TLS (mTLS) as second authentication factor (2FA) |
| 123 | +[%collapsible] |
| 124 | +==== |
| 125 | +Allows for configuring client side TLS certificates to authenticate against the server. |
| 126 | +
|
| 127 | +See xref:connect-advanced.adoc#mtls[Mutual TLS]. |
| 128 | +==== |
| 129 | + |
| 130 | +| |
| 131 | +.`BookmarkManager` support |
| 132 | +[%collapsible] |
| 133 | +==== |
| 134 | +Bookmark managers make it easier to achieve causal chaining of sessions. |
| 135 | +
|
| 136 | +See xref:bookmarks.adoc[]. |
| 137 | +==== |
| 138 | +| |
| 139 | +.Notification filtering API |
| 140 | +[%collapsible] |
| 141 | +==== |
| 142 | +Filtering allows to receive only a subset of notifications from the server, and to improve performance server-side. |
| 143 | +
|
| 144 | +See xref:result-summary.adoc#_filter_notifications[Explore the query execution summary -> Filter notifications]. |
| 145 | +==== |
| 146 | + |
| 147 | +| |
| 148 | +.GQL statuses of queries in the `ResultSummary` |
| 149 | +[%collapsible] |
| 150 | +==== |
| 151 | +A new property `ResultSummary.gql_status_objects` is available. |
| 152 | +It contains a sequence of `GqlStatusObjects`, containing information about the execution of the query. |
| 153 | +
|
| 154 | +This API is planned to supersede the current notifications API. |
| 155 | +
|
| 156 | +See xref:result-summary.adoc#_notifications[Explore the query execution summary -> Notifications]. |
| 157 | +==== |
| 158 | +| |
| 159 | +.More convenient handling of server-side warnings and notifications |
| 160 | +[%collapsible] |
| 161 | +==== |
| 162 | +The new sub-logger `neo4j.notifications` logs every notification raised by the server. |
| 163 | +The log-level is determined by the notification's severity. |
| 164 | +
|
| 165 | +If logging is not configured explicitly, the default behavior is for warnings to be logged to stderr via `warning.warn()`. |
| 166 | +The result of this change is that warnings (such as deprecations) received from the DBMS will appear on stderr. |
| 167 | +
|
| 168 | +See link:https://github.com/neo4j/neo4j-python-driver/discussions/1064[Convenient DBMS notifications]. |
| 169 | +==== |
| 170 | + |
| 171 | +| |
| 172 | +.Telemetry |
| 173 | +[%collapsible] |
| 174 | +==== |
| 175 | +The driver sends anonymous API usage statistics to the server. |
| 176 | +Use the driver configuration `telemetry_disabled=True` to opt out. |
| 177 | +==== |
| 178 | +| |
| 179 | +.Concurrency misuse checks |
| 180 | +[%collapsible] |
| 181 | +==== |
| 182 | +For local development, run your application with `python -X dev ...` or set the environment variable `PYTHONNEO4JDEBUG` to anything non-empty to get additional concurrency misuse checks. |
| 183 | +Some driver primitives (e.g. sessions) are not safe to be used concurrently, and using them so will lead to hard-to-debug errors. |
| 184 | +This feature helps identifying such code paths (detection is still inherently racy, hence not guaranteed to always work). |
| 185 | +==== |
| 186 | + |
| 187 | +|=== |
| 188 | + |
| 189 | + |
| 190 | +[[breaking-changes]] |
| 191 | +== Breaking changes and deprecations |
| 192 | + |
| 193 | +The column `Assistant` denotes whether the Neo4j Drivers Migration Assistant can detect issues related to the given changelog entry. |
| 194 | +Entries with a cross mark {cross-mark} require manual inspection. |
| 195 | + |
| 196 | +Deprecated features are likely to be removed in version 6. |
| 197 | + |
| 198 | +[cols="1,5a,1,1"] |
| 199 | +|=== |
| 200 | +|Version |Message |Status |Assistant |
| 201 | + |
| 202 | +|5.0 |
| 203 | +|Dropped support for Python 3.6. |
| 204 | +|label:removed[] |
| 205 | +|{cross-mark} |
| 206 | + |
| 207 | +|5.0 |
| 208 | +|link:https://neo4j.com/docs/api/python-driver/current/api.html#neo4j.Driver[`Driver`] -- The config options `update_routing_table_timeout` and `session_connection_timeout` have been removed. Regular keep-alives are sufficient to avoid the driver getting stuck. Further liveness check config options are available but normally not needed (link:https://neo4j.com/docs/api/python-driver/current/api.html#keep-alive-ref[`keep_alive`], link:https://neo4j.com/docs/api/python-driver/current/api.html#liveness-check-timeout[`liveness_check_timeout`]). |
| 209 | +|label:removed[] |
| 210 | +|{check-mark} |
| 211 | + |
| 212 | +|5.0 |
| 213 | +|`Result`, `Session`, and `Transaction` can no longer be imported from `neo4j.work`. Import them from `neo4j` instead. |
| 214 | +|label:removed[] |
| 215 | +|{check-mark} |
| 216 | + |
| 217 | +|5.0 |
| 218 | +|link:https://neo4j.com/docs/api/python-driver/current/api.html#neo4j.ServerInfo[`ServerInfo`] -- `ResultSummary.server.version_info` has been removed. |
| 219 | +Use `ResultSummary.server.agent`, `ResultSummary.server.protocol_version`, or call the link:https://neo4j.com/docs/operations-manual/current/reference/procedures/#procedure_dbms_components[`dbms.components`] Cypher procedure instead. |
| 220 | +|label:removed[] |
| 221 | +|{check-mark} |
| 222 | + |
| 223 | +|5.0 |
| 224 | +|link:https://neo4j.com/docs/api/python-driver/current/types/temporal.html#neo4j.time.Duration[`Duration`] -- The constructor does not accept `subseconds` anymore. Use `milliseconds`, `microseconds`, or `nanoseconds` instead. |
| 225 | +|label:removed[] |
| 226 | +|{check-mark} |
| 227 | + |
| 228 | +|5.0 |
| 229 | +|link:https://neo4j.com/docs/api/python-driver/current/types/temporal.html#neo4j.time.Duration[`Duration`] -- The property `subseconds` has been removed. Use `nanoseconds` instead. |
| 230 | +|label:removed[] |
| 231 | +|{check-mark} |
| 232 | + |
| 233 | +|5.0 |
| 234 | +|link:https://neo4j.com/docs/api/python-driver/current/types/temporal.html#neo4j.time.Duration[`Duration`] -- The property `hours_minutes_seconds` has been removed. Use `hours_minutes_seconds_nanoseconds` instead. |
| 235 | +|label:removed[] |
| 236 | +|{check-mark} |
| 237 | + |
| 238 | +|5.0 |
| 239 | +|link:https://neo4j.com/docs/api/python-driver/current/types/temporal.html#neo4j.time.DateTime[`DateTime`] -- The property `hour_minute_second` has been removed. Use `hour_minute_second_nanosecond` instead. |
| 240 | +|label:removed[] |
| 241 | +|{check-mark} |
| 242 | + |
| 243 | +|5.0 |
| 244 | +|link:https://neo4j.com/docs/api/python-driver/current/types/temporal.html#neo4j.time.DateTime[`DateTime`] -- The property `second` returns an int instead of a float. Use `nanosecond` to get the sub-second information. |
| 245 | +|label:removed[Changed] |
| 246 | +|{cross-mark} |
| 247 | + |
| 248 | +|5.0 |
| 249 | +|All math operations on `DateTime` objects are element-wise on (months, days, nanoseconds). This changes the working of `//`, `%`, `/`, and `*`. + |
| 250 | +Years are equal to 12 months. Weeks are equal to 7 days. + |
| 251 | +Seconds, milliseconds, microseconds, and nanoseconds are implicitly converted to nanoseconds or seconds as fit. + |
| 252 | +Multiplication and division allow for floats but will always result in integer values (round to nearest even). |
| 253 | +|label:removed[Changed] |
| 254 | +|{cross-mark} |
| 255 | + |
| 256 | +|5.0 |
| 257 | +|link:https://neo4j.com/docs/api/python-driver/current/types/temporal.html#neo4j.time.Time[`Time`] -- The constructor does not accept floats for `second` anymore. Use `nanosecond` instead. |
| 258 | +|label:removed[] |
| 259 | +|{check-mark} |
| 260 | + |
| 261 | +|5.0 |
| 262 | +|link:https://neo4j.com/docs/api/python-driver/current/types/temporal.html#neo4j.time.Time[`Time`] -- The property `second` returns an int instead of a float. Use `nanosecond` to get the sub-second information. |
| 263 | +|label:removed[Changed] |
| 264 | +|{cross-mark} |
| 265 | + |
| 266 | +|5.0 |
| 267 | +|link:https://neo4j.com/docs/api/python-driver/current/types/temporal.html#neo4j.time.Time[`Time`] -- The `ticks` property's type changed from float to int. It's now nanoseconds since midnight instead of seconds. |
| 268 | +|label:removed[Changed] |
| 269 | +|{cross-mark} |
| 270 | + |
| 271 | +|5.0 |
| 272 | +|link:https://neo4j.com/docs/api/python-driver/current/types/temporal.html#neo4j.time.Time[`Time`] -- The property `ticks_ns` has been renamed to `ticks`. |
| 273 | +|label:removed[] |
| 274 | +|{check-mark} |
| 275 | + |
| 276 | +|5.0 |
| 277 | +|link:https://neo4j.com/docs/api/python-driver/current/types/temporal.html#neo4j.time.Time[`Time`] -- The property `hour_minute_second` has been removed. Use `hour_minute_second_nanosecond` instead. |
| 278 | +|label:removed[] |
| 279 | +|{check-mark} |
| 280 | + |
| 281 | +|5.0 |
| 282 | +|link:https://neo4j.com/docs/api/python-driver/current/api.html#neo4j.Session[`Session`] -- Methods `.read_transaction()` and `.write_transaction()` are deprecated in favor of link:https://neo4j.com/docs/api/python-driver/current/api.html#neo4j.Session.execute_read[`.execute_read()`] and link:https://neo4j.com/docs/api/python-driver/current/api.html#neo4j.Session.execute_write[`.execute_write()`]. |
| 283 | +Through the new methods, the first argument of transaction functions is a `ManagedTransaction` object. It behaves like a regular `Transaction` object, except it does not offer the `.commit()`, `.rollback()`, `.close()`, and `.closed()` methods. |
| 284 | +|label:deprecated[] |
| 285 | +|{check-mark} |
| 286 | + |
| 287 | +|5.3 |
| 288 | +|Package-alias `neo4j-driver` is deprecated. It will stop receiving updates starting with 6.0.0. Install `neo4j` instead. |
| 289 | +|label:deprecated[] |
| 290 | +|{cross-mark} |
| 291 | + |
| 292 | +|5.0 |
| 293 | +|link:https://neo4j.com/docs/api/python-driver/current/api.html#neo4j.graph.Node[`Node`], link:https://neo4j.com/docs/api/python-driver/current/api.html#neo4j.graph.Relationship[`Relationship`] -- Property `id` (int) is deprecated in favor of `element_id` (str). |
| 294 | +This also affects link:https://neo4j.com/docs/api/python-driver/current/api.html#neo4j.graph.Graph[`Graph`] objects, as indexing `graph.nodes[...]` and `graph.relationships[...]` with integers is deprecated in favor of indexing them with strings. |
| 295 | +|label:deprecated[] |
| 296 | +|{check-mark} property + |
| 297 | +{cross-mark} indexing |
| 298 | + |
| 299 | +|5.0 |
| 300 | +|Implicit closing of drivers and sessions through `+++__del__()+++` (destructor) is deprecated. |
| 301 | +This behaviour is non-deterministic as there is no guarantee that the destructor will ever be called. |
| 302 | +A `ResourceWarning` is emitted instead. + |
| 303 | +Call `driver.close()` explicitly or create the driver via a `with` statement. |
| 304 | +|label:deprecated[] |
| 305 | +|{check-mark} |
| 306 | + |
| 307 | +|5.0 |
| 308 | +|Import of the following modules is deprecated without replacement, as they are internal and should not be used by client code: `neo4j.packstream`, `neo4j.routing`, `neo4j.config`, `neo4j.meta`, `neo4j.data`. |
| 309 | + |
| 310 | +`ExperimentalWarning` (previously in `meta`) should be imported directly from neo4j. + |
| 311 | +`neo4j.meta.version` is exposed through `+++neo4j.__version__+++`. |
| 312 | +|label:deprecated[] |
| 313 | +|{check-mark} |
| 314 | + |
| 315 | +|5.0 |
| 316 | +|link:https://neo4j.com/docs/api/python-driver/current/api.html#neo4j.Driver[`Driver`] -- The config option `trust` is deprecated. New options link:https://neo4j.com/docs/api/python-driver/current/api.html#trusted-certificates-ref[`trusted_certificates`] and link:https://neo4j.com/docs/api/python-driver/current/api.html#ssl-context-ref[`ssl_context`] are available. |
| 317 | +|label:deprecated[] |
| 318 | +|{check-mark} |
| 319 | + |
| 320 | +|5.0 |
| 321 | +|link:https://neo4j.com/docs/api/python-driver/current/api.html#neo4j.Session[`Session`] -- The method `.last_bookmark()` is deprecated in favor of link:https://neo4j.com/docs/api/python-driver/current/api.html#neo4j.Session.last_bookmarks[`.last_bookmarks()`]. The logic is similar, but the new method returns `neo4j.Bookmarks` instead of `str`. |
| 322 | +|label:deprecated[] |
| 323 | +|{check-mark} |
| 324 | + |
| 325 | +|5.0 |
| 326 | +|`neo4j.Bookmark` is deprecated in favor of link:https://neo4j.com/docs/api/python-driver/current/api.html#neo4j.Bookmarks[`neo4j.Bookmarks`]. |
| 327 | +|label:deprecated[] |
| 328 | +|{check-mark} |
| 329 | + |
| 330 | +|5.0 |
| 331 | +|Importing submodules from `neo4j.time` is deprecated. Import everything from `neo4j.time` directly instead. |
| 332 | +|label:deprecated[] |
| 333 | +|{check-mark} |
| 334 | + |
| 335 | +|5.7 |
| 336 | +|Importing `neo4j.work` and its submodules is deprecated. Import everything from `neo4j` directly instead. |
| 337 | +|label:deprecated[] |
| 338 | +|{check-mark} |
| 339 | + |
| 340 | +|5.0 |
| 341 | +|The following objects are deprecated without replacement, as they are internal and should not be used by client code: `neo4j.spatial.hydrate_point`, `neo4j.spatial.dehydrate_point`, `neoj4.Config`, `neoj4.PoolConfig`, `neoj4.SessionConfig`, `neoj4.WorkspaceConfig`, `neo4j.data.DataDehydrator`, `neo4j.data.DataHydrator`. |
| 342 | +|label:deprecated[] |
| 343 | +|{check-mark} |
| 344 | + |
| 345 | +|5.22 |
| 346 | +|Class `SummaryNotificationPosition` is deprecated in favor of link:https://neo4j.com/docs/api/python-driver/current/api.html#neo4j.SummaryInputPosition[`SummaryInputPosition`]. |
| 347 | +|label:deprecated[] |
| 348 | +|{check-mark} |
| 349 | + |
| 350 | +|5.0 |
| 351 | +|Undocumented methods `Neo4jError.is_fatal_during_discovery()` and `Neo4jError.invalidates_all_connections()` are deprecated without replacement. |
| 352 | +|label:deprecated[] |
| 353 | +|{check-mark} |
| 354 | + |
| 355 | +|5.26 |
| 356 | +|Undocumented method `Neo4jError.hydrate()` is deprecated without replacement. + |
| 357 | +Altering the attributes of a `Neo4jError` is deprecated. |
| 358 | +|label:deprecated[] |
| 359 | +|{check-mark} |
| 360 | + |
| 361 | +|=== |
0 commit comments