Python/MySQL : write to database successful ONLY one time

标签 python mysql database python-3.x cs50

慢慢构建我的应用程序(适用于 CS50),它似乎可以工作,但它只会写入数据库一次。我可以访问该网站,下订单,它每次都会成功地将我的订单显示在 HTML 页面上。但只有一次它将订单写入数据库并显示它。我可以注销,但仍然只有一个订单会写入数据库。

@app.route("/buy", methods=["GET", "POST"])
@login_required
def buy():
    if request.method == "POST":
        #http://stackoverflow.com/questions/32640090/python-flask-keeping-track-of-user-sessions-how-to-get-session-cookie-id
        id = session.get('user_id')

        url_start = 'http://download.finance.yahoo.com/d/quotes.csv?s='
        url_middle = request.form["symbol"]
        url_end = '&f=nsl1d1t1c1ohgv&e=.csv'
        full_url = url_start + url_middle + url_end

        # http://stackoverflow.com/questions/21351882/reading-data-from-a-csv-file-online-in-python-3
        response = urllib.request.urlopen(full_url)

        datareader = csv.reader(io.TextIOWrapper(response))
        quote_list = list(datareader)

        num_shares = request.form["num_shares"]

        name = quote_list[0][0]
        symbol = quote_list[0][1]
        price = float(quote_list[0][2])

        #http://stackoverflow.com/questions/12078571/jinja-templates-format-a-float-as-comma-separated-currency
        total_cost = round((float(price) * 100.0) * float(num_shares) / 100.0,2)

        username = db.execute("SELECT username FROM users WHERE id = :id", id=id)
        username = username[0]
        username = username.get('username')

        db.execute("INSERT INTO purchases (id, symbol, name, shares, price, total) VALUES(:id, :symbol, :name, :shares, :price, :total)",
            id=id, symbol=symbol, name=name, price=price, shares=num_shares, total=total_cost)

        return render_template("bought.html", username=username, id=id, name=name, symbol=symbol, price=price, num_shares=num_shares, total_cost=total_cost)
    else:
        return render_template("buy.html")

最佳答案

首先,大多数问题都可以通过将函数分成几个部分并检查每个部分是否按预期工作来解决,所以让我们稍微重构一下您的代码。

# additional import for generating URL from parts,
# not by concatenating strings
import urllib.parse


@app.route("/buy", methods=["GET", "POST"])
@login_required
def buy():
    if request.method != "POST":
        return render_template("buy.html")

    # http://stackoverflow.com/questions/32640090/python-flask-keeping-track-of-user-sessions-how-to-get-session-cookie-id
    user_id = session.get('user_id')

    # what is "full_url"?
    # to which resource and what we get with it?
    full_url = generate_url(symbol=request.form["symbol"])

    # http://stackoverflow.com/questions/21351882/reading-data-from-a-csv-file-online-in-python-3
    response = urllib.request.urlopen(full_url)

    datareader = csv.reader(io.TextIOWrapper(response))
    quote_list = list(datareader)

    num_shares = request.form["num_shares"]

    # what first element means,
    # if it contains info about specific data
    # there should be name for it
    quote_list_first_element = quote_list[0]
    name = quote_list_first_element[0]
    # is this symbol different from one in "request.form"?
    symbol = quote_list_first_element[1]
    price = float(quote_list_first_element[2])

    # http://stackoverflow.com/questions/12078571/jinja-templates-format-a-float-as-comma-separated-currency
    total_cost = get_total_cost(price, num_shares)

    username = fetch_user_name(user_id)

    save_purchase(user_id=user_id,
                  symbol=symbol,
                  name=name,
                  price=price,
                  num_shares=num_shares,
                  total_cost=total_cost)

    return render_template("bought.html",
                           username=username,
                           id=user_id,
                           name=name,
                           symbol=symbol,
                           price=price,
                           num_shares=num_shares,
                           total_cost=total_cost)


def fetch_user_name(user_id):
    username = db.execute("SELECT username FROM users WHERE id = :user_id",
                          user_id=user_id)
    username = username[0]
    username = username.get('username')
    return username


def save_purchase(user_id, name, num_shares,
                  price, symbol, total_cost):
    db.execute(
        "INSERT INTO purchases (id, symbol, name, num_shares, price, total) "
        "VALUES (:user_id, :symbol, :name, :num_shares, :price, :total)",
        # FIXME: if "purchases" table's "id" column is a primary key 
        # here we are saving purchase by user id 
        # not by purchase id (which probably is auto-incremented 
        # and should not be specified in insert query at all), 
        # so for each user we will have only one purchase since primary key is unique
        user_id=user_id,
        symbol=symbol,
        name=name,
        price=price,
        # maybe it will be better to rename column into "num_shares"?
        shares=num_shares,
        # maybe it will be better to rename column into "total_cost"?
        total=total_cost)


def get_total_cost(price, num_shares):
    return round((float(price) * 100.0) * float(num_shares) / 100.0, 2)


def generate_url(symbol):
    scheme = 'http'
    netloc = 'download.finance.yahoo.com'
    path = '/d/quotes.csv'
    params = ''
    # what 's' query parameter means?
    # looks like it stands for "symbol", but which one?
    # is it product label or something else?
    query_dict = dict(s=symbol,
                      f='nsl1d1t1c1ohgv',
                      e='.csv')
    query_str = urllib.parse.urlencode(query_dict)
    fragment = ''
    components = [scheme, netloc, path, params, query_str, fragment]
    return urllib.parse.urlunparse(components)

现在我们可以看到我们按用户 ID 保存每次购买,但它可能会自动递增列,或者有用户 ID 列,而不是购买 ID 列,我不知道您的数据库架构是什么

如果purchases表的id列是自动递增的,我们可以删除user_id参数

def save_purchase(name, num_shares,
                  price, symbol, total_cost):
    db.execute(
        "INSERT INTO purchases (symbol, name, num_shares, price, total) "
        "VALUES (:symbol, :name, :num_shares, :price, :total)",
        symbol=symbol,
        name=name,
        price=price,
        shares=num_shares,
        total=total_cost)

如果purchases表同时具有iduser_id列,并且我们想要插入指定了user_id的记录应该是这样的

def save_purchase(user_id, name, num_shares,
                  price, symbol, total_cost):
    db.execute(
        "INSERT INTO purchases (user_id, symbol, name, num_shares, price, total) "
        "VALUES (:user_id, :symbol, :name, :num_shares, :price, :total)",
        user_id=user_id,
        symbol=symbol,
        name=name,
        price=price,
        shares=num_shares,
        total=total_cost)

希望有帮助。

关于Python/MySQL : write to database successful ONLY one time,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43315103/

相关文章:

mysql - SQL 插入或更新

mysql - 在插入时使用 MySQL 检查两列的重复项,但两列都不是唯一的

python - QThread异常管理和线程竞争

python - Keras:使用 flow_from_directory 的 fit_generator 的多个输入

z/OS 大型机上 USS 中的 Python 代码 - 无法识别方括号

php - 电子商务,存储订购的产品和产品选项

python - Google Cloud Datastore - 是否可以为单个根实体使用事务?

Python 检查函数是否有返回语句

php - 当 mysql 服务器启动/重新启动时运行更新/删除查询?

SQL选择存在子集的所有行