diff --git a/sql_export/models/sql_export.py b/sql_export/models/sql_export.py
index 7be136f84..5463a328a 100644
--- a/sql_export/models/sql_export.py
+++ b/sql_export/models/sql_export.py
@@ -16,9 +16,14 @@ class SqlExport(models.Model):
_check_execution_enabled = False
copy_options = fields.Char(
- string='Copy Options', required=True,
+ string='Copy Options', required=False,
default="CSV HEADER DELIMITER ';'")
+ file_format = fields.Selection(
+ [('csv', 'CSV')],
+ default='csv',
+ required=True)
+
field_ids = fields.Many2many(
'ir.model.fields',
'fields_sqlquery_rel',
@@ -48,3 +53,18 @@ class SqlExport(models.Model):
'context': self.env.context,
'nodestroy': True,
}
+
+ def _get_file_extension(self):
+ self.ensure_one()
+ if self.file_format == 'csv':
+ return 'csv'
+
+ def csv_get_datas_from_query(self, variable_dict):
+ self.ensure_one()
+ # Execute Request
+ res = self._execute_sql_request(
+ params=variable_dict, mode='stdout',
+ copy_options=self.copy_options)
+ if self.encoding:
+ res = res.decode(self.encoding)
+ return res
diff --git a/sql_export/views/sql_export_view.xml b/sql_export/views/sql_export_view.xml
index 53ac7f4f0..5a4d1b7d4 100644
--- a/sql_export/views/sql_export_view.xml
+++ b/sql_export/views/sql_export_view.xml
@@ -21,7 +21,8 @@
-
+
+
diff --git a/sql_export/wizard/wizard_file.py b/sql_export/wizard/wizard_file.py
index fad2c569c..52614f9e1 100644
--- a/sql_export/wizard/wizard_file.py
+++ b/sql_export/wizard/wizard_file.py
@@ -68,16 +68,15 @@ class SqlFileWizard(models.TransientModel):
if "%(user_id)s" in sql_export.query:
variable_dict['user_id'] = self.env.uid
- # Execute Request
- res = sql_export._execute_sql_request(
- params=variable_dict, mode='stdout',
- copy_options=sql_export.copy_options)
- if self.sql_export_id.encoding:
- res = res.decode(self.sql_export_id.encoding)
+ # Call different method depending on file_type since the logic will be
+ # different
+ method_name = '%s_get_datas_from_query' % sql_export.file_format
+ datas = getattr(sql_export, method_name)(variable_dict)
+ extension = sql_export._get_file_extension()
self.write({
- 'binary_file': res,
- 'file_name': '%(name)s_%(date)s.csv' % {
- 'name': sql_export.name, 'date': date}
+ 'binary_file': datas,
+ 'file_name': '%(name)s_%(date)s.%(extension)s' % {
+ 'name': sql_export.name, 'date': date, 'extension': extension}
})
return {
'view_mode': 'form',
diff --git a/sql_export_excel/__openerp__.py b/sql_export_excel/__manifest__.py
similarity index 90%
rename from sql_export_excel/__openerp__.py
rename to sql_export_excel/__manifest__.py
index c130eece7..237b2df70 100644
--- a/sql_export_excel/__openerp__.py
+++ b/sql_export_excel/__manifest__.py
@@ -1,10 +1,9 @@
-# -*- coding: utf-8 -*-
# Copyright 2019 Akretion
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
{
'name': 'SQL Export Excel',
- 'version': '9.0.1.0.0',
+ 'version': '12.0.1.0.0',
'author': 'Akretion,Odoo Community Association (OCA)',
'website': 'http://github/oca/server-tools',
'license': 'AGPL-3',
diff --git a/sql_export_excel/models/sql_export.py b/sql_export_excel/models/sql_export.py
index bb1ea5e49..48a45cf90 100644
--- a/sql_export_excel/models/sql_export.py
+++ b/sql_export_excel/models/sql_export.py
@@ -1,9 +1,8 @@
-# -*- coding: utf-8 -*-
# Copyright 2019 Akretion
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
from openerp import api, exceptions, fields, models, _
-from cStringIO import StringIO
+from io import BytesIO
import logging
import base64
_logger = logging.getLogger(__name__)
@@ -78,7 +77,7 @@ class SqlExport(models.Model):
# Case we insert data in an existing excel file.
if self.attachment_id:
datas = self.attachment_id.datas
- infile = StringIO()
+ infile = BytesIO()
infile.write(base64.b64decode(datas))
infile.seek(0)
wb = openpyxl.load_workbook(filename=infile)
@@ -100,7 +99,7 @@ class SqlExport(models.Model):
for index, row in enumerate(res, row_position):
for col, val in enumerate(row, col_position):
ws.cell(row=index, column=col).value = val
- output = StringIO()
+ output = BytesIO()
wb.save(output)
output.getvalue()
output_datas = base64.b64encode(output.getvalue())
diff --git a/sql_export_excel/tests/__init__.py b/sql_export_excel/tests/__init__.py
index 22c4421ab..6d89d7607 100644
--- a/sql_export_excel/tests/__init__.py
+++ b/sql_export_excel/tests/__init__.py
@@ -1,2 +1 @@
-# -*- coding: utf-8 -*-
from . import test_sql_query_excel
diff --git a/sql_export_excel/tests/test_sql_query_excel.py b/sql_export_excel/tests/test_sql_query_excel.py
index a51423c67..b1433c55b 100644
--- a/sql_export_excel/tests/test_sql_query_excel.py
+++ b/sql_export_excel/tests/test_sql_query_excel.py
@@ -1,11 +1,10 @@
-# -*- coding: utf-8 -*-
# Copyright (C) 2019 Akretion ()
# @author: Florian da Costa
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
-from openerp.tests.common import TransactionCase
+from odoo.tests.common import TransactionCase
import base64
-from cStringIO import StringIO
+from io import BytesIO
import logging
_logger = logging.getLogger(__name__)
@@ -25,7 +24,7 @@ class TestExportSqlQueryExcel(TransactionCase):
def get_workbook_from_query(self, wizard):
wizard.export_sql()
decoded_data = base64.b64decode(wizard.binary_file)
- xlsx_file = StringIO(decoded_data)
+ xlsx_file = BytesIO(decoded_data)
return openpyxl.load_workbook(xlsx_file)
def test_excel_file_generation(self):
@@ -63,7 +62,7 @@ class TestExportSqlQueryExcel(TransactionCase):
ws2 = wb.create_sheet("data")
ws2.cell(row=1, column=1, value='Partner Id')
ws2.cell(row=1, column=2, value='Partner Name')
- output = StringIO()
+ output = BytesIO()
wb.save(output)
data = output.getvalue()
diff --git a/sql_request_abstract/models/sql_request_mixin.py b/sql_request_abstract/models/sql_request_mixin.py
index cd2010355..71e3588c0 100644
--- a/sql_request_abstract/models/sql_request_mixin.py
+++ b/sql_request_abstract/models/sql_request_mixin.py
@@ -100,7 +100,8 @@ class SQLRequestMixin(models.AbstractModel):
@api.multi
def _execute_sql_request(
self, params=None, mode='fetchall', rollback=True,
- view_name=False, copy_options="CSV HEADER DELIMITER ';'"):
+ view_name=False, copy_options="CSV HEADER DELIMITER ';'",
+ header=False):
"""Execute a SQL request on the current database.
??? This function checks before if the user has the
@@ -126,6 +127,9 @@ class SQLRequestMixin(models.AbstractModel):
:param copy_options: (str) mentions extra options for
"COPY request STDOUT WITH xxx" request.
(Ignored if @mode != 'stdout')
+ :param header: (boolean) if true, the header of the query will be
+ returned as first element of the list if the mode is fetchall.
+ (Ignored if @mode != fetchall)
..note:: The following exceptions could be raised:
psycopg2.ProgrammingError: Error in the SQL Request.
@@ -175,6 +179,11 @@ class SQLRequestMixin(models.AbstractModel):
self.env.cr.execute(query)
if mode == 'fetchall':
res = self.env.cr.fetchall()
+ if header:
+ colnames = [
+ desc[0] for desc in self.env.cr.description
+ ]
+ res.insert(0, colnames)
elif mode == 'fetchone':
res = self.env.cr.fetchone()
finally: