我正在制作一个使用Python Flask和Sqlite3的API。大多数都有效。具体做法是:
但是,其余的POST / INSERT INTO不起作用。它们都具有相同的sqlite3.OperationalError,并带有消息:
no such table: main.source
这很奇怪,因为没有一个查询使用名为" source"或" main.source"。我在execute
之前打印查询,我尝试将查询复制/粘贴到sqlite3命令提示符中。当我这样做时,查询没有问题。
另一个奇怪的是,所有INSERT INTO查询都调用相同的函数来创建实际的查询(后者又调用函数来运行查询...所有查询都使用它们大多数工作)。只有部分INSERT INTO会导致此错误。
一些可能有用的信息:
摘自createdb.sql
CREATE TABLE transactions (
id INTEGER PRIMARY KEY,
buyer INTEGER NOT NULL,
seller INTEGER NOT NULL,
amount INTEGER NOT NULL,
currency VARCHAR(6) NOT NULL,
fee INTEGER NOT NULL,
source INTEGER NOT NULL,
description TEXT NOT NULL,
status VARCHAR(40) NOT NULL,
created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
);
插入到Python中的插入/会在execute
中抛出错误:
INSERT INTO transactions (status, fee, description, source, seller, currency, amount, buyer) VALUES ('initiated', '1', 'nada', '1', '2', 'USD', '1000', '1');
来自Sqlite提示的一些内容:
sqlite> .tables
conversations sources users
messages transactions withdrawals
sqlite> SELECT id, description FROM transactions;
1|hella mulah
2|payback
3|woohoo
sqlite> INSERT INTO transactions (status, fee, description, source, seller, currency, amount, buyer) VALUES ('initiated', '1', 'nada', '1', '2', 'USD', '1000', '1');
sqlite>
sqlite> SELECT id, description FROM transactions;
1|hella mulah
2|payback
3|woohoo
4|nada
对于引用,这里是一个POST命令,尽管使用了大部分相同的东西,但没有错误:
INSERT INTO users (session, balance, name, firebaseToken) VALUES ('ABCDEFG', '0', 'Mr Miyagi', 'ABCDEFG');
在SO上有很多类似的问题,但这里有不重复的原因:
flask/sqlalchemy - OperationalError: (sqlite3.OperationalError) no such table是的,我在使用之前创建了表格。
Why am I suddenly getting "OperationalError: no such table"?我的Flask应用程序能够找到数据库没问题(并且大多数查询都可以正常运行)。为了安全起见,我使connect
中的数据库成为绝对路径。没效果。
Error: sqlite3.OperationalError: no such table: main.m我不做任何奇怪的索引+如果我这样做,那么复制粘贴将无法正常工作
Python Sqlite3 - Data is not saved permanently:我确实在@app.teardown_appcontext
中调用了提交。我也尝试在每次查询后调用commit。没效果。
我考虑过的其他内容但排除在外:
transactions
接近transaction
但不一样。 source
不在列表中。我确定这最终会成为某种愚蠢的混乱,但任何关于在哪里看的想法都会受到高度赞赏。我也试过谷歌搜索这个错误,但我没有看到任何有用的东西。
---更多代码---
这是database.py
import sqlite3
import flask
import backend
def dict_factory(cursor, row):
output = {}
for idx, col in enumerate(cursor.description):
output[col[0]] = row[idx]
return output
def get_db():
if not hasattr(flask.g, 'sqlite_db'):
flask.g.sqlite_db = sqlite3.connect("/my/absolute/path/var/data.db"
)
flask.g.sqlite_db.row_factory = dict_factory
flask.g.sqlite_db.execute("PRAGMA foreign_keys = ON;")
return flask.g.sqlite_db
def query(query, args=(), islast=False):
print(query) # this is where the print from before is
cur = get_db().execute(query, args)
rowvector = cur.fetchall()
if islast:
cur.close()
return rowvector
@backend.app.teardown_appcontext
def close_db(error):
if hasattr(flask.g, 'sqlite_db'):
flask.g.sqlite_db.commit()
flask.g.sqlite_db.close()
这是apiimpl.py
中选定的部分QUERY_INSERT = "INSERT INTO"
QUERY_SELECT = "SELECT"
QUERY_UPDATE = "UPDATE"
def queryhelper(*args, **kwargs):
sqltxt = None
selectstr = None
if kwargs["action"] == QUERY_INSERT:
sqltxt = "{} {} ({}) VALUES ({});".format(
QUERY_INSERT,
kwargs["table"],
", ".join(["{}".format(x) for x in kwargs["cols"]]),
", ".join(["'{}'".format(x) for x in kwargs["vals"]]),
)
# pretty sure this next bit is not relevant but here it is anyway
selectstr = "SELECT * FROM {} WHERE ROWID=(SELECT last_insert_rowid());".format(
kwargs["table"],
)
elif kwargs["action"] == QUERY_SELECT:
# not relevant
elif kwargs["action"] == QUERY_UPDATE:
# not relevant
else:
assert(kwargs["action"] in [QUERY_INSERT, QUERY_SELECT, QUERY_UPDATE,])
try:
rv = db.query(sqltxt) # this is where the error is thrown
if selectstr:
return db.query(selectstr)
else:
return rv
except sqlite3.OperationalError as e:
# this is where the error is caught
return api_error("SQL error (1): {}", str(e), code=500)
def append(tablename, args):
tabledata = TABLES().tablenamemap[tablename]
print("tablename: " + tablename) # "tablename: transactions"
# a bunch of error detection
rv = queryhelper(
action=QUERY_INSERT,
table=tablename,
cols=args.keys(),
vals=args.values(),
)
# not shown: potentially returning json.dumps(rv)
return rv
def transactions_post(req):
# a lot of stuff to turn req into validargs
# printed validargs: {'status': 'initiated', u'fee': u'1', u'description': u'nada', u'source': u'1', u'seller': u'2', u'currency': u'USD', u'amount': u'1000', u'buyer': u'1'}
return append("transactions", validargs)
@backend.app.route("/transactions", methods=["GET", "POST", "PUT"])
def transactions_route():
return {
"GET": transactions_get, # get list of transactions
"POST": transactions_post, # initiate a transaction
"PUT": transactions_put, # change transaction status
}[flask.request.method](flask.request)
P.S。这个问题的目的不是讨论实施,而是如果你想发表评论对我好。
---回应评论 -
sqlite> SELECT * FROM sqlite_master WHERE type="table" AND name="transactions";
table|transactions|transactions|4|CREATE TABLE transactions (
id INTEGER PRIMARY KEY,
buyer INTEGER NOT NULL,
seller INTEGER NOT NULL,
amount INTEGER NOT NULL,
currency VARCHAR(6) NOT NULL,
fee INTEGER NOT NULL,
source INTEGER NOT NULL,
description TEXT NOT NULL,
status VARCHAR(40) NOT NULL,
created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (buyer) REFERENCES users(id), -- do not want to delete on CASCADE
FOREIGN KEY (seller) REFERENCES users(id), -- do not want to delete on CASCADE
FOREIGN KEY (source) REFERENCES source(id) -- do not want to delete on CASCADE
)
答案 0 :(得分:2)
看起来您正在引用基于.tables命令的不存在的表。
sqlite> .tables
conversations sources users
messages transactions withdrawals
这个创建表语句。
CREATE TABLE transactions (
id INTEGER PRIMARY KEY,
buyer INTEGER NOT NULL,
seller INTEGER NOT NULL,
amount INTEGER NOT NULL,
currency VARCHAR(6) NOT NULL,
fee INTEGER NOT NULL,
source INTEGER NOT NULL,
description TEXT NOT NULL,
status VARCHAR(40) NOT NULL,
created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (buyer) REFERENCES users(id), -- do not want to delete on CASCADE
FOREIGN KEY (seller) REFERENCES users(id), -- do not want to delete on CASCADE
FOREIGN KEY (source) REFERENCES source(id) -- do not want to delete on CASCADE
-- ^ there is no source table
)
如果您将来源(ID)更改为来源(ID),那么您应该会感觉良好。