আমি কীভাবে স্ক্লাইট কোয়েরি থেকে ডিক পেতে পারি?


118
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'}

নাকি আমাকে নিজেই করতে হবে?



3
@ ভি 32: এই প্রশ্নটি জুলাই ২০১০ থেকে, আপনি যেটির সাথে লিঙ্ক করেছেন সে হ'ল নভেম্বর ২০১০ So এবং যেমনটি আশা করা যায়, তার বিপরীতে মন্তব্যটি দেওয়া হয়েছে :-)
অ্যানেরয়েড

উত্তর:


158

দস্তাবেজের উদাহরণ হিসাবে আপনি সারি_ কারখানাটি ব্যবহার করতে পারেন :

import sqlite3

def dict_factory(cursor, row):
    d = {}
    for idx, col in enumerate(cursor.description):
        d[col[0]] = row[idx]
    return d

con = sqlite3.connect(":memory:")
con.row_factory = dict_factory
cur = con.cursor()
cur.execute("select 1 as a")
print cur.fetchone()["a"]

বা দস্তাবেজের এই উদাহরণের পরে দেওয়া পরামর্শ অনুসরণ করুন:

যদি কোনও টুপলে ফেরত দেওয়া পর্যাপ্ত না হয় এবং আপনি কলামগুলিতে নাম ভিত্তিক অ্যাক্সেস চান তবে আপনার সারি-ফ্যাক্টরিটিকে সর্বাধিক-অনুকূলকৃত স্ক্লাইট 3 এ সেট করা বিবেচনা করা উচিত ow রো টাইপ। সারিটি প্রায় কোনও মেমরির ওভারহেড ছাড়াই কলামগুলিতে সূচক ভিত্তিক এবং কেস-সংবেদনশীল নাম ভিত্তিক অ্যাক্সেস সরবরাহ করে। এটি সম্ভবত আপনার নিজস্ব কাস্টম অভিধান-ভিত্তিক পদ্ধতির বা এমনকি একটি db_row ভিত্তিক সমাধানের চেয়ে ভাল।


যদি আপনার কলামের নামগুলিতে বিশেষ অক্ষর থাকে SELECT 1 AS "dog[cat]"তবে cursorডিক তৈরির জন্য সঠিক বর্ণনাটি থাকবে না।
ক্রেজোমিটার

আমি সেট করেছি connection.row_factory = sqlite3.Rowএবং আমি connection.row_factory = dict_factoryপ্রদর্শিত হিসাবে চেষ্টা করেছি কিন্তু cur.fetchall()এখনও আমাকে টিপলগুলির একটি তালিকা দিচ্ছি - কোনও ধারণা কেন এটি কাজ করছে না?
ডিসপ্লে

@ ডিসপ্লে নাম, ডকুমেন্টেশনে বলা হয়নি "এটি এর বেশিরভাগ বৈশিষ্ট্যে একটি টিপলকে নকল করার চেষ্টা করে।" আমি প্রায় নিশ্চিত এটা একরকম আপনার কাছ থেকে পেতে পারেন কি অনুরূপ collections.namedtuple। আমি যখন ব্যবহার cur.fetchmany()করি তখন আমার মতো এন্ট্রি পাওয়া যায় <sqlite3.Row object at 0x...>
ony

এমনকি years বছর পরেও, এই উত্তরটি হ'ল আমি এসও-তে খুঁজে পাওয়া দস্তাবেজগুলির সর্বাধিক সহায়ক অনুলিপি এবং আটকানো। ধন্যবাদ!
উইলার্ডসোলিউশনগুলি

40

আমি ভেবেছিলাম আমি এই প্রশ্নের উত্তর দিচ্ছি যদিও উত্তরটি আংশিকভাবে অ্যাডাম শ্মিদেগ এবং অ্যালেক্স মার্তেলির উভয় জবাবের মধ্যে উল্লেখ করা হয়েছে। আমার মতো অন্যদের জন্য যাতে একই প্রশ্ন থাকে, উত্তরটি সহজেই সন্ধান করতে পারেন।

conn = sqlite3.connect(":memory:")

#This is the important part, here we are setting row_factory property of
#connection object to sqlite3.Row(sqlite3.Row is an implementation of
#row_factory)
conn.row_factory = sqlite3.Row
c = conn.cursor()
c.execute('select * from stocks')

result = c.fetchall()
#returns a list of dictionaries, each item in list(each dictionary)
#represents a row of the table

