inventory manager, for flash sale inventory. by sqlalchemy and redis.
Project description
inventory_manager, for flash sale inventory. by sqlalchemy and redis.
0.0.9.dev0 is ok
pip3 install inventory_manager
使用方法如下
# InventoryManager 的原理如下,这个库,会利用 sqlalchemy 和 redis 来记录库存。
# 其中,sqlalchemy 会把设置库存操作记录到数据库的一个表中,然后数量同步记录到redis,
# 使用消费库存的时候,会在 redis 中执行 incr 或者 decr 操作,同时在数据库的另一个表中记录流水日志。
# 在 InventoryManager 中,会使用 python 动态创建 class 来实现 sqlalchemy 的 model class 定义和使用。
# 所以 InventoryManager 实例化的参数需要 sqlalchemy 的 db_session, Base,还需要 redis client。
# 考虑到实际使用场景,如果有多个 InventoryManager(), 那么他们的数据库表名字,redis 的 key,都需要用不同前缀隔开。
# 所以实例化的参数需要提供一个 prefix(要求 prefix 在业务中务必是 unique)
# demo 如下
# ========================================================================
import redis
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from inventory_manager import InventoryManager
# 创建必要的参数
# --------------------------------------------------
db_prefix = 'prefix'
# 这个 get_db_arg 是获取 sqlalchemy 的 db_session, Base,给 InventoryManager 参数用
def get_db_arg():
# 需要提前确认 database 已存在
db_config = 'mysql+pymysql://***:*****@127.0.0.1:3306/demo1?charset=utf8mb4'
echo = False
# echo = True
max_overflow = 1000
engine = create_engine(db_config, pool_size=40, max_overflow=max_overflow, pool_recycle=28000, pool_pre_ping=True, convert_unicode=True, echo=echo)
db_session = scoped_session(
sessionmaker(
autocommit=False,
autoflush=False,
bind=engine
)
)
Base = declarative_base()
Base.query = db_session.query_property()
Base.__table_args__ = {
'mysql_collate': 'utf8mb4_unicode_ci'
}
return db_session, Base
redis_host = '127.0.0.1'
redis_port = 6379
redis_db = 1
redis_password = ''
red = redis.StrictRedis(
host=redis_host,
port=redis_port,
password=redis_password,
db=redis_db,
decode_responses=True,
)
# red.flushdb()
db_session, db_Base = get_db_arg()
# 这个是例子,如 item_id='1'的初始库存10个,item_id='2'的初始库存20个,。。。。
map_sku_inventory = {
'1': 10,
'2': 20,
'3': 30,
}
# 以下是使用方法教程。
# ========================================================================
# ========================================================================
# ========================================================================
# ========================================================================
# 实例一个 InventoryManager,参数第一个代表字符串前缀,接着是前文的 sqlalchemy 变量,最后一个是 redis client
mgr = InventoryManager(db_prefix, db_session, db_Base, red)
# ping 一下 database 和 redis 通不通
mgr.ping()
# 这个会在 db 中创建对应的 table
mgr.create_table()
# 检查 db 中创建对应的 table 是否完成
mgr.table_initialized()
# 初始化设置库存最大数量
for item_id, num in map_sku_inventory.items():
mgr.inventory_init(item_id, num)
# 修改总库存量
mgr.modification_adjust(item_id='1', delta=100)
# 获取库存
r = mgr.get(item_id='1')
print('''r = mgr.get(item_id='1')''', r)
# 扣库存
success = mgr.usage_decr(item_id='1', num=1)
assert success
r = mgr.get(item_id='1')
print('''mgr.usage_decr(item_id='1', num=1)''', r)
# 扣库存
success = mgr.usage_decr(item_id='1', num=3)
assert success
r = mgr.get(item_id='1')
print('''mgr.usage_decr(item_id='1', num=3)''', r)
# 扣库存
success = mgr.usage_decr(item_id='1', num=999999999)
assert not success
r = mgr.get(item_id='1')
print('''failed, mgr.usage_decr(item_id='1', num=999999999)''', r)
# 退回库存
mgr.usage_incr(item_id='1', num=1000)
r = mgr.get(item_id='1')
print('''mgr.usage_incr(item_id='1', num=1000)''', r)
# redis 数据丢失或不一致的情况下,使用这个恢复 redis
r = mgr.refresh(item_id='1')
print('''r = mgr.refresh(item_id='1')''', r)
r = mgr.refresh_all()
'''
# todo
1. 幂等,幂等id
2. refresh() 没有加锁
done!!!! 3. def refresh_all()
4. 没测 flask_sqlalchemy 环境
5. 没测 sqlalchemy 2.x.x 兼容
6. table add column create_time
'''
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
No source distribution files available for this release.See tutorial on generating distribution archives.
Built Distribution
File details
Details for the file inventory_manager-0.0.9.dev0-py3-none-any.whl
.
File metadata
- Download URL: inventory_manager-0.0.9.dev0-py3-none-any.whl
- Upload date:
- Size: 10.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.9.13
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | d35b763b49657b2c36a59d5cfa7a76c89b4a1d5bc199e9ecd79a8edf2062a089 |
|
MD5 | 7ece2bd9907d77d63a3d5147f414e222 |
|
BLAKE2b-256 | 1aca79ae9fd47a68720423abe2ca973038e668bfed69f12f4b80bebdd1b5f6c0 |