class azure_table: def __init__(self, table_name='HemoniDataTable'): connection_string = "**" self.table_client = TableService(connection_string=connection_string) self.table_name = table_name if self.table_client.exists(table_name): pass else: self.table_client.create_table(table_name=table_name) def delete_table(self): self.table_client.delete_table(table_name=self.table_name) def insert_entity(self, entity): """ When inserting an entity into a table, you must specify values for the PartitionKey and RowKey system properties. Together, these properties form the primary key and must be unique within the table. Both the PartitionKey and RowKey values must be string values; each key value may be up to 64 KB in size. If you are using an integer value for the key value, you should convert the integer to a fixed-width string, because they are canonically sorted. For example, you should convert the value 1 to 0000001 to ensure proper sorting. :param entity:The entity to insert. Could be a dict or an entity object. Must contain a PartitionKey and a RowKey. :return: null """ self.table_client.insert_or_replace_entity(table_name=self.table_name, entity=entity) def get_entity(self, partition, row): """ Get an entity from the specified table. Throws if the entity does not exist. :param partition: The PartitionKey of the entity. :param row: The RowKey of the entity. :return: """ return self.table_client.get_entity(self.table_name, partition_key=partition, row_key=row)
class ShoppingCartServiceCloud: """Shopping Cart Methods called from the API to interact with the DB.""" def __init__(self, shards=1): self.shards = shards self.table_name = "ShoppingCartTable" try: self.db = TableService( endpoint_suffix="table.cosmos.azure.com", connection_string=os.getenv("AZURE_COSMOS_CONNECTION_STRING"), ) except ValueError: raise Exception( "Please initialize $AZURE_COSMOS_CONNECTION_STRING") try: self.db.create_table(self.table_name, fail_on_exist=True) except AzureConflictHttpError: # Accept error only if already exists pass def get_product_items(self, customer_id): row_key = utils.hash_key(customer_id) partition_key = 'ShoppingCart' + str(row_key % self.shards).zfill(3) # Get Entity try: items = self.db.get_entity(self.table_name, partition_key, str(row_key)) product_items = json.loads(items.ProductItems) except AzureMissingResourceHttpError: product_items = [] return product_items def update_product_items(self, customer_id, product_items): row_key = utils.hash_key(customer_id) partition_key = 'ShoppingCart' + str(row_key % self.shards).zfill(3) product_items = [ item for item in product_items if item["unitCount"] > 0 ] # Insert or Update Items items = Entity() items.PartitionKey = partition_key items.RowKey = str(row_key) items.CustomerId = customer_id items.ProductItems = json.dumps(product_items) self.db.insert_or_replace_entity(self.table_name, items) def delete_shopping_cart(self, customer_id): row_key = utils.hash_key(customer_id) partition_key = 'ShoppingCart' + str(row_key % self.shards).zfill(3) # Get Items to Checkout before Delete try: items = self.db.get_entity(self.table_name, partition_key, str(row_key)) checkout_items = json.loads(items.ProductItems) except AzureMissingResourceHttpError: checkout_items = [] self.db.delete_entity(self.table_name, partition_key, str(row_key)) return checkout_items
class EventRepository: events_by_date_table = "eventsByDate" event_duplicates_table = "eventDuplicates" def __init__(self, connection_string=None): if not connection_string: connection_string = "AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;DefaultEndpointsProtocol=http;BlobEndpoint=http://127.0.0.1:10000/devstoreaccount1;QueueEndpoint=http://127.0.0.1:10001/devstoreaccount1;TableEndpoint=http://127.0.0.1:10002/devstoreaccount1;" self.table_client = TableService(connection_string=connection_string, is_emulated=True) def list_events_by_date(self, dt: datetime.date) -> List[dict]: pk = self._date_to_pk(dt) for event in self.table_client.query_entities( self.events_by_date_table, filter="PartitionKey eq '%s'" % (pk, )): if 'place' in event: event['place'] = json.loads(event['place']) if 'dates' in event: event['dates'] = json.loads(event['dates']) if 'raw_dates' in event: event['raw_dates'] = event['raw_dates'].split('\n') if 'tags' in event: event['tags'] = event['tags'].split(',') if 'type' in event: event['type'] = event['type'].split(',') if 'cost' in event: event['cost'] = event['cost'].split(',') yield event def remove_rows(self, dt, row_keys): pk = self._date_to_pk(dt) for key in row_keys: self.table_client.delete_entity(self.events_by_date_table, pk, key) def save_events_by_date(self, events: List[dict], dt: datetime.date, table_name=events_by_date_table): partition_keys = set() for event in events: if 'PartitionKey' not in event: if dt: event['PartitionKey'] = self._date_to_pk(dt) else: event['PartitionKey'] = str(datetime.date.today().year) if 'RowKey' not in event: full_text = event['title'] + "\n" + event[ 'short_description'] + "\n" + event['description'] event['RowKey'] = str(hash(full_text)) event['place'] = json.dumps(event['place'], ensure_ascii=False) event['dates'] = json.dumps(event['dates']) event['tags'] = ",".join(event['tags']) if 'type' in event: event['type'] = ",".join(event['type']) if "raw_dates" in event: event['raw_dates'] = "\n".join(event['raw_dates']) if 'cost' in event and event['cost']: event['cost'] = ",".join(str(c) for c in event['cost']) else: event['cost'] = None self.table_client.insert_or_replace_entity(table_name, event) partition_keys.add(event['PartitionKey']) for pk in partition_keys: self.table_client.insert_or_replace_entity(table_name, { "PartitionKey": "PARTITIONS", "RowKey": pk }) def save_events_json(self, events: List[dict]): grouped_events = group_by_dates(events) for dt, events in grouped_events.items(): self.save_events_by_date(events, dt) def save_verified_events(self, events: List[Event]): pk = datetime.datetime.now().timestamp() % 255 for event in events: event_description = event.to_str() event_hash = hash(event_description) self.table_client.insert_or_replace_entity( "verifiedEvents", { "PartitionKey": str(pk), "RowKey": str(event_hash), "Text": event_description, "Labels": ",".join(event.event_tags) }) @staticmethod def _date_to_pk(dt: datetime.date): return "%d_%d_%d" % (dt.year, dt.month, dt.day)