21
বর্তমানে অবজেক্টগুলি fetchall()প্রত্যাবর্তনের জন্য মনে হচ্ছে sqlite3.Row। তবে এইসব কেবল ব্যবহার করে একটি অভিধান পরিবর্তিত করা যায় dict(): result = [dict(row) for row in c.fetchall()]
গোনালো রিবেইরো

21

এমনকি sqlite3.Row বর্গ ব্যবহার করে - আপনি এখনও আকারে স্ট্রিং বিন্যাস ব্যবহার করতে পারবেন না:

print "%(id)i - %(name)s: %(value)s" % row

এটি পাস করার জন্য, আমি একটি সহায়ক ফাংশন ব্যবহার করি যা সারিটি নেয় এবং অভিধানে রূপান্তর করে। আমি কেবল তখনই এটি ব্যবহার করি যখন অভিধান অবজেক্টটি সারি অবজেক্টের চেয়ে পছন্দসই হয় (উদাহরণস্বরূপ স্ট্রিং ফর্ম্যাটিংয়ের মতো জিনিসগুলির ক্ষেত্রে যেখানে সারি অবজেক্ট মূলত অভিধান এপিআই সমর্থন করে না)। তবে অন্য সমস্ত সময় সারি বস্তুটি ব্যবহার করুন।

def dict_from_row(row):
    return dict(zip(row.keys(), row))       

9
sqlite3.Row ম্যাপিং প্রোটোকল প্রয়োগ করে। আপনি কেবল করতে পারেনprint "%(id)i - %(name)s: %(value)s" % dict(row)
Mzzzzzz

9

আপনি এসকিউএলাইটের সাথে সংযুক্ত হওয়ার পরে: con = sqlite3.connect(.....)এটি কেবল চালানোর জন্য যথেষ্ট:

con.row_factory = sqlite3.Row

ভাল খবর!


8

পিইপি 249 থেকে :

Question: 

   How can I construct a dictionary out of the tuples returned by
   .fetch*():

Answer:

   There are several existing tools available which provide
   helpers for this task. Most of them use the approach of using
   the column names defined in the cursor attribute .description
   as basis for the keys in the row dictionary.

   Note that the reason for not extending the DB API specification
   to also support dictionary return values for the .fetch*()
   methods is that this approach has several drawbacks:

   * Some databases don't support case-sensitive column names or
     auto-convert them to all lowercase or all uppercase
     characters.

   * Columns in the result set which are generated by the query
     (e.g.  using SQL functions) don't map to table column names
     and databases usually generate names for these columns in a
     very database specific way.

   As a result, accessing the columns through dictionary keys
   varies between databases and makes writing portable code
   impossible.

তাই হ্যাঁ, এটি নিজেই করুন।


> ডাটাবেসগুলির মধ্যে পরিবর্তিত হয় - স্কেলাইট 3.7 এবং 3.8 এর মতো কী?
নিউকুলার

@ ব্যবহারকারী1123466: ... এসকিউএলাইট, মাইএসকিউএল, পোস্টগ্রিস, ওরাকল, এমএস এসকিউএল সার্ভার, ফায়ারবার্ডের মধ্যে ...
ইগনাসিও ওয়াজকেজ-আব্রামস


3

আমার পরীক্ষাগুলিতে দ্রুততম:

conn.row_factory = lambda c, r: dict(zip([col[0] for col in c.description], r))
c = conn.cursor()

%timeit c.execute('SELECT * FROM table').fetchall()
19.8 µs ± 1.05 µs per loop (mean ± std. dev. of 7 runs, 100000 loops each)

বনাম:

conn.row_factory = lambda c, r: dict([(col[0], r[idx]) for idx, col in enumerate(c.description)])
c = conn.cursor()

%timeit c.execute('SELECT * FROM table').fetchall()
19.4 µs ± 75.6 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

তুমি ঠিক কর :)


2

@ গ্যান্ডালফের উত্তর দ্বারা উল্লিখিত হিসাবে, একটি ব্যবহার করতে হবে 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'}

1

পূর্বে উল্লিখিত সমাধানগুলির মতো, তবে সর্বাধিক কমপ্যাক্ট:

db.row_factory = lambda C, R: { c[0]: R[i] for i, c in enumerate(C.description) }

এটি আমার পক্ষে কাজ করেছিল, যেখানে উপরের উত্তরগুলি db.row_factory = sqlite3.Rowআমার পক্ষে কাজ করে না (এটি একটি জেএসএন টাইপআরারের ফলস্বরূপ)
ফিলিপ

