def get_queryset(self, _alias=None): """ Returns a QuerySet which access remote SF objects. """ alias_is_sf = _alias and router.is_sf_database(_alias) extended_model = getattr(self.model, '_salesforce_object', '') == 'extended' if router.is_sf_database(self.db) or alias_is_sf or extended_model: q = models_sql_query.SalesforceQuery(self.model, where=compiler.SalesforceWhereNode) return query.SalesforceQuerySet(self.model, query=q, using=self.db) return super(SalesforceManager, self).get_queryset()
def get_queryset(self, _alias: Optional[str] = None) -> 'QuerySet[_T]': """ Returns a QuerySet which access remote SF objects. """ alias_is_sf = _alias and router.is_sf_database(_alias) is_extended_model = getattr(self.model, '_salesforce_object', '') == 'extended' assert self.model is not None if router.is_sf_database(self.db) or alias_is_sf or is_extended_model: return query.SalesforceQuerySet(self.model, using=self.db) return super(SalesforceManager, self).get_queryset()
def bulk_update_small(objs: 'typing.Collection[models.Model]', fields: Iterable[str], all_or_none: bool = None) -> None: # simple implementation without "batch_size" parameter, but with "all_or_none" # and objects from mixed models can be updated by one request in the same transaction assert len(objs) <= 200 records = [] dbs = set() for item in objs: query = django.db.models.sql.subqueries.UpdateQuery( item._meta.model) # fake query query.add_update_values( {field: getattr(item, field) for field in fields}) values = salesforce.backend.utils.extract_values(query) values['id'] = item.pk values['type_'] = item._meta.db_table records.append(values) dbs.add(item._state.db) db = dbs.pop() if dbs or not is_sf_database(db): raise ValueError( "All updated objects must be from the same Salesforce database.") connection = django.db.connections[db].connection connection.sobject_collections_request('PATCH', records, all_or_none=all_or_none)
def raw(self, raw_query, params=None, *args, **kwargs): if router.is_sf_database(self.db): from salesforce.backend import query q = query.SalesforceRawQuery(raw_query, self.db, params) return query.SalesforceRawQuerySet(raw_query=raw_query, model=self.model, query=q, params=params, using=self.db) else: return super(SalesforceManager, self).raw(raw_query, params, *args, **kwargs)
def _do_insert(self, manager, using, fields, returning_fields, raw): # the check "is_sf_database(using)" is used for something unexpected if self.pk and not is_sf_database(using): returning_fields = [] return super(SalesforceModel, self)._do_insert(manager, using, fields, returning_fields, raw)
def save(self, force_insert=False, force_update=False, using=None, update_fields=None): using = using or router.db_for_write(self.__class__, instance=self) if self.pk is None and not force_update and not is_sf_database(using): self.pk = get_sf_alt_pk() super(SalesforceModel, self).save(force_insert=force_insert, force_update=force_update, using=using, update_fields=update_fields) if not isinstance(self.pk, str): raise ValueError("The primary key value is not assigned correctly")
def get_queryset(self): """ Returns a QuerySet which access remote SF objects. """ if router.is_sf_database(self.db): q = models_sql_query.SalesforceQuery(self.model, where=compiler.SalesforceWhereNode) return query.SalesforceQuerySet(self.model, query=q, using=self.db) return super(SalesforceManager, self).get_queryset()
def using(self, alias): if alias is None: if getattr(self.model, '_salesforce_object', False): alias = getattr(settings, 'SALESFORCE_DB_ALIAS', 'salesforce') else: alias = DEFAULT_DB_ALIAS if router.is_sf_database(alias, self.model): return self.get_queryset().using(alias) return super(SalesforceManager, self).using(alias)
def get_queryset(self): """ Returns a QuerySet which access remote SF objects. """ if not router.is_sf_database(self.db): return super(SalesforceManager, self).get_queryset() else: from salesforce.backend import query, compiler q = query.SalesforceQuery(self.model, where=compiler.SalesforceWhereNode) return query.SalesforceQuerySet(self.model, query=q, using=self.db)
def bulk_create(self, objs, batch_size=None, ignore_conflicts=False, **kwargs): # pylint:disable=arguments-differ,unused-argument # parameter 'ignore_conflicts=False' is new in Django 2.2 if getattr(self.model, '_salesforce_object', '') == 'extended' and not is_sf_database(self.db): objs = list(objs) for x in objs: if x.pk is None: x.pk = get_sf_alt_pk() return super(SalesforceQuerySet, self).bulk_create(objs, batch_size=batch_size, **kwargs)
def bulk_create(self, objs: Iterable[_T], batch_size: Optional[int] = None, ignore_conflicts: bool = False) -> List[_T]: # parameter 'ignore_conflicts=False' is new in Django 2.2 kwargs = { 'ignore_conflicts': ignore_conflicts } if DJANGO_22_PLUS else {} if getattr(self.model, '_salesforce_object', '') == 'extended' and not is_sf_database(self.db): objs = list(objs) for x in objs: if x.pk is None: x.pk = get_sf_alt_pk() return super(SalesforceQuerySet, self).bulk_create(objs, batch_size=batch_size, **kwargs)
def sf( self, query_all: Optional[bool] = None, all_or_none: Optional[bool] = None, edge_updates: Optional[bool] = None, ) -> 'SalesforceQuerySet[_T]': """Set additional parameters for queryset methods with Salesforce. see details about these parameters in `salesforce.backend.models_sql_query.SalesforceQuery.sf(...)` It is better to put this method near the beginning of the chain of queryset methods. Example: >>> Contact.objects.sf(all_or_none=True).bulk_create([Contact(last_name='a')]) """ if not is_sf_database(self.db): return self clone = self._chain() clone.query = clone.query.sf( query_all=query_all, all_or_none=all_or_none, edge_updates=edge_updates, ) return clone
""" Common helpers for tests, like test decorators """ import sys import uuid from unittest import skip, skipUnless, expectedFailure, TestCase # NOQA pylint:disable=unused-import import django from django.conf import settings from salesforce import router from salesforce.dbapi.test_helpers import ( # NOQA pylint:disable=unused-import LazyTestMixin, expectedFailureIf, QuietSalesforceErrors) # uid strings for tests that accidentally run concurrent uid_random = '-' + str(uuid.uuid4())[:7] # this is the same as the name of tox test environment, e.g. 'py35-dj110' uid_version = 'py{0}{1}-dj{2}{3}'.format(*(sys.version_info[:2] + django.VERSION[:2])) sf_alias = getattr(settings, 'SALESFORCE_DB_ALIAS', 'salesforce') default_is_sf = router.is_sf_database(sf_alias) current_user = settings.DATABASES[sf_alias]['USER']
def query_all(self): if router.is_sf_database(self.db): return self.get_queryset().query_all() else: return self.get_queryset()
from salesforce.testrunner.example.models import ( Account, Contact, Lead, User, BusinessHours, ChargentOrder, CronTrigger, Opportunity, OpportunityContactRole, Product, Pricebook, PricebookEntry, Note, Task, WITH_CONDITIONAL_MODELS) from salesforce import router, DJANGO_15_PLUS, DJANGO_17_PLUS, DJANGO_18_PLUS import salesforce from ..backend.test_helpers import skip, skipUnless, expectedFailure, expectedFailureIf # test decorators from ..backend.test_helpers import current_user, default_is_sf, sf_alias, uid import logging log = logging.getLogger(__name__) QUIET_DJANGO_18 = DJANGO_18_PLUS and strtobool( os.getenv('QUIET_DJANGO_18', 'false')) test_email = '*****@*****.**' % uid sf_databases = [db for db in connections if router.is_sf_database(db)] _sf_tables = [] def sf_tables(): if not _sf_tables and default_is_sf: for x in connections[sf_alias].introspection.table_list_cache[ 'sobjects']: _sf_tables.append(x['name']) return _sf_tables def refresh(obj): """Get the same object refreshed from the same db. """
Note, test_custom_db_table, test_custom_db_column) from salesforce import router, DJANGO_15_PLUS from salesforce.backend import sf_alias import salesforce import logging log = logging.getLogger(__name__) random_slug = ''.join( random.choice(string.ascii_uppercase + string.ascii_lowercase + string.digits) for x in range(32)) sf_alias = getattr(settings, 'SALESFORCE_DB_ALIAS', 'salesforce') current_user = settings.DATABASES[sf_alias]['USER'] test_email = '*****@*****.**' % random_slug sf_tables = [] if router.is_sf_database(sf_alias): sf_tables = [ x['name'] for x in connections[sf_alias].introspection.table_list_cache['sobjects'] ] sf_databases = [db for db in connections if router.is_sf_database(db)] default_is_sf = router.is_sf_database(sf_alias) def refresh(obj): """ Get the same object refreshed from the same db. """ db = obj._state.db return type(obj).objects.using(db).get(pk=obj.pk)
BusinessHours, ChargentOrder, CronTrigger, TestCustomExample, Product, Pricebook, PricebookEntry, GeneralCustomModel, Note, test_custom_db_table, test_custom_db_column) from salesforce import router, DJANGO_15_PLUS from salesforce.backend import sf_alias import salesforce import logging log = logging.getLogger(__name__) random_slug = ''.join(random.choice(string.ascii_uppercase + string.ascii_lowercase + string.digits) for x in range(32)) sf_alias = getattr(settings, 'SALESFORCE_DB_ALIAS', 'salesforce') current_user = settings.DATABASES[sf_alias]['USER'] test_email = '*****@*****.**' % random_slug sf_tables = [] if router.is_sf_database(sf_alias): sf_tables = [x['name'] for x in connections[sf_alias].introspection.table_list_cache['sobjects']] sf_databases = [db for db in connections if router.is_sf_database(db)] default_is_sf = router.is_sf_database(sf_alias) def refresh(obj): """ Get the same object refreshed from the same db. """ db = obj._state.db return type(obj).objects.using(db).get(pk=obj.pk) class BasicSOQLTest(TestCase): def setUp(self):
""" Common helpers for tests, like test decorators """ import sys import uuid from unittest import skip, skipUnless, expectedFailure, TestCase # NOQA pylint:disable=unused-import import django from django.conf import settings from salesforce import router from salesforce.dbapi.test_helpers import ( # NOQA pylint:disable=unused-import LazyTestMixin, expectedFailureIf, QuietSalesforceErrors) # uid strings for tests that accidentally run concurrent uid_random = '-' + str(uuid.uuid4())[:7] # this is the same as the name of tox test environment, e.g. 'py38-dj30' uid_version = 'py{0}{1}-dj{2}{3}'.format(*(sys.version_info[:2] + django.VERSION[:2])) sf_alias = getattr(settings, 'SALESFORCE_DB_ALIAS', 'salesforce') default_is_sf = router.is_sf_database(sf_alias) current_user = settings.DATABASES[sf_alias]['USER']
from salesforce.testrunner.example.models import (Account, Contact, Lead, User, BusinessHours, ChargentOrder, CronTrigger, Opportunity, OpportunityContactRole, Product, Pricebook, PricebookEntry, Note, Task) from salesforce import router, DJANGO_18_PLUS import salesforce from ..backend.test_helpers import skip, skipUnless, expectedFailure, expectedFailureIf # test decorators from ..backend.test_helpers import current_user, default_is_sf, sf_alias, uid import logging log = logging.getLogger(__name__) QUIET_DJANGO_18 = DJANGO_18_PLUS and strtobool(os.getenv('QUIET_DJANGO_18', 'false')) test_email = '*****@*****.**' % uid sf_databases = [db for db in connections if router.is_sf_database(db)] _sf_tables = [] def sf_tables(): if not _sf_tables and default_is_sf: for x in connections[sf_alias].introspection.table_list_cache['sobjects']: _sf_tables.append(x['name']) return _sf_tables def refresh(obj): """Get the same object refreshed from the same db. """ db = obj._state.db return type(obj).objects.using(db).get(pk=obj.pk)
def using(self, alias): if router.is_sf_database(alias): return self.get_queryset().using(alias) else: return super(SalesforceManager, self).using(alias)