def execute(self, q, args=()): """ Send a query to the Salesforce API. """ from salesforce.backend import base self.rowcount = None if isinstance(self.query, SalesforceQuery) or self.query is None: response = self.execute_select(q, args) #print("response : %s" % response.text) elif isinstance(self.query, SalesforceRawQuery): response = self.execute_select(q, args) elif isinstance(self.query, subqueries.InsertQuery): response = self.execute_insert(self.query) elif isinstance(self.query, subqueries.UpdateQuery): response = self.execute_update(self.query) elif isinstance(self.query, subqueries.DeleteQuery): response = self.execute_delete(self.query) else: raise base.DatabaseError("Unsupported query: type %s: %s" % (type(self.query), self.query)) # the encoding is detected automatically, e.g. from headers if (response and response.text): # parse_float set to decimal.Decimal to avoid precision errors when # converting from the json number to a float to a Decimal object # on a model's DecimalField...converts from json number directly # a Decimal object data = response.json(parse_float=decimal.Decimal) # a SELECT query if ('totalSize' in data): self.rowcount = data['totalSize'] # a successful INSERT query, return after getting PK elif ('success' in data and 'id' in data): self.lastrowid = data['id'] return # something we don't recognize else: raise base.DatabaseError(data) if q.upper().startswith('SELECT COUNT() FROM'): # COUNT() queries in SOQL are a special case, as they don't actually return rows self.results = iter([[self.rowcount]]) else: if self.query: self.query.first_chunk_len = len(data['records']) self.first_row = data['records'][0] if data['records'] else None self.results = self.query_results(data) else: self.results = iter([])
def prep_for_deserialize(model, record, using, init_list=None): """ Convert a record from SFDC (decoded JSON) to dict(model string, pk, fields) If fixes fields of some types. If names of required fields `init_list `are specified, then only these fields are processed. """ from salesforce.backend import base # TODO the parameter 'using' is not currently important. attribs = record.pop('attributes') mod = model.__module__.split('.') if (mod[-1] == 'models'): app_label = mod[-2] elif (hasattr(model._meta, 'app_label')): app_label = getattr(model._meta, 'app_label') else: raise ImproperlyConfigured( "Can't discover the app_label for %s, you must specify it via model meta options." ) if len(record.keys()) == 1 and model._meta.db_table in record: while len(record) == 1: record = list(record.values())[0] fields = dict() for x in model._meta.fields: if not x.primary_key and (not init_list or x.name in init_list): if x.column.endswith('.Type'): # Type of generic foreign key simple_column, _ = x.column.split('.') fields[x.name] = record[simple_column]['Type'] else: # Normal fields field_val = record[x.column] #db_type = x.db_type(connection=connections[using]) if (x.__class__.__name__ == 'DateTimeField' and field_val is not None): d = datetime.datetime.strptime(field_val, SALESFORCE_DATETIME_FORMAT) import pytz d = d.replace(tzinfo=pytz.utc) if settings.USE_TZ: fields[x.name] = d.strftime(DJANGO_DATETIME_FORMAT) else: tz = pytz.timezone(settings.TIME_ZONE) d = tz.normalize(d.astimezone(tz)) fields[x.name] = d.strftime( DJANGO_DATETIME_FORMAT[:-6]) else: fields[x.name] = field_val if init_list and set(init_list).difference(fields).difference([SF_PK]): raise base.DatabaseError("Not found some expected fields") return dict( model='.'.join([app_label, model.__name__]), pk=record.pop('Id'), fields=fields, )
def execute(self, q, args=None): """ Send a query to the Salesforce API. """ from salesforce.backend import base self.rowcount = None if (isinstance(self.query, SalesforceQuery)): response = self.execute_select(q, args) elif (isinstance(self.query, SalesforceRawQuery)): response = self.execute_select(q, args) elif (isinstance(self.query, subqueries.InsertQuery)): response = self.execute_insert(self.query) elif (isinstance(self.query, subqueries.UpdateQuery)): response = self.execute_update(self.query) elif (isinstance(self.query, subqueries.DeleteQuery)): response = self.execute_delete(self.query) else: raise base.DatabaseError("Unsupported query: %s" % self.query) body = response.body_string() jsrc = force_unicode(body).encode(settings.DEFAULT_CHARSET) if (jsrc): data = json.loads(jsrc) # a SELECT query if ('totalSize' in data): self.rowcount = data['totalSize'] # a successful INSERT query, return after getting PK elif ('success' in data and 'id' in data): self.lastrowid = data['id'] return # something we don't recognize else: raise base.DatabaseError(data) if ('count()' in q.lower()): # COUNT() queries in SOQL are a special case, as they don't actually return rows data['records'] = [{self.rowcount: 'COUNT'}] self.results = self.query_results(data) else: self.results = []