From 0ed556925539a73813ce86a9fe0d457e8864dbef Mon Sep 17 00:00:00 2001 From: Sergio Teruel Date: Thu, 9 Jan 2020 20:57:58 +0100 Subject: [PATCH] [MIG] base_external_dbsource: Migration to v13.0 --- base_external_dbsource/README.rst | 10 +- base_external_dbsource/__manifest__.py | 33 ++-- .../models/base_external_dbsource.py | 125 ++++++------- .../static/description/index.html | 6 +- .../tests/test_base_external_dbsource.py | 170 +++++++++--------- .../views/base_external_dbsource.xml | 1 - 6 files changed, 152 insertions(+), 193 deletions(-) diff --git a/base_external_dbsource/README.rst b/base_external_dbsource/README.rst index cd46404f..56549feb 100644 --- a/base_external_dbsource/README.rst +++ b/base_external_dbsource/README.rst @@ -14,13 +14,13 @@ External Database Sources :target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html :alt: License: LGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fserver--backend-lightgray.png?logo=github - :target: https://github.com/OCA/server-backend/tree/12.0/base_external_dbsource + :target: https://github.com/OCA/server-backend/tree/13.0/base_external_dbsource :alt: OCA/server-backend .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/server-backend-12-0/server-backend-12-0-base_external_dbsource + :target: https://translation.odoo-community.org/projects/server-backend-13-0/server-backend-13-0-base_external_dbsource :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png - :target: https://runbot.odoo-community.org/runbot/253/12.0 + :target: https://runbot.odoo-community.org/runbot/253/13.0 :alt: Try me on Runbot |badge1| |badge2| |badge3| |badge4| |badge5| @@ -75,7 +75,7 @@ Bug Tracker Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us smashing it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -111,6 +111,6 @@ OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use. -This module is part of the `OCA/server-backend `_ project on GitHub. +This module is part of the `OCA/server-backend `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/base_external_dbsource/__manifest__.py b/base_external_dbsource/__manifest__.py index 6d5861fe..a196c05d 100644 --- a/base_external_dbsource/__manifest__.py +++ b/base_external_dbsource/__manifest__.py @@ -2,26 +2,15 @@ # Copyright <2016> # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). { - 'name': 'External Database Sources', - 'version': '12.0.1.0.1', - 'category': 'Tools', - 'author': "Daniel Reis, " - "LasLabs, " - "Odoo Community Association (OCA)", - 'website': 'https://github.com/OCA/server-backend', - 'license': 'LGPL-3', - 'images': [ - 'images/screenshot01.png', - ], - 'depends': [ - 'base', - ], - 'data': [ - 'views/base_external_dbsource.xml', - 'security/ir.model.access.csv', - ], - 'demo': [ - 'demo/base_external_dbsource.xml', - ], - 'installable': True, + "name": "External Database Sources", + "version": "13.0.1.0.0", + "category": "Tools", + "author": "Daniel Reis, " "LasLabs, " "Odoo Community Association (OCA)", + "website": "https://github.com/OCA/server-backend", + "license": "LGPL-3", + "images": ["images/screenshot01.png"], + "depends": ["base"], + "data": ["views/base_external_dbsource.xml", "security/ir.model.access.csv"], + "demo": ["demo/base_external_dbsource.xml"], + "installable": True, } diff --git a/base_external_dbsource/models/base_external_dbsource.py b/base_external_dbsource/models/base_external_dbsource.py index 69c6a355..12653c1a 100644 --- a/base_external_dbsource/models/base_external_dbsource.py +++ b/base_external_dbsource/models/base_external_dbsource.py @@ -3,10 +3,10 @@ # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). import logging -import psycopg2 - from contextlib import contextmanager +import psycopg2 + from odoo import _, api, fields, models, tools from ..exceptions import ConnectionFailedError, ConnectionSuccessError @@ -33,18 +33,18 @@ class BaseExternalDbsource(models.Model): """ _name = "base.external.dbsource" - _description = 'External Database Sources' + _description = "External Database Sources" - CONNECTORS = [ - ('postgresql', 'PostgreSQL'), - ] + CONNECTORS = [("postgresql", "PostgreSQL")] # This is appended to the conn string if pass declared but not detected. # Children should declare PWD_STRING_CONNECTOR (such as PWD_STRING_FBD) # to allow for override. - PWD_STRING = 'PWD=%s;' + PWD_STRING = "PWD=%s;" - name = fields.Char('Datasource name', required=True, size=64) - conn_string = fields.Text('Connection string', help=""" + name = fields.Char("Datasource name", required=True, size=64) + conn_string = fields.Text( + "Connection string", + help=""" Sample connection strings: - Microsoft SQL Server: mssql+pymssql://username:%s@server:port/dbname?charset=utf8 @@ -56,34 +56,31 @@ class BaseExternalDbsource(models.Model): password=%s - SQLite: sqlite:///test.db - Elasticsearch: https://user:%s@localhost:9200 - """) - conn_string_full = fields.Text( - readonly=True, - compute='_compute_conn_string_full', + """, ) - password = fields.Char('Password', size=40) + conn_string_full = fields.Text(readonly=True, compute="_compute_conn_string_full") + password = fields.Char("Password", size=40) client_cert = fields.Text() client_key = fields.Text() - ca_certs = fields.Char( - help='Path to CA Certs file on server.', - ) + ca_certs = fields.Char(help="Path to CA Certs file on server.") connector = fields.Selection( - CONNECTORS, 'Connector', required=True, + CONNECTORS, + "Connector", + required=True, help="If a connector is missing from the list, check the server " - "log to confirm that the required components were detected.", + "log to confirm that the required components were detected.", ) current_table = None - @api.multi - @api.depends('conn_string', 'password') + @api.depends("conn_string", "password") def _compute_conn_string_full(self): for record in self: if record.password: - if '%s' not in record.conn_string: + if "%s" not in record.conn_string: pwd_string = getattr( record, - 'PWD_STRING_%s' % record.connector.upper(), + "PWD_STRING_%s" % record.connector.upper(), record.PWD_STRING, ) record.conn_string += pwd_string @@ -93,12 +90,10 @@ class BaseExternalDbsource(models.Model): # Interface - @api.multi def change_table(self, name): """ Change the table that is used for CRUD operations """ self.current_table = name - @api.multi def connection_close(self, connection): """ It closes the connection to the data source. @@ -106,10 +101,9 @@ class BaseExternalDbsource(models.Model): the adapter type. """ - method = self._get_adapter_method('connection_close') + method = self._get_adapter_method("connection_close") return method(connection) - @api.multi @contextmanager def connection_open(self): """ It provides a context manager for the data source. @@ -118,20 +112,17 @@ class BaseExternalDbsource(models.Model): the adapter type. """ - method = self._get_adapter_method('connection_open') + method = self._get_adapter_method("connection_open") try: connection = method() yield connection finally: try: self.connection_close(connection) - except: - _logger.exception('Connection close failure.') + except Exception: + _logger.exception("Connection close failure.") - @api.multi - def execute( - self, query=None, execute_params=None, metadata=False, **kwargs - ): + def execute(self, query=None, execute_params=None, metadata=False, **kwargs): """ Executes a query and returns a list of rows. "execute_params" can be a dict of values, that can be referenced @@ -154,24 +145,23 @@ class BaseExternalDbsource(models.Model): # Old API compatibility if not query: try: - query = kwargs['sqlquery'] + query = kwargs["sqlquery"] except KeyError: - raise TypeError(_('query is a required argument')) + raise TypeError(_("query is a required argument")) if not execute_params: try: - execute_params = kwargs['sqlparams'] + execute_params = kwargs["sqlparams"] except KeyError: pass - method = self._get_adapter_method('execute') + method = self._get_adapter_method("execute") rows, cols = method(query, execute_params, metadata) if metadata: - return {'cols': cols, 'rows': rows} + return {"cols": cols, "rows": rows} else: return rows - @api.multi def connection_test(self): """ It tests the connection @@ -179,22 +169,18 @@ class BaseExternalDbsource(models.Model): ConnectionSuccessError: On connection success ConnectionFailedError: On connection failed """ + try: + with self.connection_open(): + pass + except Exception as e: + raise ConnectionFailedError( + _("Connection test failed:\n" "Here is what we got instead:\n%s") + % tools.ustr(e) + ) + raise ConnectionSuccessError( + _("Connection test succeeded:\n" "Everything seems properly set up!") + ) - for obj in self: - try: - with self.connection_open(): - pass - except Exception as e: - raise ConnectionFailedError(_( - "Connection test failed:\n" - "Here is what we got instead:\n%s" - ) % tools.ustr(e)) - raise ConnectionSuccessError(_( - "Connection test succeeded:\n" - "Everything seems properly set up!", - )) - - @api.multi def remote_browse(self, record_ids, *args, **kwargs): """ It browses for and returns the records from remote by ID @@ -210,10 +196,9 @@ class BaseExternalDbsource(models.Model): """ assert self.current_table - method = self._get_adapter_method('remote_browse') + method = self._get_adapter_method("remote_browse") return method(record_ids, *args, **kwargs) - @api.multi def remote_create(self, vals, *args, **kwargs): """ It creates a record on the remote data source. @@ -229,10 +214,9 @@ class BaseExternalDbsource(models.Model): """ assert self.current_table - method = self._get_adapter_method('remote_create') + method = self._get_adapter_method("remote_create") return method(vals, *args, **kwargs) - @api.multi def remote_delete(self, record_ids, *args, **kwargs): """ It deletes records by ID on remote @@ -248,10 +232,9 @@ class BaseExternalDbsource(models.Model): """ assert self.current_table - method = self._get_adapter_method('remote_delete') + method = self._get_adapter_method("remote_delete") return method(record_ids, *args, **kwargs) - @api.multi def remote_search(self, query, *args, **kwargs): """ It searches the remote for the query. @@ -267,10 +250,9 @@ class BaseExternalDbsource(models.Model): """ assert self.current_table - method = self._get_adapter_method('remote_search') + method = self._get_adapter_method("remote_search") return method(query, *args, **kwargs) - @api.multi def remote_update(self, record_ids, vals, *args, **kwargs): """ It updates the remote records with the vals @@ -286,7 +268,7 @@ class BaseExternalDbsource(models.Model): """ assert self.current_table - method = self._get_adapter_method('remote_update') + method = self._get_adapter_method("remote_update") return method(record_ids, vals, *args, **kwargs) # Adapters @@ -312,7 +294,6 @@ class BaseExternalDbsource(models.Model): # Compatibility & Private - @api.multi def conn_open(self): """ It opens and returns a connection to the remote data source. @@ -339,14 +320,14 @@ class BaseExternalDbsource(models.Model): """ self.ensure_one() - method = '%s_%s' % (method_prefix, self.connector) + method = "{}_{}".format(method_prefix, self.connector) try: return getattr(self, method) except AttributeError: - raise NotImplementedError(_( - '"%s" method not found, check that all assets are installed ' - 'for the %s connector type.' - )) % ( - method, self.connector, - ) + raise NotImplementedError( + _( + '"%s" method not found, check that all assets are installed ' + "for the %s connector type." + ) + ) % (method, self.connector) diff --git a/base_external_dbsource/static/description/index.html b/base_external_dbsource/static/description/index.html index 0c0ae80c..7b3cad00 100644 --- a/base_external_dbsource/static/description/index.html +++ b/base_external_dbsource/static/description/index.html @@ -367,7 +367,7 @@ ul.auto-toc { !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> -

