migration scripts for adding new tables and fields.

modified:   make_post_sell/models/__init__.py
	modified:   make_post_sell/models/inventory.py
	modified:   make_post_sell/models/meta.py
	modified:   make_post_sell/models/product.py
	modified:   make_post_sell/models/shop.py
	modified:   make_post_sell/models/shop_location.py
	new file:   make_post_sell/scripts/alembic/versions/cc6211ec360e_physical_products_shop_locations_and_.py
This commit is contained in:
Russell Ballestrini 2024-06-08 10:14:51 -04:00
parent 9dd56e0898
commit 8af327bed1
7 changed files with 82 additions and 11 deletions

View file

@ -7,6 +7,7 @@ import zope.sqlalchemy
# Base.metadata prior to any initialization routines.
from .product import *
from .shop import *
from .shop_location import *
from .user import *
from .user_shop import *
from .user_product import *
@ -18,6 +19,7 @@ from .market import *
from .coupon import *
from .coupon_redemption import *
from .invoice import *
from .inventory import *
from .stripe_user_shop import *

View file

@ -13,8 +13,8 @@ class Inventory(RBase, Base):
created_timestamp = Column(BigInteger, nullable=False)
updated_timestamp = Column(BigInteger, nullable=False)
shop_location = relationship("ShopLocation", backref=backref("inventories", cascade="all, delete-orphan"))
product = relationship("Product", backref=backref("inventories", cascade="all, delete-orphan"))
shop_location = relationship("ShopLocation", uselist=False)
product = relationship("Product", uselist=False)
def __init__(self, shop_location, product, quantity=0):
if not product.is_physical:

View file

@ -16,7 +16,6 @@ UUIDType = TempUUIDType(binary=False)
CLASS_TO_TABLE = {
"Address": "mps_address",
"Shop": "mps_shop",
"ShopLocation": "mps_shop_location",
"Inventory": "mps_inventory",

View file

@ -104,6 +104,12 @@ class Product(RBase, Base):
# this value should be treated as immutable after object creation.
is_sellable = Column(Boolean, default=False, nullable=False)
# this value should be treated as immutable after object creation.
is_physical = Column(Boolean, default=False, nullable=False)
# Add relationship to inventories
inventories = relationship("Inventory", lazy="dynamic", back_populates="product")
# lazy="joined" performs a left join to reduce queries, it's magic.
# set uselist=False creates one-to-one relationship.
shop = relationship(argument="Shop", uselist=False, lazy="joined")
@ -121,13 +127,6 @@ class Product(RBase, Base):
"product_users", "user", creator=lambda u: UserProduct(user=u)
)
"""
_users = relationship(UserProduct, order_by=[UserProduct.created_timestamp.desc()])
users = association_proxy(
"_users", "user", creator=lambda u: UserProduct(user=u)
)
"""
file_keys = [
"product",
"preview",
@ -241,6 +240,12 @@ class Product(RBase, Base):
"""return slug from title"""
return slugify(self.title)
@property
def total_inventory_quantity(self):
if not self.is_physical:
return None
return sum(inventory.quantity for inventory in self.inventories)
@property
def s3_path(self):
"""return the S3 path shop.id/product.id"""

View file

@ -99,6 +99,10 @@ class Shop(RBase, Base):
order_by="desc(Coupon.created_timestamp)",
)
# lazy='dynamic' returns a query object instead of collection.
# Reference: http://docs.sqlalchemy.org/en/latest/orm/collections.html
shop_locations = relationship(argument="ShopLocation", lazy="dynamic", back_populates="shop")
# lazy='dynamic' returns a query object instead of collection.
# Reference: http://docs.sqlalchemy.org/en/latest/orm/collections.html
search_requests = relationship(

View file

@ -16,7 +16,7 @@ class ShopLocation(RBase, Base):
postal_code = Column(Unicode(16), nullable=False)
created_timestamp = Column(BigInteger, nullable=False)
shop = relationship("Shop", backref=backref("shop_locations", cascade="all, delete-orphan"))
shop = relationship("Shop", uselist=False)
def __init__(self, shop, name, address, city, state, country, postal_code):
self.id = uuid.uuid1()

View file

@ -0,0 +1,61 @@
"""physical products shop_locations and inventory
Revision ID: cc6211ec360e
Revises: 7217f39a20a8
Create Date: 2024-06-08 09:40:24.200194
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = 'cc6211ec360e'
down_revision = '7217f39a20a8'
branch_labels = None
depends_on = None
from make_post_sell.models.meta import UUIDType
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('mps_shop_location',
sa.Column('id', UUIDType, nullable=False),
sa.Column('shop_id', UUIDType, nullable=False),
sa.Column('name', sa.Unicode(length=64), nullable=False),
sa.Column('address', sa.Unicode(length=256), nullable=False),
sa.Column('city', sa.Unicode(length=64), nullable=False),
sa.Column('state', sa.Unicode(length=64), nullable=False),
sa.Column('country', sa.Unicode(length=64), nullable=False),
sa.Column('postal_code', sa.Unicode(length=16), nullable=False),
sa.Column('created_timestamp', sa.BigInteger(), nullable=False),
sa.ForeignKeyConstraint(['shop_id'], ['mps_shop.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_mps_shop_location_id'), 'mps_shop_location', ['id'], unique=False)
op.create_table('mps_inventory',
sa.Column('id', UUIDType, nullable=False),
sa.Column('shop_location_id', UUIDType, nullable=False),
sa.Column('product_id', UUIDType, nullable=False),
sa.Column('quantity', sa.Integer(), nullable=False),
sa.Column('created_timestamp', sa.BigInteger(), nullable=False),
sa.Column('updated_timestamp', sa.BigInteger(), nullable=False),
sa.ForeignKeyConstraint(['product_id'], ['mps_product.id'], ),
sa.ForeignKeyConstraint(['shop_location_id'], ['mps_shop_location.id'], ),
sa.PrimaryKeyConstraint('id')
)
op.create_index(op.f('ix_mps_inventory_id'), 'mps_inventory', ['id'], unique=False)
op.add_column('mps_product', sa.Column('is_physical', sa.Boolean(), nullable=False, server_default=sa.false()))
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column('mps_product', 'is_physical')
op.drop_index(op.f('ix_mps_inventory_id'), table_name='mps_inventory')
op.drop_table('mps_inventory')
op.drop_index(op.f('ix_mps_shop_location_id'), table_name='mps_shop_location')
op.drop_table('mps_shop_location')
# ### end Alembic commands ###