feat: ozon sync
This commit is contained in:
		
							
								
								
									
										40
									
								
								external/marketplace/base/product_synchronizer.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								external/marketplace/base/product_synchronizer.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
				
			|||||||
 | 
					from abc import ABC, abstractmethod
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from sqlalchemy.ext.asyncio import AsyncSession
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from external.marketplace.base import BaseMarketplaceApi
 | 
				
			||||||
 | 
					from models import Product, ProductBarcode, ProductImage
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class BaseProductSynchronizer(ABC):
 | 
				
			||||||
 | 
					    products: list[Product] = []
 | 
				
			||||||
 | 
					    barcodes: list[ProductBarcode] = []
 | 
				
			||||||
 | 
					    images: list[ProductImage] = []
 | 
				
			||||||
 | 
					    marketplace_products: list = []
 | 
				
			||||||
 | 
					    api: BaseMarketplaceApi
 | 
				
			||||||
 | 
					    session: AsyncSession
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, session, marketplace, api):
 | 
				
			||||||
 | 
					        self.session = session
 | 
				
			||||||
 | 
					        self.marketplace = marketplace
 | 
				
			||||||
 | 
					        self.api = api
 | 
				
			||||||
 | 
					        self._clear()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _clear(self):
 | 
				
			||||||
 | 
					        self.products = []
 | 
				
			||||||
 | 
					        self.barcodes = []
 | 
				
			||||||
 | 
					        self.images = []
 | 
				
			||||||
 | 
					        self.marketplace_products = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async def _write(self):
 | 
				
			||||||
 | 
					        instances = self.products + self.marketplace_products + self.barcodes + self.images
 | 
				
			||||||
 | 
					        self.session.add_all(instances)
 | 
				
			||||||
 | 
					        await self.session.commit()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @abstractmethod
 | 
				
			||||||
 | 
					    async def create_products(self):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @abstractmethod
 | 
				
			||||||
 | 
					    async def synchronize_products(self):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
							
								
								
									
										52
									
								
								external/marketplace/ozon/core.py
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										52
									
								
								external/marketplace/ozon/core.py
									
									
									
									
										vendored
									
									
								
							@@ -1,15 +1,61 @@
 | 
				
			|||||||
 | 
					from typing import AsyncIterator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from external.marketplace.base.core import BaseMarketplaceApi
 | 
					from external.marketplace.base.core import BaseMarketplaceApi
 | 
				
			||||||
from models import Marketplace
 | 
					from models import Marketplace
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class OzonMarketplaceApi(BaseMarketplaceApi):
 | 
					class OzonMarketplaceApi(BaseMarketplaceApi):
 | 
				
			||||||
    def __init__(self, marketplace: Marketplace):
 | 
					    def __init__(self, marketplace: Marketplace):
 | 
				
			||||||
        pass
 | 
					        client_id = marketplace.auth_data.get('Client-Id')
 | 
				
			||||||
 | 
					        api_key = marketplace.auth_data.get('Api-Key')
 | 
				
			||||||
 | 
					        if not client_id or not api_key:
 | 
				
			||||||
 | 
					            raise ValueError(
 | 
				
			||||||
 | 
					                f"Client-Id or Api-Key is missing for Marketplace ID: {marketplace.id}. "
 | 
				
			||||||
 | 
					                "Please check the marketplace credentials."
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					        self.headers = marketplace.auth_data
 | 
				
			||||||
 | 
					        self.marketplace = marketplace
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def get_headers(self) -> dict:
 | 
					    def get_headers(self) -> dict:
 | 
				
			||||||
        return {}
 | 
					        return self.headers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def base_url(self) -> str:
 | 
					    def base_url(self) -> str:
 | 
				
			||||||
        return ""
 | 
					        return "https://api-seller.ozon.ru"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async def get_products(self, data: dict) -> dict:
 | 
				
			||||||
 | 
					        method = '/v2/product/list'
 | 
				
			||||||
 | 
					        response = await  self._method('POST', method, json=data)
 | 
				
			||||||
 | 
					        return response
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async def get_all_products(self) -> AsyncIterator[dict]:
 | 
				
			||||||
 | 
					        limit = 100
 | 
				
			||||||
 | 
					        last_id = ''
 | 
				
			||||||
 | 
					        while True:
 | 
				
			||||||
 | 
					            data = {
 | 
				
			||||||
 | 
					                'limit': limit,
 | 
				
			||||||
 | 
					                'last_id': last_id,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            response = await self.get_products(data)
 | 
				
			||||||
 | 
					            if not response:
 | 
				
			||||||
 | 
					                break
 | 
				
			||||||
 | 
					            result = response.get('result')
 | 
				
			||||||
 | 
					            if not result:
 | 
				
			||||||
 | 
					                break
 | 
				
			||||||
 | 
					            items = result.get('items')
 | 
				
			||||||
 | 
					            if not items:
 | 
				
			||||||
 | 
					                break
 | 
				
			||||||
 | 
					            for item in items:
 | 
				
			||||||
 | 
					                yield item
 | 
				
			||||||
 | 
					            last_id = result.get('last_id')
 | 
				
			||||||
 | 
					            if not last_id:
 | 
				
			||||||
 | 
					                break
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async def get_products_info(self, data: dict) -> dict:
 | 
				
			||||||
 | 
					        method = '/v2/product/info/list'
 | 
				
			||||||
 | 
					        response = await self._method('POST', method, json=data)
 | 
				
			||||||
 | 
					        return response
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
@@ -1,6 +1,190 @@
 | 
				
			|||||||
 | 
					from collections import defaultdict
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from sqlalchemy import select
 | 
				
			||||||
 | 
					from sqlalchemy.orm import selectinload
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from external.marketplace import OzonMarketplaceApi
 | 
				
			||||||
 | 
					from external.marketplace.base.product_synchronizer import BaseProductSynchronizer
 | 
				
			||||||
from marketplaces.base.core import BaseMarketplaceController
 | 
					from marketplaces.base.core import BaseMarketplaceController
 | 
				
			||||||
 | 
					from models import OzonProduct, ProductImage, ProductBarcode, Product
 | 
				
			||||||
 | 
					from utils.list_utils import chunk_list
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class OzonProductSynchronizer(BaseProductSynchronizer):
 | 
				
			||||||
 | 
					    api: OzonMarketplaceApi
 | 
				
			||||||
 | 
					    marketplace_products: list[OzonProduct]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _create_product(self, product_info):
 | 
				
			||||||
 | 
					        return Product(
 | 
				
			||||||
 | 
					            client_id=self.marketplace.client_id,
 | 
				
			||||||
 | 
					            name=product_info['name'],
 | 
				
			||||||
 | 
					            article=product_info['offer_id'],
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _create_barcodes(self, product, param):
 | 
				
			||||||
 | 
					        barcodes = []
 | 
				
			||||||
 | 
					        for sku in param:
 | 
				
			||||||
 | 
					            barcode = ProductBarcode(
 | 
				
			||||||
 | 
					                product=product,
 | 
				
			||||||
 | 
					                barcode=sku
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					            barcodes.append(barcode)
 | 
				
			||||||
 | 
					        return barcodes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _create_images(self, product, product_info):
 | 
				
			||||||
 | 
					        primary_image = product_info.get('primary_image')
 | 
				
			||||||
 | 
					        if primary_image:
 | 
				
			||||||
 | 
					            image = ProductImage(
 | 
				
			||||||
 | 
					                product=product,
 | 
				
			||||||
 | 
					                image_url=primary_image
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					            return [image]
 | 
				
			||||||
 | 
					        product_images = []
 | 
				
			||||||
 | 
					        images = product_info.get('images') or []
 | 
				
			||||||
 | 
					        for image in images[:1]:
 | 
				
			||||||
 | 
					            product_image = ProductImage(
 | 
				
			||||||
 | 
					                product=product,
 | 
				
			||||||
 | 
					                image_url=image
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					            product_images.append(product_image)
 | 
				
			||||||
 | 
					        return product_images
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _create_ozon_product(self, product, product_info):
 | 
				
			||||||
 | 
					        return OzonProduct(
 | 
				
			||||||
 | 
					            marketplace_id=self.marketplace.id,
 | 
				
			||||||
 | 
					            product=product,
 | 
				
			||||||
 | 
					            ozon_product_id=product_info['id'],
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _process_product(self, product_info):
 | 
				
			||||||
 | 
					        product = self._create_product(product_info)
 | 
				
			||||||
 | 
					        barcodes = self._create_barcodes(product, product_info['barcodes'])
 | 
				
			||||||
 | 
					        images = self._create_images(product, product_info)
 | 
				
			||||||
 | 
					        ozon_product = self._create_ozon_product(product, product_info)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.products.append(product)
 | 
				
			||||||
 | 
					        self.barcodes.extend(barcodes)
 | 
				
			||||||
 | 
					        self.images.extend(images)
 | 
				
			||||||
 | 
					        self.marketplace_products.append(ozon_product)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async def create_products(self):
 | 
				
			||||||
 | 
					        self._clear()
 | 
				
			||||||
 | 
					        product_ids = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        async for product in self.api.get_all_products():
 | 
				
			||||||
 | 
					            product_ids.append(product['product_id'])
 | 
				
			||||||
 | 
					            if len(product_ids) > 100:
 | 
				
			||||||
 | 
					                break
 | 
				
			||||||
 | 
					        max_products = 1000
 | 
				
			||||||
 | 
					        for chunk in chunk_list(product_ids, max_products):
 | 
				
			||||||
 | 
					            data = {
 | 
				
			||||||
 | 
					                'product_id': chunk
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            products_info = await self.api.get_products_info(data)
 | 
				
			||||||
 | 
					            if not products_info:
 | 
				
			||||||
 | 
					                continue
 | 
				
			||||||
 | 
					            result = products_info.get('result')
 | 
				
			||||||
 | 
					            if not result:
 | 
				
			||||||
 | 
					                continue
 | 
				
			||||||
 | 
					            items = result.get('items')
 | 
				
			||||||
 | 
					            for product_info in items:
 | 
				
			||||||
 | 
					                product = self._create_product(product_info)
 | 
				
			||||||
 | 
					                self.products.append(product)
 | 
				
			||||||
 | 
					                barcodes = self._create_barcodes(product, product_info['barcodes'])
 | 
				
			||||||
 | 
					                self.barcodes.extend(barcodes)
 | 
				
			||||||
 | 
					                images = self._create_images(product, product_info)
 | 
				
			||||||
 | 
					                self.images.extend(images)
 | 
				
			||||||
 | 
					                ozon_product = self._create_ozon_product(product, product_info)
 | 
				
			||||||
 | 
					                self.marketplace_products.append(ozon_product)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        await self._write()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async def synchronize_products(self):
 | 
				
			||||||
 | 
					        self._clear()
 | 
				
			||||||
 | 
					        synchronized_products_stmt = (
 | 
				
			||||||
 | 
					            select(
 | 
				
			||||||
 | 
					                Product
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					            .join(
 | 
				
			||||||
 | 
					                OzonProduct
 | 
				
			||||||
 | 
					            ).options(
 | 
				
			||||||
 | 
					                selectinload(Product.barcodes),
 | 
				
			||||||
 | 
					                selectinload(Product.ozon_products)
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					            .where(
 | 
				
			||||||
 | 
					                OzonProduct.marketplace_id == self.marketplace.id
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        synchronized_products = await self.session.execute(synchronized_products_stmt)
 | 
				
			||||||
 | 
					        synchronized_products = synchronized_products.scalars().all()
 | 
				
			||||||
 | 
					        synchronized_products_ozon_id_dict = defaultdict(list)
 | 
				
			||||||
 | 
					        for product in synchronized_products:
 | 
				
			||||||
 | 
					            for ozon_product in product.ozon_products:
 | 
				
			||||||
 | 
					                synchronized_products_ozon_id_dict[ozon_product.ozon_product_id].append(product)
 | 
				
			||||||
 | 
					        synchronized_ozon_ids = list(synchronized_products_ozon_id_dict.keys())
 | 
				
			||||||
 | 
					        max_products = 1000
 | 
				
			||||||
 | 
					        for chunk in chunk_list(synchronized_ozon_ids, max_products):
 | 
				
			||||||
 | 
					            data = {
 | 
				
			||||||
 | 
					                'product_id': chunk
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            products_info = await self.api.get_products_info(data)
 | 
				
			||||||
 | 
					            if not products_info:
 | 
				
			||||||
 | 
					                continue
 | 
				
			||||||
 | 
					            result = products_info.get('result')
 | 
				
			||||||
 | 
					            if not result:
 | 
				
			||||||
 | 
					                continue
 | 
				
			||||||
 | 
					            items = result.get('items')
 | 
				
			||||||
 | 
					            for product_info in items:
 | 
				
			||||||
 | 
					                ozon_id = product_info['id']
 | 
				
			||||||
 | 
					                if ozon_id not in synchronized_ozon_ids:
 | 
				
			||||||
 | 
					                    continue
 | 
				
			||||||
 | 
					                products = synchronized_products_ozon_id_dict.get(ozon_id)
 | 
				
			||||||
 | 
					                if not products:
 | 
				
			||||||
 | 
					                    continue
 | 
				
			||||||
 | 
					                product = products[0]
 | 
				
			||||||
 | 
					                await self._update_product_info(product, product_info)
 | 
				
			||||||
 | 
					        await self._write()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async def _update_product_info(self, product, product_info):
 | 
				
			||||||
 | 
					        product.name = product_info['name']
 | 
				
			||||||
 | 
					        product.article = product_info['offer_id']
 | 
				
			||||||
 | 
					        barcodes = self._update_barcodes(product, product_info['barcodes'])
 | 
				
			||||||
 | 
					        self.barcodes.extend(barcodes)
 | 
				
			||||||
 | 
					        images = self._update_images(product, product_info)
 | 
				
			||||||
 | 
					        self.images.extend(images)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _update_barcodes(self, product, param):
 | 
				
			||||||
 | 
					        existing_barcodes = {barcode.barcode for barcode in product.barcodes}
 | 
				
			||||||
 | 
					        barcodes = []
 | 
				
			||||||
 | 
					        for sku in param:
 | 
				
			||||||
 | 
					            if sku not in existing_barcodes:
 | 
				
			||||||
 | 
					                barcode = ProductBarcode(
 | 
				
			||||||
 | 
					                    product=product,
 | 
				
			||||||
 | 
					                    barcode=sku
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					                barcodes.append(barcode)
 | 
				
			||||||
 | 
					        return barcodes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _update_images(self, product, product_info):
 | 
				
			||||||
 | 
					        existing_images = {image.image_url for image in product.images}
 | 
				
			||||||
 | 
					        primary_image = product_info.get('primary_image')
 | 
				
			||||||
 | 
					        if primary_image and primary_image not in existing_images:
 | 
				
			||||||
 | 
					            image = ProductImage(
 | 
				
			||||||
 | 
					                product=product,
 | 
				
			||||||
 | 
					                image_url=primary_image
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					            return [image]
 | 
				
			||||||
 | 
					        return []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class OzonController(BaseMarketplaceController):
 | 
					class OzonController(BaseMarketplaceController):
 | 
				
			||||||
 | 
					    def __init__(self, session, marketplace):
 | 
				
			||||||
 | 
					        super().__init__(session, marketplace)
 | 
				
			||||||
 | 
					        self.product_synchronizer = OzonProductSynchronizer(session, marketplace, self.api)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async def synchronize_products(self):
 | 
				
			||||||
 | 
					        await self.product_synchronizer.synchronize_products()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def create_products(self):
 | 
					    async def create_products(self):
 | 
				
			||||||
        pass
 | 
					        await self.product_synchronizer.create_products()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,34 +4,18 @@ from collections import defaultdict
 | 
				
			|||||||
from sqlalchemy import select
 | 
					from sqlalchemy import select
 | 
				
			||||||
from sqlalchemy.orm import selectinload
 | 
					from sqlalchemy.orm import selectinload
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from external.marketplace.base.product_synchronizer import BaseProductSynchronizer
 | 
				
			||||||
from external.marketplace.wildberries.core import WildberriesMarketplaceApi
 | 
					from external.marketplace.wildberries.core import WildberriesMarketplaceApi
 | 
				
			||||||
from marketplaces.base.core import BaseMarketplaceController
 | 
					from marketplaces.base.core import BaseMarketplaceController
 | 
				
			||||||
from models import Product, ProductBarcode, ProductImage, WildberriesProduct
 | 
					from models import Product, ProductBarcode, ProductImage, WildberriesProduct
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class WildberriesProductSynchronizer:
 | 
					class WildberriesProductSynchronizer(BaseProductSynchronizer):
 | 
				
			||||||
    products: list[Product]
 | 
					    marketplace_products: list[WildberriesProduct]
 | 
				
			||||||
    barcodes: list[ProductBarcode]
 | 
					    api: WildberriesMarketplaceApi
 | 
				
			||||||
    images: list[ProductImage]
 | 
					 | 
				
			||||||
    wildberries_products: list[WildberriesProduct]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __init__(self, session, marketplace, api):
 | 
					 | 
				
			||||||
        self.session = session
 | 
					 | 
				
			||||||
        self.marketplace = marketplace
 | 
					 | 
				
			||||||
        self.api = api
 | 
					 | 
				
			||||||
        self.products = []
 | 
					 | 
				
			||||||
        self.barcodes = []
 | 
					 | 
				
			||||||
        self.images = []
 | 
					 | 
				
			||||||
        self.wildberries_products = []
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def _clear(self):
 | 
					 | 
				
			||||||
        self.products = []
 | 
					 | 
				
			||||||
        self.barcodes = []
 | 
					 | 
				
			||||||
        self.images = []
 | 
					 | 
				
			||||||
        self.wildberries_products = []
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def _write(self):
 | 
					    async def _write(self):
 | 
				
			||||||
        instances = self.products + self.wildberries_products + self.barcodes + self.images
 | 
					        instances = self.products + self.marketplace_products + self.barcodes + self.images
 | 
				
			||||||
        start = time.time()
 | 
					        start = time.time()
 | 
				
			||||||
        self.session.add_all(instances)
 | 
					        self.session.add_all(instances)
 | 
				
			||||||
        await self.session.commit()
 | 
					        await self.session.commit()
 | 
				
			||||||
@@ -125,7 +109,7 @@ class WildberriesProductSynchronizer:
 | 
				
			|||||||
        self.products.append(product)
 | 
					        self.products.append(product)
 | 
				
			||||||
        self.barcodes.extend(barcodes)
 | 
					        self.barcodes.extend(barcodes)
 | 
				
			||||||
        self.images.extend(images)
 | 
					        self.images.extend(images)
 | 
				
			||||||
        self.wildberries_products.append(wildberries_product)
 | 
					        self.marketplace_products.append(wildberries_product)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def create_products(self):
 | 
					    async def create_products(self):
 | 
				
			||||||
        self._clear()
 | 
					        self._clear()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,7 +27,7 @@ class OzonProduct(BaseModel):
 | 
				
			|||||||
    product_id: Mapped[int] = mapped_column(ForeignKey('products.id'), primary_key=True)
 | 
					    product_id: Mapped[int] = mapped_column(ForeignKey('products.id'), primary_key=True)
 | 
				
			||||||
    product: Mapped["Product"] = relationship()
 | 
					    product: Mapped["Product"] = relationship()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ozon_product_id: Mapped[int] = mapped_column(nullable=False)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class YandexProduct(BaseModel):
 | 
					class YandexProduct(BaseModel):
 | 
				
			||||||
    __tablename__ = 'yandex_products'
 | 
					    __tablename__ = 'yandex_products'
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -40,6 +40,11 @@ class Product(BaseModel):
 | 
				
			|||||||
                                        cascade="all, delete-orphan",
 | 
					                                        cascade="all, delete-orphan",
 | 
				
			||||||
                                        uselist=True)
 | 
					                                        uselist=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ozon_products = relationship('OzonProduct',
 | 
				
			||||||
 | 
					                                        back_populates='product',
 | 
				
			||||||
 | 
					                                        cascade="all, delete-orphan",
 | 
				
			||||||
 | 
					                                        uselist=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ProductImage(BaseModel):
 | 
					class ProductImage(BaseModel):
 | 
				
			||||||
    __tablename__ = 'product_images'
 | 
					    __tablename__ = 'product_images'
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										60
									
								
								test.py
									
									
									
									
									
								
							
							
						
						
									
										60
									
								
								test.py
									
									
									
									
									
								
							@@ -1,18 +1,54 @@
 | 
				
			|||||||
import asyncio
 | 
					# import asyncio
 | 
				
			||||||
import datetime
 | 
					#
 | 
				
			||||||
 | 
					# from dict_hash import dict_hash
 | 
				
			||||||
 | 
					# from sqlalchemy.ext.asyncio import AsyncSession
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# from backend.session import session_maker
 | 
				
			||||||
 | 
					# from marketplaces import MarketplaceControllerFactory
 | 
				
			||||||
 | 
					# from models import Marketplace
 | 
				
			||||||
 | 
					# import pickle
 | 
				
			||||||
 | 
					# pickle.dumps()
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# async def main():
 | 
				
			||||||
 | 
					#     a = "example"
 | 
				
			||||||
 | 
					#     b = "example"
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#     print(hash(a))  # Хэш для строки "example"
 | 
				
			||||||
 | 
					#     print(hash(b))  # Хэш для строки "example", будет таким же как и у a
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#     return
 | 
				
			||||||
 | 
					#     session: AsyncSession = session_maker()
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#     try:
 | 
				
			||||||
 | 
					#         mp = await  session.get(Marketplace, 2)
 | 
				
			||||||
 | 
					#         if not mp:
 | 
				
			||||||
 | 
					#             return
 | 
				
			||||||
 | 
					#         c = MarketplaceControllerFactory.get_controller(session, mp)
 | 
				
			||||||
 | 
					#         await c.synchronize_products()
 | 
				
			||||||
 | 
					#     finally:
 | 
				
			||||||
 | 
					#         await session.close()
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# if __name__ == '__main__':
 | 
				
			||||||
 | 
					#     loop = asyncio.get_event_loop()
 | 
				
			||||||
 | 
					#     loop.run_until_complete(main())
 | 
				
			||||||
 | 
					import hashlib
 | 
				
			||||||
 | 
					import time
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from sqlalchemy import select, func
 | 
					from reportlab.rl_settings import autoGenerateMissingTTFName
 | 
				
			||||||
from sqlalchemy.ext.asyncio import AsyncSession
 | 
					 | 
				
			||||||
from sqlalchemy.orm import joinedload
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
import models
 | 
					from decorators.locking import lock, redis_client
 | 
				
			||||||
from backend.session import session_maker
 | 
					 | 
				
			||||||
from models import User, PaymentRecord
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async def main():
 | 
					@lock('synchronize_marketplace', include_args_in_key=True)
 | 
				
			||||||
    pass
 | 
					def test(marketplace_id: int):
 | 
				
			||||||
 | 
					    print("test")
 | 
				
			||||||
 | 
					    time.sleep(100)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def main():
 | 
				
			||||||
 | 
					    test(1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if __name__ == '__main__':
 | 
					if __name__ == '__main__':
 | 
				
			||||||
    loop = asyncio.get_event_loop()
 | 
					    main()
 | 
				
			||||||
    loop.run_until_complete(main())
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										3
									
								
								utils/list_utils.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								utils/list_utils.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					def chunk_list(lst, n) -> list:
 | 
				
			||||||
 | 
					    for i in range(0, len(lst), n):
 | 
				
			||||||
 | 
					        yield lst[i:i + n]
 | 
				
			||||||
		Reference in New Issue
	
	Block a user