سؤال

db = sqlite.connect("test.sqlite")
res = db.execute("select * from table")

مع التكرار أحصل على قوائم تتوافق مع الصفوف.

for row in res:
    print row

يمكنني الحصول على اسم الأعمدة

col_name_list = [tuple[0] for tuple in res.description]

ولكن هل هناك بعض الوظائف أو الإعداد للحصول على القواميس بدلا من القائمة?

{'col1': 'value', 'col2': 'value'}

أو يجب أن أفعل نفسي?

هل كانت مفيدة؟

المحلول

يمكنك استخدام ROW_AFTORY ، كما في المثال فيالمستندات:

giveacodicetagpre.

أو اتبع النصيحة التي تعطى مباشرة بعد هذا المثال في المستندات:

إذا لم يكن إرجاع tuple لا يكفي وتريد الوصول المستندة إلى الاسم الأعمدة، يجب أن تنظر في الإعداد Row_Factory إلى الأمثل للغاية SQLite3.Wrow نوع.يوفر الصف كليهما المستندة إلى الفهرس وغير حساس الوصول المستندة إلى الاسم إلى الأعمدة مع تقريبا لا توجد ذاكرة النفقات العامة.سوف تكون ربما يكون أفضل من الخاصة بك النهج القائم على القاموس المخصصة أو حتى الحل القائم على DB_ROW.

نصائح أخرى

اعتقدت أنني أجب على هذا السؤال على الرغم من أن الإجابة مذكورة جزئيا في إجابات Adam Schmideg's و Alex Martelli.من أجل الآخرين مثلي لديهم نفس السؤال، للعثور على الإجابة بسهولة.

giveacodicetagpre.

حتى باستخدام فئة SQLITE3.ROW - لا تزال غير قادر على استخدام تنسيق السلسلة في شكل:

giveacodicetagpre.

من أجل تجاوز هذا، يمكنني استخدام وظيفة المساعد التي تأخذ الصف وتحول إلى القاموس.أنا فقط استخدام هذا عندما يكون كائن القاموس هو الأفضل لكائن الصف (E.G. بالنسبة للأشياء مثل تنسيق السلسلة حيث لا يدعم كائن الصف أصليا قاموس API أيضا).ولكن استخدم كائن الصف في جميع الأوقات الأخرى.

giveacodicetagpre.

بعد الاتصال سكليتي:con = sqlite3.connect(.....) ويكفي لتشغيل فقط:

con.row_factory = sqlite3.Row

فويلا!

من PEP 249 :

giveacodicetagpre.

لذلك نعم، افعل ذلك بنفسك.

نسخة أقصر:

giveacodicetagpre.

أسرع في اختباراتي:

giveacodicetagpre.

vs:

giveacodicetagpre.

تقرر :)

كما ذكر الجواب @ غاندالف ، على المرء أن يستخدم conn.row_factory = sqlite3.Row, ، لكن النتائج هي ليس مباشرة القواميس.على المرء أن يضيف "مصبوب" إضافي إلى dict في الحلقة الأخيرة:

import sqlite3
conn = sqlite3.connect(":memory:")
conn.execute('create table t (a text, b text, c text)')
conn.execute('insert into t values ("aaa", "bbb", "ccc")')
conn.execute('insert into t values ("AAA", "BBB", "CCC")')
conn.row_factory = sqlite3.Row
c = conn.cursor()
c.execute('select * from t')
for r in c.fetchall():
    print(dict(r))

# {'a': 'aaa', 'b': 'bbb', 'c': 'ccc'}
# {'a': 'AAA', 'b': 'BBB', 'c': 'CCC'}

مماثلة مثل الحلول المذكورة قبل ذلك، ولكن أكثر مدمجة:

giveacodicetagpre.

أعتقد أنك كنت على الطريق الصحيح.دعونا نبقي هذا بسيطا جدا ونكمل ما كنت تحاول القيام به:

import sqlite3
db = sqlite3.connect("test.sqlite3")
cur = db.cursor()
res = cur.execute("select * from table").fetchall()
data = dict(zip([c[0] for c in cur.description], res[0]))

print(data)

الجانب السلبي هو أن .fetchall(), ، وهو القتل على استهلاك الذاكرة الخاصة بك, ، إذا كانت طاولتك كبيرة جدا.ولكن بالنسبة للتطبيقات التافهة التي تتعامل مع بضعة آلاف من صفوف النص والأعمدة الرقمية ، فإن هذا النهج البسيط جيد بما فيه الكفاية.

بالنسبة للأشياء الجادة ، يجب أن تنظر في مصانع الصفوف ، كما هو مقترح في العديد من الإجابات الأخرى.

أو يمكنك تحويل sqlite3. ولا تقاطع في القاموس على النحو التالي.هذا سيعطي القاموس مع قائمة لكل صف.

giveacodicetagpre.

بديل عام، باستخدام ثلاثة خطوط فقط

giveacodicetagpre.

ولكن إذا أخلف استفسارك شيئا، فسوف ينتج عنه خطأ.في هذه الحالة ...

giveacodicetagpre.

أو

giveacodicetagpre.

giveacodicetagpre.

النتيجة هي بالتأكيد صحيحة، لكنني لا أعرف الأفضل.

توفر القواميس في بايثون وصولا تعسفيا إلى عناصرها.لذلك أي قاموس مع "أسماء" على الرغم من أنه قد يكون بالمعلومات من جهة (ويعرف أيضا باسم.ما هي أسماء الحقول) "إلغاء أوامر" الحقول ، والتي قد تكون غير مرغوب فيها.

أفضل طريقة هي الحصول على الأسماء في قائمة منفصلة ثم دمجها مع النتائج بنفسك ، إذا لزم الأمر.

try:
         mycursor = self.memconn.cursor()
         mycursor.execute('''SELECT * FROM maintbl;''')
         #first get the names, because they will be lost after retrieval of rows
         names = list(map(lambda x: x[0], mycursor.description))
         manyrows = mycursor.fetchall()

         return manyrows, names

تذكر أيضا أن الأسماء ، في جميع النهج ، هي الأسماء التي قدمتها في الاستعلام ، وليس الأسماء في قاعدة البيانات.الاستثناء هو SELECT * FROM

إذا كان الشاغل الوحيد هو الحصول على النتائج باستخدام القاموس ، ثم بالتأكيد استخدام conn.row_factory = sqlite3.Row (سبق ذكره في إجابة أخرى).

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top