الإعداد/الإدراج في قاعدة بيانات متعددة الأطراف باستخدام Python وSQLALchemy وSqlite

StackOverflow https://stackoverflow.com/questions/1403084

سؤال

أنا أتعلم لغة بايثون، وكمشروع أول أقوم بأخذ خلاصات RSS من Twitter، وتحليل البيانات، وإدراج البيانات في قاعدة بيانات sqlite.لقد تمكنت من تحليل كل إدخال موجز في ملف محتوى متغير (على سبيل المثال، "يجب عليك الشراء بسعر منخفض...")، أ عنوان URL متغير (على سبيل المثال، u'http://bit.ly/HbFwL")، و أ الوسم قائمة (على سبيل المثال، #stocks'، u'#stockmarket'، u'#finance'، u'#money'، u'#mkt']).لقد نجحت أيضًا في إدراج هذه الأجزاء الثلاثة من المعلومات في ثلاثة أعمدة منفصلة في جدول "RSSEentries" sqlite، حيث يكون كل صف عبارة عن إدخال/تغريدة RSS مختلفة.

ومع ذلك، أريد إعداد قاعدة بيانات حيث توجد علاقة متعدد إلى متعدد بين إدخالات موجز RSS الفردية (أي التغريدات الفردية) وعلامات التصنيف المرتبطة بكل إدخال.لذلك، قمت بإعداد الجداول التالية باستخدام sqlalchemy (يتضمن الجدول الأول فقط عناوين URL لخلاصات RSS الخاصة بمستخدمي Twitter والتي أريد تنزيلها وتحليلها):

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')),
)

لقد تمكنت حتى الآن من إدخال المعلومات الثلاثة الرئيسية بنجاح في جدول RSSEentries باستخدام الكود التالي (مختصر حيث...)

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))

الآن، وهنا السؤال الكبير.كيف أقوم بإدخال البيانات في com.feedtag و اسم العلامة الجداول؟هذه نقطة شائكة حقيقية بالنسبة لي، منذ أن بدأت hashtag المتغير عبارة عن قائمة حاليًا، ويمكن أن يحتوي كل إدخال في الخلاصة على ما بين 0 و6 علامات تصنيف على سبيل المثال.أعرف كيفية إدراج القائمة بأكملها في عمود واحد ولكن لا أعرف كيفية إدراج عناصر القائمة فقط في أعمدة منفصلة (أو في هذا المثال، صفوف).النقطة الشائكة الأكبر هي السؤال العام حول كيفية إدراج علامات التصنيف الفردية في اسم العلامة الجدول عندما يمكن استخدام اسم العلامة في العديد من إدخالات الخلاصات المختلفة، ثم كيفية ظهور "الارتباطات" بشكل صحيح في com.feedtag طاولة.

باختصار، أعرف بالضبط كيف يجب أن يبدو كل جدول عند الانتهاء من كل شيء، لكن ليس لدي أي فكرة عن كيفية كتابة التعليمات البرمجية لإدخال البيانات في اسم العلامة و com.feedtag الجداول.إن إعداد "من متعدد إلى متعدد" بأكمله جديد بالنسبة لي.

يمكنني حقا استخدام مساعدتكم في هذا الشأن.شكرا مقدما على أي اقتراحات.

-جريج

ملاحظة.- يحرر - بفضل اقتراحات النمل أسماء الممتازة، فقد تمكنت من ذلك بالكاد الحصول على كل شيء للعمل.على وجه التحديد، تعمل الآن الكتلتان المقترحتان من التعليمات البرمجية بشكل جيد، ولكن أواجه مشكلة في تنفيذ المجموعة الثالثة من التعليمات البرمجية.اتلقى الخطأ التالي:

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

بعد ذلك، لأنني لم أتمكن من معرفة من أين حصلت Ants Aasma على الجزء "entry_id"، حاولت استبداله بـ "entries.id"، معتقدًا أن هذا قد يدرج "id" من جدول "entries".ومع ذلك، في هذه الحالة أحصل على هذا الخطأ:

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'

لست متأكدًا تمامًا من مكان المشكلة، ولا أفهم حقًا المكان المناسب للجزء "entry_id"، لذلك قمت بلصق كل كود "الإدراج" ذي الصلة أسفله.هل يمكن لأحد أن يساعدني في معرفة ما هو الخطأ؟لاحظ أنني لاحظت للتو أنني كنت أسمي جدولي الأخير بشكل غير صحيح "feedtag_table" بدلاً من "entrytag_table" وهذا لا يتطابق مع هدفي المعلن في البداية وهو ربط الخلاصة الفردية إدخالات إلى علامات التصنيف، بدلاً من خلاصات علامات التصنيف.لقد قمت منذ ذلك الحين بتصحيح الكود أعلاه.

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])
هل كانت مفيدة؟

المحلول

أولاً، يجب عليك استخدام منشئ SQLAlchemy SQL للإدراجات لمنح SQLAlcehemy مزيدًا من المعرفة حول ما تفعله.

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

لإدراج ارتباطات العلامات في مخططك، يتعين عليك البحث أولاً عن معرفات العلامات الخاصة بك وإنشاء أي معرفات غير موجودة:

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]

ثم فقط أدخل المعرف المرتبط في ملف feedtag_table.يمكنك استخدام دعم تنفيذ العديد من خلال تمرير قائمة الإملاءات إلى طريقة التنفيذ.

conn.execute(feedtag_table.insert(),
    [{'feedid': entry_id, 'tagid': tag_ids[tag]} for tag in hashtags])
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top