【发布时间】:2021-01-31 04:29:49
【问题描述】:
所以我使用 FlaskSQLAlchemy 编写了一个推荐系统,当我测试它时,它有时有效,有时无效,我发现它非常混乱,任何帮助将不胜感激。
这是模型:
class User(TimestampMixin, UserMixin, db.Model):
# __tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
role_id = db.Column(db.Integer, db.ForeignKey('role.id'))
public_id = db.Column(db.String(MaxLengths.public_id))
email = db.Column(db.String(MaxLengths.email), unique=True, nullable=False)
password = db.Column(db.String(MaxLengths.password))
reset_password_code = db.Column(db.String(MaxLengths.reset_password_code))
attempt_reset_password = db.Column(db.Boolean(), default=False)
is_email_verified = db.Column(db.Boolean(), default=False)
is_age_verified = db.Column(db.Boolean(), default=False)
is_newsletter_registered = db.Column(db.Boolean(), default=True)
balance = db.Column(db.Float(), default=0.0)
lifetime_balance = db.Column(db.Float(), default=0.0)
reviews = db.relationship('Review', backref='user')
ref_code = db.Column(db.String(MaxLengths.ref_code))
# NOTE: Ref relationships here
referred_by_user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
referred_by_user = db.relationship(
'User', foreign_keys=[referred_by_user_id], uselist=False
)
referred_to_user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
referred_to_users = db.relationship(
'User', foreign_keys=[referred_to_user_id], post_update=True)
discount_code_used_by_id = db.Column(
db.Integer, db.ForeignKey('discount_code.id'))
profile_pic = db.Column(db.Boolean(), default=False)
id_verification_pics = db.Column(db.JSON(), default=[])
orders = db.relationship('Orders', backref='user')
login_attempts = db.relationship('LoginAttempt', backref='user')
last_seen = db.Column(ArrowType, default=arrow.utcnow())
# TODO: Update this upon placing an order
total_spent = db.Column(db.Float(), default=0.0)
billing_address_id = db.Column(db.Integer, db.ForeignKey('address.id'))
shipping_address_id = db.Column(db.Integer, db.ForeignKey('address.id'))
billing_address = db.relationship(
'Address', foreign_keys=[billing_address_id], uselist=False)
shipping_address = db.relationship(
'Address', foreign_keys=[shipping_address_id], uselist=False)
review_votes = db.relationship('ReviewVote', backref='user')
consumer_id = db.Column(db.String(MaxLengths.consumer_id))
class Orders(TimestampMixin, db.Model):
'''
Orders database model and custom order related functions
'''
id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
status = db.Column(db.String(MaxLengths.order_status),
default="Order Pending")
dest_address_id = db.Column(db.Integer, db.ForeignKey('address.id'))
from_address_id = db.Column(db.Integer, db.ForeignKey('address.id'))
dest_address = db.relationship('Address', foreign_keys=[
dest_address_id], uselist=False)
from_address = db.relationship('Address', foreign_keys=[
from_address_id], uselist=False)
products = db.relationship('Product', backref='orders')
subtotal = db.Column(db.Float())
shipping_fee = db.Column(db.Float(), nullable=False)
tax_cost = db.Column(db.Float())
tax_percent = db.Column(db.Float(), nullable=False)
total = db.Column(db.Float())
discount_code = db.relationship(
'DiscountCode', uselist=False)
discount_code_amount = db.Column(db.Float)
user_balance_applied = db.Column(db.Float)
currency = db.Column(db.String(MaxLengths.currency), default="CAD")
date = db.Column(ArrowType, default=arrow.utcnow()
) # datetime.datetime.now()
# TODO: This should exist in the interac_payment obj/json
is_payment_recieved = db.Column(
db.Boolean(), nullable=False, default=False)
interac_payment = db.Column(db.JSON(), default={})
order_number = db.Column(db.String(MaxLengths.order_number), default='')
tracking_number = db.Column(db.String(MaxLengths.tracking_number))
tracking_info = db.Column(db.JSON)
ref_record = db.relationship(
'ReferralRecord', backref='order', uselist=False)
def apply_ref_bonus(self, rate=1.5):
if self.is_payment_recieved:
# user = self.get_user()
if not self.user:
print("No user found for this order")
if not self.user.referred_by_user:
print('This user wasn\'t referred by anyone')
print(self.user.referred_by_user)
if self.user and self.user.referred_by_user:
cashback = (self.subtotal * (rate / 100))
record = ReferralRecord(
referred_by_user_email=self.user.referred_by_user.email,
referred_to_user_email=self.user.email,
cashback_amount=cashback)
self.user.referred_by_user.balance += cashback
self.user.referred_by_user.lifetime_balance += cashback
self.ref_record = record
db.session.add(record)
db.session.add(self.user.referred_by_user)
db.session.add(self.user)
db.session.commit()
class DiscountCode(TimestampMixin, db.Model):
'''
:param id: int primary_key
:param code: str discount code
:param amount: float numeric representation of discount
:param is_percent_off: bool amount is treated as a % discount if True
:param minimum_subtotal: float minimum order subtotal for discount code to be valid for a given order
:param expiration_date: datetime() the date a code is no longer valid
:param uses: int the number of times the code has been used
:param max_uses: int max number of times a code can be used before becoming invalid
:param used_by: a list of User objects who have used this code (for analytical purposes)
'''
id = db.Column(db.Integer(), primary_key=True)
code = db.Column(db.String(MaxLengths.discount_code),
unique=True, nullable=False)
amount = db.Column(db.Float(), nullable=False)
is_percent_off = db.Column(db.Boolean(), default=False)
minimum_subtotal = db.Column(db.Float(), default=0.0)
# TODO: add default via arrow.shift()
start_date = db.Column(ArrowType)
expiration_date = db.Column(ArrowType)
uses = db.Column(db.Integer(), default=0)
max_uses = db.Column(db.Integer(), default=0)
order_id = db.Column(db.Integer, db.ForeignKey('orders.id'))
这是测试用例:
def referr(ref_by_user, ref_to_user):
ref_by_user.referred_to_users.append(ref_to_user)
ref_to_user.referred_by_user = ref_by_user
db.session.add(ref_by_user)
db.session.add(ref_to_user)
db.session.commit()
@app.cli.command('test-ref')
def testref():
db.drop_all()
db.create_all()
user1 = User(email='test1@example.com')
user2 = User(email='test2@example.com')
user3 = User(email='test3@example.com')
order = Orders(shipping_fee=4.00, tax_percent=0.5, subtotal=15.00, total=18.50, is_payment_recieved=True, interac_payment={})
db.session.add(user1)
db.session.add(user2)
db.session.add(user3)
db.session.add(order)
db.session.commit()
# user1.referr(user2)
# user1.referr(user3)
# referr(user1, user2)
# referr(user1, user3)
user1.referred_to_users.append(user2)
user1.referred_to_users.append(user3)
user2.referred_by_user = user1
user3.referred_by_user = user1
print("This should be == 0 - ", user1.balance)
user2.orders.append(order)
# order.user = user2
db.session.add(user1)
db.session.add(user2)
db.session.add(user3)
db.session.add(order)
db.session.commit()
# user2.apply_ref_bonus_from_order(order)
order.apply_ref_bonus()
db.session.commit()
print("This should be > 0 - ", user1.balance)
print(user1.referred_to_users)
但有时我会得到以下输出:
This should be == 0 - 0.0
This should be > 0 - 0.22499999999999998
[<User 'test2@example.com'>, <User 'test3@example.com'>]
其他时候我得到这个输出:
This should be == 0 - 0.0
This user wasn't referred by anyone
None
This should be > 0 - 0.0
[<User 'test2@example.com'>, <User 'test3@example.com'>]
我使用相同的代码得到不同的输出,尽管每当我尝试使用来自 User 模型或作为独立函数的 referr() 包装器时,我总是得到后者的输出。当我不通过函数推荐用户时,会出现不一致的输出,老实说,我真的对整个事情感到困惑
【问题讨论】:
标签: python flask sqlalchemy flask-sqlalchemy