在Python中查询

时间:2016-03-14 21:26:35

标签: python mysql sqlite

我正在使用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相对缺乏经验,这是我第一次使用查询编写,所以任何帮助都将不胜感激!

提前致谢。

2 个答案:

答案 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))
  1. 首先,如果推文存在,则获取user_name
  2. 然后删除推文
  3. 然后检查是否有来自同一用户的更多推文。
  4. 如果没有,则从数据库中删除他。
  5. 如果您愿意,您可以支持多个用户:

    # 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 ?;

虽然您要找的是thisON DELETE CASCADE。 这将自动从外键表中删除它,这将是您的User表。

确保在SQLite中启用外键支持

PRAGMA foreign_keys = ON;