Frage

Ich lerne Python, und als erstes Projekt nehme Twitter RSS-Feeds, Analysieren der Daten, und die Daten in einer SQLite-Datenbank einfügen. Ich konnte erfolgreich jeden Feed-Eintrag in einen Inhalt analysiert Variable (zB "Sie sollten niedrig kaufen ..."), ein url Variable (zB u‘ http://bit.ly/HbFwL ') und eine Hashtag Liste (zB #stocks', u '# Börse', u '# finance', u '# Geld', u '# mkt']). Ich habe auch erfolgreich gewesen, diese drei Informationen in drei separate Spalten in einem SQLite „RSSEntries“ Tisch im Einfügen, wobei jede Zeile eine andere rss entry / tweet.

Allerdings möchte ich eine Datenbank einzurichten, in denen es eine many-to-many-Beziehung zwischen den einzelnen RSS-Feed-Einträge ist (das heißt, einzelne Tweets) und den Hashtags, die mit jedem Eintrag zugeordnet sind. Also, habe ich die folgenden Tabellen mit sqlalchemy up (die erste Tabelle enthält nur die RSS-Feed-URLs Twitterer, die ich herunterladen möchten, und analysieren):

RSSFeeds = schema.Table('feeds', metadata,
    schema.Column('id', types.Integer, 
        schema.Sequence('feeds_seq_id', optional=True), primary_key=True),
    schema.Column('url', types.VARCHAR(1000), default=u''),
)

RSSEntries = schema.Table('entries', metadata,
    schema.Column('id', types.Integer, 
        schema.Sequence('entries_seq_id', optional=True), primary_key=True),
    schema.Column('feed_id', types.Integer, schema.ForeignKey('feeds.id')),
    schema.Column('short_url', types.VARCHAR(1000), default=u''),
    schema.Column('content', types.Text(), nullable=False),
    schema.Column('hashtags', types.Unicode(255)),
)

tag_table = schema.Table('tag', metadata,
    schema.Column('id', types.Integer,
       schema.Sequence('tag_seq_id', optional=True), primary_key=True),
    schema.Column('tagname', types.Unicode(20), nullable=False, unique=True)
)

entrytag_table = schema.Table('entrytag', metadata,
    schema.Column('id', types.Integer,
        schema.Sequence('entrytag_seq_id', optional=True), primary_key=True),
    schema.Column('entryid', types.Integer, schema.ForeignKey('entries.id')),
    schema.Column('tagid', types.Integer, schema.ForeignKey('tag.id')),
)

Bisher konnte ich nur die drei wichtigsten Stücke von Informationen in die RSSEntries Tabelle mit dem folgenden Code erfolgreich eingeben (abgekürzt, wo ...)

engine = create_engine('sqlite:///test.sqlite', echo=True)
conn = engine.connect()
.........
conn.execute('INSERT INTO entries (feed_id, short_url, content, hashtags) VALUES 
    (?,?,?,?)', (id, tinyurl, content, hashtags))

Nun, hier ist die große Frage. Wie füge ich die Daten in die feedtag und tagname Tabellen? Dies ist ein echter Knackpunkt für mich, da der Start hasthag Variable ist derzeit eine Liste, und jeder Feed-Eintrag irgendwo zwischen 0 und, sagen wir, 6 Hashtags enthalten könnten. Ich weiß, wie die ganze Liste in eine einzige Spalte einzufügen, aber nicht, wie nur die Elemente der Liste in separate Spalten (oder, in diesem Beispiel Zeilen) einzufügen. Ein größerer Knackpunkt ist die allgemeine Frage, wie die einzelnen Hashtags zum Einfügen in die tagname Tabelle, wenn ein Tag-Name in zahlreichen unterschiedlichen Feed-Einträgen verwendet werden könnte, und dann, wie die „Verbände“ richtig erscheinen müssen feedtag Tabelle.

Kurz gesagt, ich weiß genau, wie jeder der Tabellen aussehen soll, wenn sie fertig sind, aber ich habe keine Ahnung, wie Sie den Code zu schreiben, um die Daten in den tagname zu bekommen und feedtag Tabellen. Das ganze "many-to-many" Set-up ist neu für mich.

Ich kann wirklich Ihre Hilfe auf diesem verwenden. Vielen Dank im Voraus für alle Anregungen.

-Greg

P. S. - Bearbeiten - Dank Aasma ausgezeichnete Vorschläge Ameisen, ich habe in der Lage zu fast erhält die ganze Sache zu arbeiten. Insbesondere jetzt die 1. und 2. vorgeschlagene Codeblocks gut funktionieren, aber ich habe ein Problem mit dem dritten Block von Code zu implementieren. Ich erhalte die folgende Fehlermeldung:

Traceback (most recent call last):
  File "RSS_sqlalchemy.py", line 242, in <module>
    store_feed_items(id, entries)
  File "RSS_sqlalchemy.py", line 196, in store_feed_items
    [{'feedid': entry_id, 'tagid': tag_ids[tag]} for tag in hashtags2])
NameError: global name 'entry_id' is not defined

Dann, denn ich konnte nicht sagen, wo Ameisen Aasma den „entry_id“ Teil von bekam, habe ich versucht, es mit „entries.id“ zu ersetzen, denken könnte dies die „id“ aus der „Einträgen“ Tabelle einfügen. Doch in diesem Fall bekomme ich diesen Fehler:

Traceback (most recent call last):
  File "RSS_sqlalchemy.py", line 242, in <module>
    store_feed_items(id, entries)
  File "RSS_sqlalchemy.py", line 196, in store_feed_items
    [{'feedid': entries.id, 'tagid': tag_ids[tag]} for tag in hashtags2])
AttributeError: 'list' object has no attribute 'id'

Ich bin mir nicht ganz sicher, wo das Problem ist, und ich weiß nicht wirklich verstehen, wo die „entry_id“ an passt, also habe ich unter allen meinen relevant „Einfügen“ Code eingefügt in. Kann mir helfen, jemanden zu sehen, was falsch ist? Beachten Sie, dass ich auch gerade bemerkt, dass ich falsch meine letzte Tabelle „feedtag_table“ statt „entrytag_table“ entsprechen rief mit meiner eingangs genannten Ziel in Bezug einzelnen Feed Einträge zu Hashtags, anstatt Feeds Das ist nicht zu Hashtags. Ich habe den Code oben, da korrigiert.

feeds = conn.execute('SELECT id, url FROM feeds').fetchall()

def store_feed_items(id, items):
    """ Takes a feed_id and a list of items and stored them in the DB """
    for entry in items:
        conn.execute('SELECT id from entries WHERE short_url=?', (entry.link,))
        s = unicode(entry.summary) 
        test = s.split()
        tinyurl2 = [i for i in test if i.startswith('http://')]
        hashtags2 = [i for i in s.split() if i.startswith('#')]
        content2 = ' '.join(i for i in s.split() if i not in tinyurl2+hashtags2)
        content = unicode(content2)
        tinyurl = unicode(tinyurl2)
        hashtags = unicode (hashtags2)
        date = strftime("%Y-%m-%d %H:%M:%S",entry.updated_parsed)

        conn.execute(RSSEntries.insert(), {'feed_id': id, 'short_url': tinyurl,
            'content': content, 'hashtags': hashtags, 'date': date})    

        tags = tag_table
        tag_id_query = select([tags.c.tagname, tags.c.id], tags.c.tagname.in_(hashtags))
        tag_ids = dict(conn.execute(tag_id_query).fetchall())
        for tag in hashtags:
            if tag not in tag_ids:
                result = conn.execute(tags.insert(), {'tagname': tag})
                tag_ids[tag] = result.last_inserted_ids()[0]

        conn.execute(entrytag_table.insert(),
            [{'feedid': id, 'tagid': tag_ids[tag]} for tag in hashtags2])
War es hilfreich?

Lösung

Als erstes sollten Sie die SQLAlchemy SQL-Builder für die Einsätze verwenden SQLAlcehemy mehr Einblick in das geben, was Sie tun.

 result = conn.execute(RSSEntries.insert(), {'feed_id': id, 'short_url': tinyurl,
        'content': content, 'hashtags': hashtags, 'date': date})
 entry_id = result.last_insert_ids()[0]

Um Tag Assoziationen zu Ihrem Schema fügen Sie Ihren Tag Identifikatoren aufblicken zur Faust brauchen und schaffen alle, die nicht existieren:

tags = tag_table
tag_id_query = select([tags.c.tagname, tags.c.id], tags.c.tagname.in_(hashtags))
tag_ids = dict(conn.execute(tag_id_query).fetchall())
for tag in hashtags:
    if tag not in tag_ids:
        result = conn.execute(tags.insert(), {'tagname': tag})
        tag_ids[tag] = result.last_inserted_ids()[0]

Dann legen Sie einfach die zugehörigen IDs in die feedtag_table. Sie können, indem man eine Liste von dicts an die Methode execute die executemany Unterstützung verwenden.

conn.execute(feedtag_table.insert(),
    [{'feedid': entry_id, 'tagid': tag_ids[tag]} for tag in hashtags])
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top