我正在使用sqlite3在python 2.7上构建数据库,我遇到了一个小问题。
基本上我有两个表,每个表都存储以下信息:
推文:
user_name,
tweet_time,
tweet_text
用户:
user_name,
user_description,
user_followers,
user_verified,
user_location
我正在尝试添加一个提示用户输入字符串的函数,并删除两个表中包含提交的字符串的每一行(可在tweet_text列中找到)。
我遇到的问题是'User'表不包含tweet_text列,因此我不确定如何删除此表中的相应行而不必实际添加tweet_text列。
到目前为止,我只是在'推文'表上进行了简单的删除查询。
delete_string = raw_input("Which string would you like to be removed from your database?: ")
c.execute("DELETE FROM Tweet WHERE tweet_text LIKE ?", ('%'+delete_string+'%',))
我想知道是否有任何方法可以删除“用户”表中的相应行,而无需将tweet_text显式包含为列。
我对python相对缺乏经验,这是我第一次使用查询编写,所以任何帮助都将不胜感激!
提前致谢。
答案 0 :(得分:0)
根据您的问题,您可以通过使用username
列查询tweet_text
来删除,但如果您有来自同一用户的2条推文并删除,我认为您不希望删除用户名之一。
我可能会建议:
# Fetch all users with a tweet_text that is similar to the delete_string
res = c.execute("SELECT user_name FROM Tweet WHERE tweet_text LIKE ?", ('%'+delete_string+'%',)).fetchall()
# If any user is found
if res:
# Get his username
user_name = res[0][0]
# Delete the tweet
c.execute("DELETE FROM Tweet WHERE tweet_text LIKE ?", ('%'+delete_string+'%',))
# If he has no more tweets in the database
if c.execute("SELECT 1 FROM Tweet WHERE user_name = ?", (user_name)).fetchone() is None:
# Delete the user.
c.execute("DELETE FROM User WHERE user_name = ?", (user_name))
如果您愿意,您可以支持多个用户:
# Get all users with similar tweets
res = c.execute("SELECT user_name FROM Tweet WHERE tweet_text LIKE ?", ('%'+delete_string+'%',)).fetchall()
# If there are any
if res:
# Get their user names (make it a set to avoid repeated names)
user_names = set(u[0] for u in res)
# Delete all the similar tweets
c.execute("DELETE FROM Tweet WHERE tweet_text LIKE ?", ('%'+delete_string+'%',))
for user in user_names:
# Check for each user if he has more tweets in the database
if c.execute("SELECT 1 FROM Tweet WHERE user_name = ?", (user,)).fetchone() is None:
# If he has none, delete him.
c.execute("DELETE FROM User WHERE user_name = ?", (user_name))
<强>更新强>
如果您拥有相同数量的行,则必须具有标识符(rowid),该标识符将绑定推文和用户。将tweet数据库定义为:(重要的部分是标识符)
identifier INTEGER PRIMARY KEY AUTOINCREMENT,
user_name TEXT,
tweet_time DATETIME,
tweet_text TEXT
用户数据库如下:
identifier PRIMARY KEY,
user_name TEXT,
user_description TEXT,
...
在向tweet数据库插入行时,使用cursor.lastrowid
以获取生成的标识符,并将生成的标识符与用户一起插入Users数据库。您可能应该在同一个事务中执行此操作。删除后,从两个标识符相同的数据库中删除。
请参阅this stackoverflow问题和有关rowid或标识符列的sqlite文档。
以下是一个例子:
# When adding
with connection:
cursor = connection.execute("INSERT INTO Tweet (user_name, tweet_time, tweet_text) VALUES (?, ?, ?)", (user, time, text))
rowid = cursor.lastrowid
cursor.execute("INSERT INTO User (identifier, user_name, user_description, ...) VALUES (?, ?, ?, ...", (rowid, user, desc, ...))
# When deleting
tweet_ids = c.execute("SELECT identifier FROM Tweet WHERE tweet_text LIKE ?", ('%'+delete_string+'%',)).fetchall()
if tweet_ids:
cursor.executemany("DELETE FROM Tweet WHERE identifier = ?", tweet_ids)
cursor.executemany("DELETE FROM User WHERE identifier = ?", tweet_ids)
# Or one line when deleting (I'm not sure if it works)
c.execute("DELETE tweet, user FROM Tweet tweet JOIN User user "
"ON tweet.identifier = user.identifier "
"WHERE tweet.tweet_text LIKE ?", ('%'+delete_string+'%',))
答案 1 :(得分:0)
我刚刚从脑海中写下了这个,但尝试了这个问题:
DELETE tweet, user
FROM Tweet tweet JOIN User user ON tweet.user_name = user.user_name
WHERE tweet.tweet_text LIKE ?;
虽然您要找的是this,ON DELETE CASCADE
。
这将自动从外键表中删除它,这将是您的User
表。
确保在SQLite中启用外键支持
PRAGMA foreign_keys = ON;