def datastore_upsert(context, data_dict): '''Updates or inserts into a table in the datastore The datastore_upsert API action allows a user to add or edit records to an existing dataStore resource. In order for the *upsert* and *update* methods to work, a unique key has to be defined via the datastore_create action. The available methods are: *upsert* Update if record with same key already exists, otherwise insert. Requires unique key. *insert* Insert only. This method is faster that upsert, but will fail if any inserted record matches an existing one. Does *not* require a unique key. *update* Update only. An exception will occur if the key that should be updated does not exist. Requires unique key. :param resource_id: resource id that the data is going to be stored under. :type resource_id: string :param records: the data, eg: [{"dob": "2005", "some_stuff": ["a","b"]}] :type records: list of dictionaries :param method: the method to use to put the data into the datastore. Possible options are: upsert (default), insert, update :type method: string :returns: the newly created data object. :rtype: dictionary ''' # res_id = _get_or_bust(data_dict, 'resource_id') res_id = data_dict['resource_id'] # data_dict['connection_url'] = pylons.config['ckan.datastore.write_url'] resources_sql = sqlalchemy.text(u'''SELECT 1 FROM "_table_metadata" WHERE name = :id AND alias_of IS NULL''') results = db._get_engine(None, data_dict).execute(resources_sql, id=res_id) res_exists = results.rowcount > 0 if not res_exists: raise p.toolkit.ObjectNotFound(p.toolkit._( 'Resource "{0}" was not found.'.format(res_id) )) # p.toolkit.check_access('datastore_upsert', context, data_dict) result = db.upsert(context, data_dict) if 'id' in result: result.pop('id') result.pop('connection_url') return result
def datastore_delete(context, data_dict): '''Deletes a table or a set of records from the datastore. :param resource_id: resource id that the data will be deleted from. :type resource_id: string :param filters: filters to apply before deleting (eg {"name": "fred"}). If missing delete whole table and all dependent views. :type filters: dictionary :returns: original filters sent. :rtype: dictionary ''' # res_id = _get_or_bust(data_dict, 'resource_id') res_id = data_dict['resource_id'] # data_dict['connection_url'] = pylons.config['ckan.datastore.write_url'] resources_sql = sqlalchemy.text(u'''SELECT 1 FROM "_table_metadata" WHERE name = :id AND alias_of IS NULL''') results = db._get_engine(None, data_dict).execute(resources_sql, id=res_id) res_exists = results.rowcount > 0 # if not res_exists: # raise p.toolkit.ObjectNotFound(p.toolkit._( # 'Resource "{0}" was not found.'.format(res_id) # )) # p.toolkit.check_access('datastore_delete', context, data_dict) result = db.delete(context, data_dict) if 'id' in result: result.pop('id') result.pop('connection_url') return result
def datastore_search(context, data_dict): '''Search a datastore table. The datastore_search action allows a user to search data in a resource. :param resource_id: id or alias of the resource to be searched against. :type resource_id: string :param filters: matching conditions to select, e.g {"key1": "a", "key2": "b"} :type filters: dictionary :param q: full text query :type q: string :param plain: treat as plain text query (default: true) :type plain: bool :param language: language of the full text query (default: english) :type language: string :param limit: maximum number of rows to return (default: 100) :type limit: int :param offset: offset this number of rows :type offset: int :param fields: fields to return (default: all fields in original order) :type fields: list or comma separated string :param sort: comma separated field names with ordering e.g.: "fieldname1, fieldname2 desc" :type sort: string **Results:** The result of this action is a dict with the following keys: :rtype: A dictionary with the following keys :param fields: fields/columns and their extra metadata :type fields: list of dictionaries :param offset: query offset value :type offset: int :param limit: query limit value :type limit: int :param filters: query filters :type filters: list of dictionaries :param total: number of total matching records :type total: int :param records: list of matching results :type records: list of dictionaries ''' # res_id = _get_or_bust(data_dict, 'resource_id') res_id = data_dict['resource_id'] # data_dict['connection_url'] = pylons.config.get('ckan.datastore.read_url', # pylons.config['ckan.datastore.write_url']) resources_sql = sqlalchemy.text( u'SELECT 1 FROM "_table_metadata" WHERE name = :id') results = db._get_engine(None, data_dict).execute(resources_sql, id=res_id) res_exists = results.rowcount > 0 # if not res_exists: # raise p.toolkit.ObjectNotFound(p.toolkit._( # 'Resource "{0}" was not found.'.format(res_id) # )) # p.toolkit.check_access('datastore_search', context, data_dict) result = db.search(context, data_dict) result.pop('id', None) result.pop('connection_url') return result