Beta License: LGPL-3 OCA/server-backend Translate me on Weblate Try me on Runbot

+

Beta License: LGPL-3 OCA/server-backend Translate me on Weblate Try me on Runbot

This module allows you to define connections to foreign databases using ODBC, Firebird, Oracle Client or SQLAlchemy.

Table of contents

@@ -427,7 +427,7 @@ support larger datasets in a more efficient manner.

Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us smashing it by providing a detailed and welcomed -feedback.

+feedback.

Do not contact contributors directly about support or help with technical issues.

@@ -457,7 +457,7 @@ If you spotted it first, help us smashing it by providing a detailed and welcome

OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use.

-

This module is part of the OCA/server-backend project on GitHub.

+

This module is part of the OCA/server-backend project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

diff --git a/base_external_dbsource/tests/test_base_external_dbsource.py b/base_external_dbsource/tests/test_base_external_dbsource.py index 917c0ac6..fcc47dfe 100644 --- a/base_external_dbsource/tests/test_base_external_dbsource.py +++ b/base_external_dbsource/tests/test_base_external_dbsource.py @@ -2,14 +2,13 @@ import mock -from odoo.tests import common from odoo.sql_db import connection_info_for +from odoo.tests import common from ..exceptions import ConnectionFailedError, ConnectionSuccessError class TestBaseExternalDbsource(common.TransactionCase): - def setUp(self): super(TestBaseExternalDbsource, self).setUp() # Obtain current odoo instance DB connection settings @@ -20,26 +19,32 @@ class TestBaseExternalDbsource(common.TransactionCase): connection_info["dbname"] = connection_info["database"] del connection_info["database"] # Create a proper dbsource record to test - self.dbsource = self.env["base.external.dbsource"].create({ - "conn_string": " ".join( - "%s='%s'" % item for item in connection_info.items() - ), - "connector": "postgresql", - "name": "test postgres with current odoo config", - "password": password, - }) + self.dbsource = self.env["base.external.dbsource"].create( + { + "conn_string": " ".join( + "%s='%s'" % item for item in connection_info.items() + ), + "connector": "postgresql", + "name": "test postgres with current odoo config", + "password": password, + } + ) def _test_adapter_method( - self, method_name, side_effect=None, return_value=None, - create=False, args=None, kwargs=None, + self, + method_name, + side_effect=None, + return_value=None, + create=False, + args=None, + kwargs=None, ): if args is None: args = [] if kwargs is None: kwargs = {} - adapter = '%s_postgresql' % method_name - with mock.patch.object(self.dbsource, - adapter, create=create) as adapter: + adapter = "%s_postgresql" % method_name + with mock.patch.object(self.dbsource, adapter, create=create) as adapter: if side_effect is not None: adapter.side_effect = side_effect elif return_value is not None: @@ -49,12 +54,10 @@ class TestBaseExternalDbsource(common.TransactionCase): def test_conn_string_full(self): """ It should add password if string interpolation not detected """ - self.dbsource.conn_string = 'User=Derp;' - self.dbsource.password = 'password' - expect = self.dbsource.conn_string + 'PWD=%s;' % self.dbsource.password - self.assertEqual( - self.dbsource.conn_string_full, expect, - ) + self.dbsource.conn_string = "User=Derp;" + self.dbsource.password = "password" + expect = self.dbsource.conn_string + "PWD=%s;" % self.dbsource.password + self.assertEqual(self.dbsource.conn_string_full, expect) # Interface @@ -65,16 +68,14 @@ class TestBaseExternalDbsource(common.TransactionCase): def test_connection_fail(self): """ It should raise for failed/invalid connection """ - with mock.patch.object(self.dbsource, 'connection_open') as conn: + with mock.patch.object(self.dbsource, "connection_open") as conn: conn.side_effect = Exception with self.assertRaises(ConnectionFailedError): self.dbsource.connection_test() def test_connection_open_calls_close(self): """ It should close connection after context ends """ - with mock.patch.object( - self.dbsource, 'connection_close', - ) as close: + with mock.patch.object(self.dbsource, "connection_close") as close: with self.dbsource.connection_open(): pass close.assert_called_once() @@ -82,9 +83,7 @@ class TestBaseExternalDbsource(common.TransactionCase): def test_connection_close(self): """ It should call adapter's close method """ args = [mock.MagicMock()] - res, adapter = self._test_adapter_method( - 'connection_close', args=args, - ) + res, adapter = self._test_adapter_method("connection_close", args=args) adapter.assert_called_once_with(args[0]) def test_execute_asserts_query_arg(self): @@ -94,144 +93,140 @@ class TestBaseExternalDbsource(common.TransactionCase): def test_execute_calls_adapter(self): """ It should call the adapter methods with proper args """ - expect = ('query', 'execute', 'metadata') - return_value = 'rows', 'cols' + expect = ("query", "execute", "metadata") + return_value = "rows", "cols" res, adapter = self._test_adapter_method( - 'execute', args=expect, return_value=return_value, + "execute", args=expect, return_value=return_value ) adapter.assert_called_once_with(*expect) def test_execute_return(self): """ It should return rows if not metadata """ expect = (True, True, False) - return_value = 'rows', 'cols' + return_value = "rows", "cols" res, adapter = self._test_adapter_method( - 'execute', args=expect, return_value=return_value, + "execute", args=expect, return_value=return_value ) self.assertEqual(res, return_value[0]) def test_execute_return_metadata(self): """ It should return rows and cols if metadata """ expect = (True, True, True) - return_value = 'rows', 'cols' + return_value = "rows", "cols" res, adapter = self._test_adapter_method( - 'execute', args=expect, return_value=return_value, - ) - self.assertEqual( - res, - {'rows': return_value[0], - 'cols': return_value[1]}, + "execute", args=expect, return_value=return_value ) + self.assertEqual(res, {"rows": return_value[0], "cols": return_value[1]}) def test_remote_browse(self): """ It should call the adapter method with proper args """ - args = [1], 'args' - kwargs = {'kwargs': True} - self.dbsource.current_table = 'table' + args = [1], "args" + kwargs = {"kwargs": True} + self.dbsource.current_table = "table" res, adapter = self._test_adapter_method( - 'remote_browse', create=True, args=args, kwargs=kwargs, + "remote_browse", create=True, args=args, kwargs=kwargs ) adapter.assert_called_once_with(*args, **kwargs) self.assertEqual(res, adapter()) def test_remote_browse_asserts_current_table(self): """ It should raise AssertionError if a table not selected """ - args = [1], 'args' - kwargs = {'kwargs': True} + args = [1], "args" + kwargs = {"kwargs": True} with self.assertRaises(AssertionError): res, adapter = self._test_adapter_method( - 'remote_browse', create=True, args=args, kwargs=kwargs, + "remote_browse", create=True, args=args, kwargs=kwargs ) def test_remote_create(self): """ It should call the adapter method with proper args """ - args = {'val': 'Value'}, 'args' - kwargs = {'kwargs': True} - self.dbsource.current_table = 'table' + args = {"val": "Value"}, "args" + kwargs = {"kwargs": True} + self.dbsource.current_table = "table" res, adapter = self._test_adapter_method( - 'remote_create', create=True, args=args, kwargs=kwargs, + "remote_create", create=True, args=args, kwargs=kwargs ) adapter.assert_called_once_with(*args, **kwargs) self.assertEqual(res, adapter()) def test_remote_create_asserts_current_table(self): """ It should raise AssertionError if a table not selected """ - args = [1], 'args' - kwargs = {'kwargs': True} + args = [1], "args" + kwargs = {"kwargs": True} with self.assertRaises(AssertionError): res, adapter = self._test_adapter_method( - 'remote_create', create=True, args=args, kwargs=kwargs, + "remote_create", create=True, args=args, kwargs=kwargs ) def test_remote_delete(self): """ It should call the adapter method with proper args """ - args = [1], 'args' - kwargs = {'kwargs': True} - self.dbsource.current_table = 'table' + args = [1], "args" + kwargs = {"kwargs": True} + self.dbsource.current_table = "table" res, adapter = self._test_adapter_method( - 'remote_delete', create=True, args=args, kwargs=kwargs, + "remote_delete", create=True, args=args, kwargs=kwargs ) adapter.assert_called_once_with(*args, **kwargs) self.assertEqual(res, adapter()) def test_remote_delete_asserts_current_table(self): """ It should raise AssertionError if a table not selected """ - args = [1], 'args' - kwargs = {'kwargs': True} + args = [1], "args" + kwargs = {"kwargs": True} with self.assertRaises(AssertionError): res, adapter = self._test_adapter_method( - 'remote_delete', create=True, args=args, kwargs=kwargs, + "remote_delete", create=True, args=args, kwargs=kwargs ) def test_remote_search(self): """ It should call the adapter method with proper args """ - args = {'search': 'query'}, 'args' - kwargs = {'kwargs': True} - self.dbsource.current_table = 'table' + args = {"search": "query"}, "args" + kwargs = {"kwargs": True} + self.dbsource.current_table = "table" res, adapter = self._test_adapter_method( - 'remote_search', create=True, args=args, kwargs=kwargs, + "remote_search", create=True, args=args, kwargs=kwargs ) adapter.assert_called_once_with(*args, **kwargs) self.assertEqual(res, adapter()) def test_remote_search_asserts_current_table(self): """ It should raise AssertionError if a table not selected """ - args = [1], 'args' - kwargs = {'kwargs': True} + args = [1], "args" + kwargs = {"kwargs": True} with self.assertRaises(AssertionError): res, adapter = self._test_adapter_method( - 'remote_search', create=True, args=args, kwargs=kwargs, + "remote_search", create=True, args=args, kwargs=kwargs ) def test_remote_update(self): """ It should call the adapter method with proper args """ - args = [1], {'vals': 'Value'}, 'args' - kwargs = {'kwargs': True} - self.dbsource.current_table = 'table' + args = [1], {"vals": "Value"}, "args" + kwargs = {"kwargs": True} + self.dbsource.current_table = "table" res, adapter = self._test_adapter_method( - 'remote_update', create=True, args=args, kwargs=kwargs, + "remote_update", create=True, args=args, kwargs=kwargs ) adapter.assert_called_once_with(*args, **kwargs) self.assertEqual(res, adapter()) def test_remote_update_asserts_current_table(self): """ It should raise AssertionError if a table not selected """ - args = [1], 'args' - kwargs = {'kwargs': True} + args = [1], "args" + kwargs = {"kwargs": True} with self.assertRaises(AssertionError): res, adapter = self._test_adapter_method( - 'remote_update', create=True, args=args, kwargs=kwargs, + "remote_update", create=True, args=args, kwargs=kwargs ) # Postgres def test_execute_postgresql(self): """ It should call generic executor with proper args """ - expect = ('query', 'execute', 'metadata') + expect = ("query", "execute", "metadata") with mock.patch.object( - self.dbsource, '_execute_generic', autospec=True, + self.dbsource, "_execute_generic", autospec=True ) as execute: - execute.return_value = 'rows', 'cols' + execute.return_value = "rows", "cols" self.dbsource.execute(*expect) execute.assert_called_once_with(*expect) @@ -239,24 +234,19 @@ class TestBaseExternalDbsource(common.TransactionCase): def test_execute_calls_adapter_old_api(self): """ It should call the adapter correctly if old kwargs provided """ - expect = [None, None, 'metadata'] + expect = [None, None, "metadata"] with mock.patch.object( - self.dbsource, 'execute_postgresql', autospec=True, + self.dbsource, "execute_postgresql", autospec=True ) as psql: - psql.return_value = 'rows', 'cols' - self.dbsource.execute( - *expect, sqlparams='params', sqlquery='query' - ) - expect[0], expect[1] = 'query', 'params' + psql.return_value = "rows", "cols" + self.dbsource.execute(*expect, sqlparams="params", sqlquery="query") + expect[0], expect[1] = "query", "params" psql.assert_called_once_with(*expect) def test_conn_open(self): """ It should return open connection for use """ with mock.patch.object( - self.dbsource, 'connection_open', autospec=True, + self.dbsource, "connection_open", autospec=True ) as connection: res = self.dbsource.conn_open() - self.assertEqual( - res, - connection().__enter__(), - ) + self.assertEqual(res, connection().__enter__()) diff --git a/base_external_dbsource/views/base_external_dbsource.xml b/base_external_dbsource/views/base_external_dbsource.xml index dcc72961..00539e77 100644 --- a/base_external_dbsource/views/base_external_dbsource.xml +++ b/base_external_dbsource/views/base_external_dbsource.xml @@ -47,7 +47,6 @@ External Database Sources base.external.dbsource - form tree,form