Bir sqlite veritabanını sorgularken neden bir imleç oluşturmanız gerekiyor?


133

Python'un sqlite3 modülünde (ve bu konuda genel olarak SQL) tamamen yeniyim ve bu beni tamamen şaşırtıyor. cursorNesnelerin tanımlarının bol miktarda olmaması (daha ziyade bunların gerekliliği) de tuhaf görünüyor.

Bu kod parçası, bir şeyler yapmanın tercih edilen yoludur:

import sqlite3
conn = sqlite3.connect("db.sqlite")
c = conn.cursor()
c.execute('''insert into table "users" values ("Jack Bauer", "555-555-5555")''')
conn.commit()
c.close()

Bu, aynı şekilde ve (görünüşte anlamsız) olmadan çalışmasına rağmen değil cursor:

import sqlite3
conn = sqlite3.connect("db.sqlite")
conn.execute('''insert into table "users" values ("Jack Bauer", "555-555-5555")''')
conn.commit()

Biri bana neden ihtiyacım olduğunu söyleyebilir cursormi?
Anlamsız ek yük gibi görünüyor. Komut dosyamdaki bir veritabanına erişen her yöntem için, bir cursor?
Neden sadece connectionnesneyi kullanmıyorsunuz ?

Yanıtlar:


60

Bana öyle geliyor ki sadece yanlış uygulanmış bir soyutlama. Bir db imleci, veri kümesi geçişi için kullanılan bir soyutlamadır.

Gönderen konuyla Vikipedi'ye :

Bilgisayar bilimi ve teknolojisinde, bir veritabanı imleci, bir veritabanındaki kayıtlar üzerinde geçiş yapılmasını sağlayan bir kontrol yapısıdır. İmleçler, veri tabanı kayıtlarının alınması, eklenmesi ve kaldırılması gibi geçişle birlikte sonraki işlemleri kolaylaştırır. Geçişin veritabanı imleci özelliği, imleçleri yineleyicinin programlama dili kavramına benzer hale getirir.

Ve:

İmleçler yalnızca DBMS'den bir uygulamaya veri almak için değil, aynı zamanda bir tablodaki güncellenecek veya silinecek bir satırı tanımlamak için de kullanılabilir. SQL: 2003 standardı, bu amaç için konumlandırılmış güncellemeyi ve konumlandırılmış silme SQL deyimlerini tanımlar. Bu tür ifadeler, yüklemlerle normal bir WHERE cümlesi kullanmaz. Bunun yerine, bir imleç satırı tanımlar. İmleç açılmalı ve FETCH ifadesi aracılığıyla bir satıra zaten yerleştirilmelidir.

Python sqlite modülündeki dokümanları kontrol ederseniz, cursorbir CREATE TABLEifade için bile bir python modülünün gerekli olduğunu görebilirsiniz , bu nedenle connectionOP tarafından doğru bir şekilde belirtildiği gibi , sadece bir nesnenin yeterli olması gereken durumlarda kullanılır . Bu tür bir soyutlama, insanların bir db imlecinin ne olduğunu anladığından ve dolayısıyla kullanıcılar açısından kafa karışıklığı / hayal kırıklığı olduğundan farklıdır. Verimlilikten bağımsız olarak, bu sadece kavramsal bir ek yük. Dokümanlarda python modülünün cursorbir imlecin SQL ve veritabanlarında olduğundan biraz farklı olduğu belirtilseydi iyi olurdu .


7
"Geleneksel" db imleçleri ile Python'da bir db için kullanılan imleçler arasındaki çok kafa karıştırıcı ayrımı (ilk başta) kabul etmek için +1
Paul Draper


38

Sonuçları almak için bir imleç nesnesine ihtiyacınız var. Örneğiniz işe yarıyor çünkü o bir INSERTve bu nedenle ondan herhangi bir satır geri almaya çalışmıyorsunuz, ancak sqlite3belgelere bakarsanız, .fetchXXXXbağlantı nesnelerinde herhangi bir yöntem olmadığını fark edeceksiniz , bu yüzden yapmaya çalıştıysanız a SELECTimleç olmadan elde edilen verileri almanın bir yolu olamaz.

İmleç nesneleri, hangi sonuç kümesinin hangisi olduğunu izlemenizi sağlar, çünkü ilkinin sonuçlarını almayı bitirmeden önce birden fazla sorgu çalıştırmanız mümkündür.


5
Ayrıca akılda tutmaya değer: PEP 249execute bir bağlantı nesnesi üzerinde tanımlamaz , bu bir sqlite3uzantıdır.
Cat Plus Plus

4
Hala SELECT deyimleriyle çalışır: pastebin.com/5ZbhfEn7 . Bağlantı nesnesinde herhangi bir .fetchXXXX yöntemini çağırmamanızın nedeni, bağlantının .execute () yöntemi tarafından döndürülen nesnede bir .fetchXXXX yöntemini çağırmanızdır.
Jack Bauer

1
Evet. Ancak veritabanını sorgulamak için (görünüşte) gereksiz bir imleci bulmanızın bir yolu: p
Jack Bauer

2
Muhtemelen şeyler nerede çalışmak gelecekteki projeler olacak çünkü Açıkça işaretleri kullanılarak, içine almak için iyi bir alışkanlıktır değil otomatik işlemek.
Amber

1
Yeterince adil. Bilgi için teşekkürler :)
Jack Bauer

36

Resmi göre dokümanlar connection.execute() bir olan standart olmayan kısayol bir ara imleç nesnesi oluşturur:

Connection.execute
Bu, cursor () yöntemini çağırarak bir imleç nesnesi oluşturan, verilen parametrelerle imlecin execute () yöntemini çağıran ve imleci döndüren standart olmayan bir kısayoldur.


19

12.6.8. Sqlite3 kullanma verimli ly

12.6.8.1. Kısayol yöntemlerini kullanma

Kullanılması standart dışı execute() , executemany()ve executescript()bağlantı nesnesi yöntemleri, kodunuzu yazılabilir daha özlü (genellikle oluşturmak gerekmez ly çünkü gereksiz İmleç nesneleri açıkça). Bunun yerine, İmleç nesneleri örtük olarak oluşturulur ve bu kısayol yöntemleri imleç nesnelerini döndürür. Bu şekilde, bir SELECT ifadesini çalıştırabilir ve Connection nesnesinde yalnızca tek bir çağrıyı kullanarak doğrudan üzerinde yineleyebilirsiniz.

( sqlite3 belgeleri ; vurgu benim.)

Neden sadece bağlantı nesnesini kullanmıyorsunuz?

Çünkü bağlantı nesnesinin bu yöntemleri standart değildir , yani Python Veritabanı API Spesifikasyonu v2.0'ın (PEP 249) parçası değildirler .

Cursor nesnesinin standart yöntemlerini kullandığınız sürece, yukarıdaki belirtimi izleyen başka bir veritabanı uygulamasına geçerseniz kodunuzun tamamen taşınabilir olacağından emin olabilirsiniz. Belki de sadece importçizgiyi değiştirmeniz gerekecek .

Ancak, kullanırsanız, connection.executegeçişin bu kadar kolay olmayacağı bir şans vardır. Bunun cursor.executeyerine kullanmak isteyebileceğiniz ana neden budur .

Ancak, geçiş yapmayacağınızdan eminseniz, connection.executekısayolu kullanmanın ve "verimli" olmanın tamamen sorun olmadığını söyleyebilirim .


1

Veritabanına aynı bağlantı üzerinden birden fazla ayrı çalışma ortamına sahip olma yeteneği sağlar.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.