Skip to content

Commit a4b6d6b

Browse files
committed
fix #6: allow update existing table or skipping it by perform no action on existing data
1 parent db460c6 commit a4b6d6b

File tree

3 files changed

+92
-9
lines changed

3 files changed

+92
-9
lines changed

pyexcel_io/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
)
2222
from .csvbook import CSVBook, CSVWriter
2323
from .csvzipbook import CSVZipWriter, CSVZipBook
24-
from .sqlbook import SQLBookReader, SQLBookWriter
24+
from .sqlbook import SQLBookReader, SQLBookWriter, PyexcelSQLSkipRowException
2525
from .djangobook import DjangoBookReader, DjangoBookWriter
2626
from ._compact import is_string, BytesIO, StringIO, isstream, OrderedDict, PY2
2727
from .constants import (

pyexcel_io/sqlbook.py

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
from ._compact import OrderedDict
1111
from .constants import (
1212
MESSAGE_INVALID_PARAMETERS,
13-
MESSAGE_EMPTY_ARRAY
13+
MESSAGE_EMPTY_ARRAY,
14+
MESSAGE_IGNORE_ROW
1415
)
1516
from .base import (
1617
BookReaderBase,
@@ -23,6 +24,14 @@
2324
)
2425

2526

27+
class PyexcelSQLSkipRowException(Exception):
28+
"""
29+
Raised this exception to skipping a row
30+
while data import
31+
"""
32+
pass
33+
34+
2635
class SQLTableReader(SheetReaderBase):
2736
"""Read a table
2837
"""
@@ -83,21 +92,28 @@ def write_row(self, array):
8392
print(MESSAGE_EMPTY_ARRAY)
8493
else:
8594
new_array = swap_empty_string_for_none(array)
86-
self._write_row(new_array)
95+
try:
96+
self._write_row(new_array)
97+
except PyexcelSQLSkipRowException:
98+
print(MESSAGE_IGNORE_ROW)
99+
print(new_array)
87100

88101
def _write_row(self, array):
89102
row = dict(zip(self.column_names, array))
103+
obj = None
90104
if self.initializer:
91-
o = self.initializer(row)
92-
else:
93-
o = self.table()
105+
# allow initinalizer to return None
106+
# if skipping is needed
107+
obj = self.initializer(row)
108+
if obj is None:
109+
obj = self.table()
94110
for name in self.column_names:
95111
if self.mapdict is not None:
96112
key = self.mapdict[name]
97113
else:
98114
key = name
99-
setattr(o, key, row[name])
100-
self.session.add(o)
115+
setattr(obj, key, row[name])
116+
self.session.add(obj)
101117

102118
def close(self):
103119
if self.auto_commit:

tests/test_sql_book.py

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
SQLBookReader,
99
SQLBookWriter,
1010
from_query_sets,
11-
OrderedDict
11+
OrderedDict,
12+
PyexcelSQLSkipRowException
1213
)
1314
from pyexcel_io.sqlbook import SQLTableReader, SQLTableWriter
1415
from sqlalchemy.orm import relationship, backref
@@ -121,6 +122,72 @@ def test_one_table(self):
121122
assert results == self.results
122123
mysession.close()
123124

125+
def test_update_existing_row(self):
126+
mysession = Session()
127+
# write existing data
128+
writer = SQLTableWriter(mysession,
129+
[Pyexcel,self.data[0], None, None])
130+
writer.write_array(self.data[1:])
131+
writer.close()
132+
query_sets=mysession.query(Pyexcel).all()
133+
results = from_query_sets(self.data[0], query_sets)
134+
assert results == self.results
135+
# update data using custom initializer
136+
update_data = [
137+
['birth', 'id', 'name', 'weight'],
138+
[datetime.date(2014, 11, 11), 0, 'Adam_E', 12.25],
139+
[datetime.date(2014, 11, 12), 1, 'Smith_E', 11.25]
140+
]
141+
updated_results = [
142+
['birth', 'id', 'name', 'weight'],
143+
['2014-11-11', 0, 'Adam_E', 12.25],
144+
['2014-11-12', 1, 'Smith_E', 11.25]
145+
]
146+
def row_updater(row):
147+
an_instance = mysession.query(Pyexcel).get(row['id'])
148+
if an_instance is None:
149+
an_instance = Pyexcel()
150+
for name in row.keys():
151+
setattr(an_instance, name, row[name])
152+
return an_instance
153+
writer = SQLTableWriter(mysession,
154+
[Pyexcel,update_data[0], None, row_updater])
155+
writer.write_array(update_data[1:])
156+
writer.close()
157+
query_sets=mysession.query(Pyexcel).all()
158+
results = from_query_sets(self.data[0], query_sets)
159+
assert results == updated_results
160+
mysession.close()
161+
162+
def test_skipping_rows_if_data_exist(self):
163+
mysession = Session()
164+
# write existing data
165+
writer = SQLTableWriter(mysession,
166+
[Pyexcel,self.data[0], None, None])
167+
writer.write_array(self.data[1:])
168+
writer.close()
169+
query_sets=mysession.query(Pyexcel).all()
170+
results = from_query_sets(self.data[0], query_sets)
171+
assert results == self.results
172+
# update data using custom initializer
173+
update_data = [
174+
['birth', 'id', 'name', 'weight'],
175+
[datetime.date(2014, 11, 11), 0, 'Adam_E', 12.25],
176+
[datetime.date(2014, 11, 12), 1, 'Smith_E', 11.25]
177+
]
178+
def row_updater(row):
179+
an_instance = mysession.query(Pyexcel).get(row['id'])
180+
if an_instance is not None:
181+
raise PyexcelSQLSkipRowException()
182+
writer = SQLTableWriter(mysession,
183+
[Pyexcel,update_data[0], None, row_updater])
184+
writer.write_array(update_data[1:])
185+
writer.close()
186+
query_sets=mysession.query(Pyexcel).all()
187+
results = from_query_sets(self.data[0], query_sets)
188+
assert results == self.results
189+
mysession.close()
190+
124191
def test_one_table_with_empty_rows(self):
125192
mysession = Session()
126193
data = [

0 commit comments

Comments
 (0)