Insert Values from dictionary into sqlite database

后端 未结 3 2100
孤独总比滥情好
孤独总比滥情好 2021-02-06 10:40

I cannot get my head around it. I want to insert the values of a dictionary into a sqlite databse.

url = \"https://api.flickr.com/services/rest/?method=flickr.ph         


        
相关标签:
3条回答
  • 2021-02-06 10:43

    You can use named parameters and insert all rows at once using executemany().

    As a bonus, you would get a good separation of html-parsing and data-pipelining logic:

    data = [{"id_p": photo.get('id'),
             "title_p": photo.get('title'),
             "tags_p": photo.get('tags'),
             "latitude_p": photo.get('latitude'),
             "longitude_p": photo.get('longitude')} for photo in soup.find_all('photo')]
    connector.executemany("""
        INSERT INTO
            DATAGERMANY
            (id_photo, title, tags, latitude, longitude)
        VALUES
            (:id_p, :title_p, :tags_p, :latitude_p, :longitude_p)""", data)
    

    Also, don't forget to actually call the close() method:

    connector.close()
    

    FYI, the complete code:

    import sqlite3
    from urllib2 import urlopen
    from bs4 import BeautifulSoup
    
    url = "https://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=5f...1b&per_page=250&accuracy=1&has_geo=1&extras=geo,tags,views,description"
    soup = BeautifulSoup(urlopen(url))
    
    connector = sqlite3.connect(":memory:")
    cursor = connector.cursor()
    
    cursor.execute('''CREATE TABLE DATAGERMANY
            (id_db INTEGER PRIMARY KEY AUTOINCREMENT,
            id_photo INTEGER NOT NULL,
            title TEXT,
            tags TEXT,
            latitude NUMERIC NOT NULL,
            longitude NUMERIC NOT NULL);''')
    
    data = [{"id_p": photo.get('id'),
             "title_p": photo.get('title'),
             "tags_p": photo.get('tags'),
             "latitude_p": photo.get('latitude'),
             "longitude_p": photo.get('longitude')} for photo in soup.find_all('photo')]
    
    cursor.executemany("""
        INSERT INTO
            DATAGERMANY
            (id_photo, title, tags, latitude, longitude)
        VALUES
            (:id_p, :title_p, :tags_p, :latitude_p, :longitude_p)""", data)
    
    connector.commit()
    
    cursor.close()
    connector.close()
    
    0 讨论(0)
  • 2021-02-06 10:46

    As written, your connector.execute() statement is missing the parameters argument.

    It should be used like this:

    connector.execute("insert into some_time values (?, ?)", ["question_mark_1", "question_mark_2"])
    

    Unless you need the dictionary for later, I would actually use a list or tuple instead:

    row = [
      data.get('id'),
      data.get('title'),
      data.get('tags'),
      data.get('latitude'),
      data.get('longitude'),
    ]
    

    Then your insert statement becomes:

    connector.execute("insert into DATAGERMANY values (NULL,?,?,?,?,?)", *row)
    

    Why these changes?

    • The NULL in the values (NULL, ...) is so the auto-incrementing primary key will work
    • The list instead of the dictionary because order is important, and dictionaries don't preserve order
    • The *row so the five-element row variable will be expanded (see here for details).
    • Lastly, you shouldn't use dict as a variable name, since that's a built-in variable in Python.
    0 讨论(0)
  • 2021-02-06 11:00

    If you're using Python 3.6 or above, you can do this for dicts:

    dict_data = {
     'filename' : 'test.txt',
     'size' : '200'
    }
    table_name = 'test_table'
    attrib_names = ", ".join(dict_data.keys())
    attrib_values = ", ".join("?" * len(dict_data.keys()))
    sql = f"INSERT INTO {table_name} ({attrib_names}) VALUES ({attrib_values})"
    cursor.execute(sql, list(dict_data.values()))
    
    0 讨论(0)
提交回复
热议问题