1

আমি মনে করি আপনি সঠিক পথে ছিলেন আসুন এটি খুব সহজ রাখুন এবং আপনি যা করার চেষ্টা করছেন তা সম্পূর্ণ করুন:

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()যা আপনার স্মৃতিশক্তি গ্রহণের জন্য হত্যা , যদি আপনার টেবিলটি খুব বড় হয়। তবে তুচ্ছ অ্যাপ্লিকেশনগুলির জন্য কয়েক হাজার সারি পাঠ্য এবং সংখ্যাযুক্ত কলামগুলিতে ডিল করার জন্য, এই সাধারণ পদ্ধতির পক্ষে যথেষ্ট ভাল।

গুরুতর স্টাফগুলির জন্য, আপনার আরও অনেক উত্তরে প্রস্তাবিত হিসাবে সারি কারখানাগুলি সন্ধান করা উচিত।


0

অথবা আপনি sqlite3 রূপান্তর করতে পারেন। নীচে হিসাবে একটি অভিধানে Rows। এটি প্রতিটি সারির জন্য একটি তালিকা সহ একটি অভিধান দেবে।

    def from_sqlite_Row_to_dict(list_with_rows):
    ''' Turn a list with sqlite3.Row objects into a dictionary'''
    d ={} # the dictionary to be filled with the row data and to be returned

    for i, row in enumerate(list_with_rows): # iterate throw the sqlite3.Row objects            
        l = [] # for each Row use a separate list
        for col in range(0, len(row)): # copy over the row date (ie. column data) to a list
            l.append(row[col])
        d[i] = l # add the list to the dictionary   
    return d

0

একটি জেনেরিক বিকল্প, মাত্র তিনটি লাইন ব্যবহার করে

def select_column_and_value(db, sql, parameters=()):
    execute = db.execute(sql, parameters)
    fetch = execute.fetchone()
    return {k[0]: v for k, v in list(zip(execute.description, fetch))}

con = sqlite3.connect('/mydatabase.db')
c = con.cursor()
print(select_column_and_value(c, 'SELECT * FROM things WHERE id=?', (id,)))

তবে যদি আপনার কোয়েরিটি কিছু না ফেরায়, এর ফলে ত্রুটি হবে। এক্ষেত্রে...

def select_column_and_value(self, sql, parameters=()):
    execute = self.execute(sql, parameters)
    fetch = execute.fetchone()

    if fetch is None:
        return {k[0]: None for k in execute.description}

    return {k[0]: v for k, v in list(zip(execute.description, fetch))}

অথবা

def select_column_and_value(self, sql, parameters=()):
    execute = self.execute(sql, parameters)
    fetch = execute.fetchone()

    if fetch is None:
        return {}

    return {k[0]: v for k, v in list(zip(execute.description, fetch))}

0
import sqlite3

db = sqlite3.connect('mydatabase.db')
cursor = db.execute('SELECT * FROM students ORDER BY CREATE_AT')
studentList = cursor.fetchall()

columnNames = list(map(lambda x: x[0], cursor.description)) #students table column names list
studentsAssoc = {} #Assoc format is dictionary similarly


#THIS IS ASSOC PROCESS
for lineNumber, student in enumerate(studentList):
    studentsAssoc[lineNumber] = {}

    for columnNumber, value in enumerate(student):
        studentsAssoc[lineNumber][columnNames[columnNumber]] = value


print(studentsAssoc)

ফলাফল অবশ্যই সত্য, তবে আমি সবচেয়ে ভাল জানি না।


0

পাইথনের অভিধানগুলি তাদের উপাদানগুলিতে নির্বিচারে অ্যাক্সেস সরবরাহ করে। সুতরাং "নামগুলি" সহ যে কোনও অভিধান যদিও এটি একদিকে তথ্যমূলক হতে পারে (ক্ষেত্রের নামগুলি কী হয়) ক্ষেত্রগুলিকে "আন-অর্ডার" দেয়, যা অযাচিত হতে পারে।

সেরা পদ্ধতির নাম হল একটি পৃথক তালিকায় নাম পাওয়া এবং তারপরে প্রয়োজনীয়তার সাথে সেগুলি নিজের সাথে ফলাফলের সাথে একত্রিত করা।

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(ইতিমধ্যে অন্য উত্তরে বর্ণিত)।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.