Implemented update and delete method for the db plugin and ON DUPLICATE UPDATE logic for insert
This commit is contained in:
parent
42fa8360f3
commit
7114d8bcaa
1 changed files with 123 additions and 6 deletions
|
@ -14,9 +14,6 @@ class DbPlugin(Plugin):
|
||||||
|
|
||||||
Requires:
|
Requires:
|
||||||
* **sqlalchemy** (``pip install sqlalchemy``)
|
* **sqlalchemy** (``pip install sqlalchemy``)
|
||||||
|
|
||||||
.. todo::
|
|
||||||
Implement ``update`` and ``delete`` methods
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
engine = None
|
engine = None
|
||||||
|
@ -122,7 +119,8 @@ class DbPlugin(Plugin):
|
||||||
|
|
||||||
|
|
||||||
@action
|
@action
|
||||||
def insert(self, table, records, engine=None, *args, **kwargs):
|
def insert(self, table, records, engine=None, key_columns=[],
|
||||||
|
on_duplicate_update=False, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Inserts records (as a list of hashes) into a table.
|
Inserts records (as a list of hashes) into a table.
|
||||||
|
|
||||||
|
@ -132,6 +130,10 @@ class DbPlugin(Plugin):
|
||||||
:type records: list
|
:type records: list
|
||||||
:param engine: Engine to be used (default: default class engine)
|
:param engine: Engine to be used (default: default class engine)
|
||||||
:type engine: str
|
:type engine: str
|
||||||
|
:param key_columns: Set it to specify the names of the key columns for ``table``. Set it if you want your statement to be executed with the ``on_duplicate_update`` flag.
|
||||||
|
:type key_columns: list
|
||||||
|
:param on_duplicate_update: If set, update the records in case of duplicate rows (default: False). If set, you'll need to specify ``key_columns`` as well.
|
||||||
|
:type on_duplicate_update: bool
|
||||||
:param args: Extra arguments that will be passed to ``sqlalchemy.create_engine`` (see http://docs.sqlalchemy.org/en/latest/core/engines.html)
|
:param args: Extra arguments that will be passed to ``sqlalchemy.create_engine`` (see http://docs.sqlalchemy.org/en/latest/core/engines.html)
|
||||||
:param kwargs: Extra kwargs that will be passed to ``sqlalchemy.create_engine`` (see http://docs.sqlalchemy.org/en/latest/core/engines.html)
|
:param kwargs: Extra kwargs that will be passed to ``sqlalchemy.create_engine`` (see http://docs.sqlalchemy.org/en/latest/core/engines.html)
|
||||||
|
|
||||||
|
@ -161,13 +163,128 @@ class DbPlugin(Plugin):
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
db = self._get_engine(engine, *args, **kwargs)
|
||||||
|
|
||||||
|
for record in records:
|
||||||
|
metadata = MetaData()
|
||||||
|
table = Table(table, metadata, autoload=True, autoload_with=db)
|
||||||
|
insert = table.insert().values(**record)
|
||||||
|
|
||||||
|
try:
|
||||||
|
db.execute(insert)
|
||||||
|
except Exception as e:
|
||||||
|
if on_duplicate_update and key_columns:
|
||||||
|
self.update(table=table, records=records,
|
||||||
|
key_columns=key_columns, engine=engine,
|
||||||
|
*args, **kwargs)
|
||||||
|
else:
|
||||||
|
raise e
|
||||||
|
|
||||||
|
|
||||||
|
@action
|
||||||
|
def update(self, table, records, key_columns, engine=None, *args, **kwargs):
|
||||||
|
"""
|
||||||
|
Updates records on a table.
|
||||||
|
|
||||||
|
:param table: Table name
|
||||||
|
:type table: str
|
||||||
|
:param records: Records to be updated (as a list of hashes)
|
||||||
|
:type records: list
|
||||||
|
:param key_columns: Names of the key columns, used in the WHERE condition
|
||||||
|
:type key_columns: list
|
||||||
|
:param engine: Engine to be used (default: default class engine)
|
||||||
|
:type engine: str
|
||||||
|
:param args: Extra arguments that will be passed to ``sqlalchemy.create_engine`` (see http://docs.sqlalchemy.org/en/latest/core/engines.html)
|
||||||
|
:param kwargs: Extra kwargs that will be passed to ``sqlalchemy.create_engine`` (see http://docs.sqlalchemy.org/en/latest/core/engines.html)
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
Request::
|
||||||
|
|
||||||
|
{
|
||||||
|
"type": "request",
|
||||||
|
"target": "your_host",
|
||||||
|
"action": "db.update",
|
||||||
|
"args": {
|
||||||
|
"table": "table",
|
||||||
|
"engine": "sqlite:///:memory:",
|
||||||
|
"key_columns": ["id"],
|
||||||
|
"records": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"name": foo
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"name": bar
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
engine = self._get_engine(engine, *args, **kwargs)
|
engine = self._get_engine(engine, *args, **kwargs)
|
||||||
|
|
||||||
for record in records:
|
for record in records:
|
||||||
metadata = MetaData()
|
metadata = MetaData()
|
||||||
table = Table(table, metadata, autoload=True, autoload_with=engine)
|
table = Table(table, metadata, autoload=True, autoload_with=engine)
|
||||||
insert = table.insert().values(**record)
|
key = { k:v for (k,v) in record.items() if k in key_columns }
|
||||||
engine.execute(insert)
|
values = { k:v for (k,v) in record.items() if k not in key_columns }
|
||||||
|
|
||||||
|
update = table.update()
|
||||||
|
|
||||||
|
for (k,v) in key.items():
|
||||||
|
update = update.where(eval('table.c.{}=={}'.format(k, v)))
|
||||||
|
|
||||||
|
update = update.values(**values)
|
||||||
|
engine.execute(update)
|
||||||
|
|
||||||
|
|
||||||
|
@action
|
||||||
|
def delete(self, table, records, engine=None, *args, **kwargs):
|
||||||
|
"""
|
||||||
|
Deletes records from a table.
|
||||||
|
|
||||||
|
:param table: Table name
|
||||||
|
:type table: str
|
||||||
|
:param records: Records to be deleted, as a list of dictionaries
|
||||||
|
:type records: list
|
||||||
|
:param engine: Engine to be used (default: default class engine)
|
||||||
|
:type engine: str
|
||||||
|
:param args: Extra arguments that will be passed to ``sqlalchemy.create_engine`` (see http://docs.sqlalchemy.org/en/latest/core/engines.html)
|
||||||
|
:param kwargs: Extra kwargs that will be passed to ``sqlalchemy.create_engine`` (see http://docs.sqlalchemy.org/en/latest/core/engines.html)
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
Request::
|
||||||
|
|
||||||
|
{
|
||||||
|
"type": "request",
|
||||||
|
"target": "your_host",
|
||||||
|
"action": "db.delete",
|
||||||
|
"args": {
|
||||||
|
"table": "table",
|
||||||
|
"engine": "sqlite:///:memory:",
|
||||||
|
"records": [
|
||||||
|
{ "id": 1 },
|
||||||
|
{ "id": 2 }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
engine = self._get_engine(engine, *args, **kwargs)
|
||||||
|
|
||||||
|
for record in records:
|
||||||
|
metadata = MetaData()
|
||||||
|
table = Table(table, metadata, autoload=True, autoload_with=engine)
|
||||||
|
delete = table.delete()
|
||||||
|
|
||||||
|
for (k,v) in record.items():
|
||||||
|
delete = delete.where(eval('table.c.{}=={}'.format(k, v)))
|
||||||
|
|
||||||
|
engine.execute(delete)
|
||||||
|
|
||||||
|
|
||||||
# vim:sw=4:ts=4:et:
|
# vim:sw=4:ts=4:et:
|
||||||
|
|
Loading…
Reference in a new issue