GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | ||||||||||||||||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | ||||||||||||||||||||||||||||||||||||||||
GeezerVison is showing python.github.io — sqlite3 --- رابط DB-API 2.0 برای پایگاههای داده SQLite
|
حالت نخبندی SQLite |
معنای DB-API 2.0 |
||
|---|---|---|---|
تکنخی |
0 |
0 |
نخها نمیتوانند ماژول را به اشتراک بگذارند |
چندنخی |
1 |
۲ |
نخها میتوانند ماژول را به اشتراک بگذارند، اما اتصالها را نه |
سریالشده |
۳ |
1 |
نخها میتوانند ماژول، اتصالها و نشانگرها را به اشتراک بگذارند |
تغییر یافته در نسخهی 3.11: بهجای سختکد کردن آن روی 1، threadsafety را بهصورت پویا تنظیم کنید.
این ثابتها برای متدهای Connection.setconfig() و getconfig() استفاده میشوند.
دسترسپذیری این ثابتها بسته به نسخهی SQLite که پایتون با آن کامپایل شده است، متفاوت است.
اضافه شده در نسخهی 3.12.
همچنین ببینید
مستندات SQLite: گزینههای پیکربندی اتصال پایگاه داده
منسوخ شده از نسخهی 3.12، در نسخهی 3.14 حذف شده است: ثابتهای version و version_info.
هر پایگاه دادهی باز SQLite با یک شیء Connection نمایش داده میشود، که با استفاده از sqlite3.connect() ایجاد میشود. هدف اصلی آنها ایجاد اشیای Cursor و کنترل تراکنش است.
تغییر یافته در نسخهی 3.13: اگر close() پیش از حذف یک شیء Connection فراخوانی نشود، یک ResourceWarning نشان داده میشود.
اتصال پایگاه دادهی SQLite دارای ویژگیها و متدهای زیر است:
یک شیء Cursor را ایجاد کرده و برمیگرداند. متد cursor یک پارامتر اختیاری واحد به نام factory میپذیرد. در صورت ارائه، این باید یک callable باشد که نمونهای از Cursor یا زیرکلاسهای آن را برمیگرداند.
یک دستهی Blob به یک BLOB موجود باز کنید.
table (str) -- نام جدولی که blob در آن قرار دارد.
column (str) -- نام ستونی که blob در آن قرار دارد.
rowid (int) -- شناسهی ردیفی که blob در آن قرار دارد.
readonly (bool) -- اگر قرار باشد blob بدون اجازههای نوشتن باز شود، روی True تنظیم شود. پیشفرض آن False است.
name (str) -- نام پایگاه دادهای که بلاب (blob) در آن قرار دارد. بهطور پیشفرض "main" است.
OperationalError -- هنگام تلاش برای باز کردن یک بلاب در جدول WITHOUT ROWID.
نکته
اندازهی blob را نمیتوان با استفاده از کلاس Blob تغییر داد. برای ایجاد یک blob با اندازهی ثابت، از تابع SQL zeroblob استفاده کنید.
اضافه شده در نسخهی 3.11.
هر تراکنش در انتظار را در پایگاه داده ثبت میکند. اگر autocommit برابر True باشد، یا هیچ تراکنش بازی وجود نداشته باشد، این متد هیچ کاری انجام نمیدهد. اگر autocommit برابر False باشد، چنانچه تراکنش در انتظاری توسط این متد ثبت شود، تراکنش جدیدی بهطور ضمنی باز میشود.
به آغاز هر تراکنش در حال انتظار عقبگرد میکند. اگر autocommit برابر True باشد، یا هیچ تراکنش بازی وجود نداشته باشد، این متد هیچ کاری انجام نمیدهد. اگر autocommit برابر False باشد، در صورتی که یک تراکنش در حال انتظار توسط این متد عقبگرد شده باشد، تراکنش جدیدی بهطور ضمنی باز میشود.
اتصال به پایگاه داده را ببندید. اگر autocommit برابر False باشد، هر تراکنش در انتظاری بهصورت ضمنی بازگردانده میشود. اگر autocommit برابر True یا LEGACY_TRANSACTION_CONTROL باشد، هیچ کنترل تراکنشی بهصورت ضمنی اعمال نمیشود. برای جلوگیری از دست رفتن تغییرات در انتظار، اطمینان حاصل کنید که پیش از بستن، commit() را فراخوانی کنید.
یک شیء Cursor جدید ایجاد میکند و execute() را با sql و parameters دادهشده روی آن فراخوانی میکند. شیء نشانگر جدید را برمیگرداند.
یک شیء Cursor جدید ایجاد کنید و executemany() را با sql و parameters دادهشده روی آن فراخوانی کنید. شیء نشانگر جدید را برگردانید.
یک شیء Cursor جدید ایجاد میکند و executescript() را با sql_script دادهشده روی آن فراخوانی میکند. شیء نشانگر جدید را برمیگرداند.
ایجاد یا حذف یک تابع SQL تعریفشده توسط کاربر.
name (str) -- نام تابع SQL.
narg (int) -- تعداد آرگومانهایی که تابع SQL میتواند بپذیرد. اگر -1 باشد، میتواند هر تعداد آرگومان بگیرد.
func (callback | None) -- یک فراخوانیپذیر است که هنگام فراخوانی تابع SQL فراخوانده میشود. این فراخوانیپذیر باید نوعی که SQLite بهصورت بومی از آن پشتیبانی میکند را برگرداند. برای حذف یک تابع SQL موجود، آن را روی None تنظیم کنید.
deterministic (bool) -- اگر True باشد، تابع SQL ایجادشده بهعنوان قطعی (deterministic) علامتگذاری میشود، که به SQLite امکان میدهد بهینهسازیهای بیشتری انجام دهد.
تغییر یافته در نسخهی 3.8: پارامتر deterministic افزوده شد.
تغییر یافته در نسخهی 3.15: سه پارامتر اول اکنون فقط جایگاهی هستند.
مثال:
>>> import hashlib >>> def md5sum(t): ... return hashlib.md5(t).hexdigest() >>> con = sqlite3.connect(":memory:") >>> con.create_function("md5", 1, md5sum) >>> for row in con.execute("SELECT md5(?)", (b"foo",)): ... print(row) ('acbd18db4cc2f85cedef654fccc4a4d8',) >>> con.close()
ایجاد یا حذف یک تابع تجمیعی SQL تعریفشده توسط کاربر.
name (str) -- نام تابع تجمعی SQL.
n_arg (int) -- تعداد آرگومانهایی که تابع تجمیعی SQL میتواند بپذیرد. اگر -1 باشد، ممکن است هر تعداد آرگومان را بپذیرد.
aggregate_class (class | None) -- یک کلاس باید متدهای زیر را پیادهسازی کند: * step(): یک ردیف را به تجمیع اضافه میکند. * finalize(): نتیجه نهایی تجمیع را بهعنوان نوعی که بهصورت بومی توسط SQLite پشتیبانی میشود برمیگرداند. تعداد آرگومانهایی که متد step() باید بپذیرد، با n_arg کنترل میشود. برای حذف یک تابع تجمیعی SQL موجود، آن را روی None تنظیم کنید.
تغییر یافته در نسخهی 3.15: هر سه پارامتر اکنون فقط جایگاهی هستند.
مثال:
class MySum: def __init__(self): self.count = 0 def step(self, value): self.count += value def finalize(self): return self.count con = sqlite3.connect(":memory:") con.create_aggregate("mysum", 1, MySum) cur = con.execute("CREATE TABLE test(i)") cur.execute("INSERT INTO test(i) VALUES(1)") cur.execute("INSERT INTO test(i) VALUES(2)") cur.execute("SELECT mysum(i) FROM test") print(cur.fetchone()[0]) con.close()
ایجاد یا حذف یک تابع پنجرهای تجمیعی تعریفشده توسط کاربر.
name (str) -- نام تابع پنجرهای تجمیعی SQL برای ایجاد یا حذف.
num_params (int) -- تعداد آرگومانهایی که تابع تجمیعی پنجرهای SQL میتواند بپذیرد. اگر -1 باشد، میتواند هر تعداد آرگومان بگیرد.
aggregate_class (class | None) -- کلاسی که باید متدهای زیر را پیادهسازی کند: * step(): افزودن یک ردیف به پنجره جاری. * value(): برگرداندن مقدار فعلی تجمیع. * inverse(): حذف یک ردیف از پنجره جاری. * finalize(): برگرداندن نتیجه نهایی تجمیع بهعنوان نوعی که SQLite بهصورت بومی از آن پشتیبانی میکند. تعداد آرگومانهایی که متدهای step() و value() باید بپذیرند، با num_params کنترل میشود. برای حذف یک تابع پنجرهای تجمیعی SQL موجود، آن را روی None تنظیم کنید.
NotSupportedError -- اگر با نسخهای از SQLite قدیمیتر از 3.25.0 استفاده شود، که از توابع پنجرهای تجمیعی پشتیبانی نمیکند.
اضافه شده در نسخهی 3.11.
مثال:
# Example taken from https://www.sqlite.org/windowfunctions.html#udfwinfunc class WindowSumInt: def __init__(self): self.count = 0 def step(self, value): """Add a row to the current window.""" self.count += value def value(self): """Return the current value of the aggregate.""" return self.count def inverse(self, value): """Remove a row from the current window.""" self.count -= value def finalize(self): """Return the final value of the aggregate. Any clean-up actions should be placed here. """ return self.count con = sqlite3.connect(":memory:") cur = con.execute("CREATE TABLE test(x, y)") values = [ ("a", 4), ("b", 5), ("c", 3), ("d", 8), ("e", 1), ] cur.executemany("INSERT INTO test VALUES(?, ?)", values) con.create_window_function("sumint", 1, WindowSumInt) cur.execute(""" SELECT x, sumint(y) OVER ( ORDER BY x ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING ) AS sum_y FROM test ORDER BY x """) print(cur.fetchall()) con.close()
یک ترتیبگذاری (collation) به نام name با استفاده از تابع مقایسهکننده callable ایجاد کنید. callable دو آرگومان از نوع رشته دریافت میکند و باید یک عدد صحیح برگرداند:
1 اگر مورد اول بالاتر از مورد دوم مرتب شده باشد
-1 اگر اولی از نظر ترتیب، پایینتر از دومی باشد
0 اگر از نظر ترتیب برابر باشند
مثال زیر یک ترتیبگذاری (collation) مرتبسازی معکوس را نشان میدهد:
def collate_reverse(string1, string2): if string1 == string2: return 0 elif string1 < string2: return 1 else: return -1 con = sqlite3.connect(":memory:") con.create_collation("reverse", collate_reverse) cur = con.execute("CREATE TABLE test(x)") cur.executemany("INSERT INTO test(x) VALUES(?)", [("a",), ("b",)]) cur.execute("SELECT x FROM test ORDER BY x COLLATE reverse") for row in cur: print(row) con.close()
برای حذف یک تابع ترتیبگذاری (collation)، callable را روی None تنظیم کنید.
تغییر یافته در نسخهی 3.11: نام ترتیبگذاری (collation) میتواند شامل هر نویسهای از Unicode باشد. پیشتر، فقط نویسههای ASCII مجاز بودند.
این متد را از یک نخ دیگر فراخوانی کنید تا هر پرسوجویی که ممکن است روی اتصال در حال اجرا باشد، لغو شود. پرسوجوهای لغوشده یک OperationalError پرتاب خواهند کرد.
authorizer_callback، یک فراخوانیپذیر، را ثبت کنید تا برای هر تلاش برای دسترسی به یک ستون از یک جدول در پایگاه داده فراخوانی شود. این کالبک باید یکی از SQLITE_OK، SQLITE_DENY یا SQLITE_IGNORE را برگرداند تا مشخص کند دسترسی به ستون باید توسط کتابخانه زیربنایی SQLite چگونه مدیریت شود.
نخستین آرگومان کالبک نشان میدهد که چه نوع عملیاتی باید مجاز شود. آرگومان دوم و سوم، بسته به آرگومان نخست، یا آرگومانهایی خواهند بود یا None. آرگومان چهارم در صورت لزوم، نام پایگاه داده ("main"، "temp" و غیره) است. آرگومان پنجم نام درونیترین تریگر یا ویویی است که مسئول تلاش برای دسترسی است، یا None اگر این تلاش برای دسترسی مستقیماً از کد SQL ورودی باشد.
لطفاً مستندات SQLite را دربارهی مقادیر ممکن برای آرگومان اول و معنی آرگومان دوم و سوم، بسته به آرگومان اول، ببینید. همهی ثابتهای مورد نیاز در ماژول sqlite3 در دسترس هستند.
با ارسال None بهعنوان authorizer_callback، تأییدکنندهی دسترسی غیرفعال میشود.
تغییر یافته در نسخهی 3.11: پشتیبانی از غیرفعالسازی مجوزدهنده (authorizer) با استفاده از None افزوده شد.
تغییر یافته در نسخهی 3.15: تنها پارامتر اکنون فقط جایگاهی است.
callable progress_handler را ثبت کنید تا به ازای هر n دستورالعملِ ماشین مجازی SQLite فراخوانی شود. این قابلیت زمانی مفید است که بخواهید در حین عملیاتهای طولانیمدت از SQLite فراخوانی شوید، برای مثال برای بهروزرسانی رابط کاربری گرافیکی (GUI).
اگر میخواهید هر مدیر پیشرفت (progress handler) نصبشدهی قبلی را پاک کنید، متد را با None برای progress_handler فراخوانی کنید.
بازگرداندن یک مقدار غیرصفر از تابع هندلر، پرسوجوی در حال اجرا را خاتمه میدهد و باعث میشود که یک استثنا DatabaseError پرتاب شود.
تغییر یافته در نسخهی 3.15: پارامتر اول اکنون فقط جایگاهی است.
یک callable به نام trace_callback را ثبت کنید تا برای هر دستور SQL که بهطور واقعی توسط بکاند SQLite اجرا میشود، فراخوانی شود.
تنها آرگومانی که به کالبک داده میشود، دستور در حال اجرا (بهصورت str) است. مقدار بازگشتی کالبک نادیده گرفته میشود. توجه داشته باشید که بکاند تنها دستورهایی را که به متدهای Cursor.execute() دادهشدهاند، اجرا نمیکند. منابع دیگر شامل مدیریت تراکنش ماژول sqlite3 و اجرای ماشههای تعریفشده در پایگاه دادهی جاری هستند.
با ارسال None بهعنوان trace_callback، کالبک ردگیری غیرفعال میشود.
نکته
استثناهای پرتابشده در کالبک ردگیری منتشر نمیشوند. بهعنوان کمکی برای توسعه و اشکالزدایی، از enable_callback_tracebacks() برای فعال کردن چاپ ردگیریهای پشتهی استثناهای پرتابشده در کالبک ردگیری استفاده کنید.
اضافه شده در نسخهی 3.3.
تغییر یافته در نسخهی 3.15: پارامتر اول اکنون فقط جایگاهی است.
اگر enabled برابر True باشد، به موتور SQLite اجازه میدهد تا افزونههای SQLite را از کتابخانههای مشترک بارگذاری کند؛ در غیر این صورت، بارگذاری افزونههای SQLite را مجاز نمیداند. افزونههای SQLite میتوانند توابع جدید، تجمیعها یا پیادهسازیهای کاملاً جدید جدول مجازی را تعریف کنند. یکی از افزونههای شناختهشده، افزونه جستجوی تماممتنی (fulltext-search) است که همراه SQLite توزیع شده است.
نکته
ماژول sqlite3 بهطور پیشفرض با پشتیبانی از افزونههای قابل بارگذاری ساخته نمیشود، زیرا برخی سکوها (بهویژه macOS) کتابخانههای SQLite دارند که بدون این قابلیت کامپایل شدهاند. برای بهرهمندی از پشتیبانی از افزونههای قابل بارگذاری، باید گزینهی --enable-loadable-sqlite-extensions را به configure بدهید.
یک رویداد حسابرسی sqlite3.enable_load_extension را با آرگومانهای connection و enabled پرتاب میکند.
اضافه شده در نسخهی 3.2.
تغییر یافته در نسخهی 3.10: رویداد حسابرسی sqlite3.enable_load_extension اضافه شد.
con.enable_load_extension(True) # Load the fulltext search extension con.execute("select load_extension('./fts3.so')") # alternatively you can load the extension using an API call: # con.load_extension("./fts3.so") # disable extension loading again con.enable_load_extension(False) # example from SQLite wiki con.execute("CREATE VIRTUAL TABLE recipe USING fts3(name, ingredients)") con.executescript(""" INSERT INTO recipe (name, ingredients) VALUES('broccoli stew', 'broccoli peppers cheese tomatoes'); INSERT INTO recipe (name, ingredients) VALUES('pumpkin stew', 'pumpkin onions garlic celery'); INSERT INTO recipe (name, ingredients) VALUES('broccoli pie', 'broccoli cheese onions flour'); INSERT INTO recipe (name, ingredients) VALUES('pumpkin pie', 'pumpkin sugar flour butter'); """) for row in con.execute("SELECT rowid, name, ingredients FROM recipe WHERE name MATCH 'pie'"): print(row)
یک افزونهی SQLite را از یک کتابخانه مشترک بارگذاری کنید. پیش از فراخوانی این متد، بارگذاری افزونه را با enable_load_extension() فعال کنید.
path (str) -- مسیر افزونهی SQLite.
entrypoint (str | None) -- نام نقطه ورود. اگر None (پیشفرض) باشد، SQLite نام نقطه ورود خاص خود را انتخاب میکند؛ برای جزئیات، مستندات SQLite با عنوان Loading an Extension را ببینید.
یک رویداد حسابرسی sqlite3.load_extension را با آرگومانهای connection و path پرتاب میکند.
اضافه شده در نسخهی 3.2.
تغییر یافته در نسخهی 3.10: رویداد حسابرسی sqlite3.load_extension افزوده شد.
تغییر یافته در نسخهی 3.12: پارامتر entrypoint اضافه شد.
یک iterator برای برونریزی پایگاه داده بهصورت کد منبع SQL برمیگرداند. هنگام ذخیرهی یک پایگاه دادهی درونحافظهای برای بازیابی بعدی مفید است. مشابه دستور .dump در پوستهی sqlite3 است.
filter (str | None) -- یک الگوی LIKE اختیاری برای اشیای پایگاه دادهای که باید برونریزی شوند، بهعنوان مثال prefix_%. اگر None (پیشفرض) باشد، تمام اشیای پایگاه داده گنجانده میشوند.
مثال:
# Convert file example.db to SQL dump file dump.sql con = sqlite3.connect('example.db') with open('dump.sql', 'w') as f: for line in con.iterdump(): f.write('%s\n' % line) con.close()
همچنین ببینید
تغییر یافته در نسخهی 3.13: پارامتر filter اضافه شد.
یک نسخه پشتیبان از پایگاهداده SQLite ایجاد کنید.
حتی اگر پایگاه داده توسط کلاینتهای دیگر یا بهصورت همزمان توسط همان اتصال در حال دسترسی باشد، باز هم کار میکند.
target (Connection) -- اتصال پایگاه دادهای که نسخه پشتیبان در آن ذخیره میشود.
pages (int) -- تعداد صفحههایی که در هر نوبت کپی میشوند. اگر برابر یا کمتر از 0 باشد، کل پایگاه داده در یک مرحله کپی میشود. مقدار پیشفرض آن -1 است.
progress (callback | None) -- اگر به یک callable تنظیم شود، در هر تکرار پشتیبانگیری با سه آرگومان عدد صحیحی فراخوانی میشود: وضعیت آخرین تکرار، تعداد صفحات باقیمانده که هنوز باید کپی شوند و تعداد کل صفحات. مقدار پیشفرض آن None است.
name (str) -- نام پایگاه دادهای که از آن پشتیبانگیری میشود. یا "main" (پیشفرض) برای پایگاه داده اصلی، "temp" برای پایگاه داده موقت، یا نام یک پایگاه داده سفارشی که با دستور SQL ATTACH DATABASE متصل شده است.
sleep (float) -- تعداد ثانیههای توقف بین تلاشهای متوالی برای پشتیبانگیری صفحههای باقیمانده.
مثال ۱، کپی کردن یک پایگاه دادهی موجود به پایگاه دادهای دیگر:
def progress(status, remaining, total): print(f'Copied {total-remaining} of {total} pages...') src = sqlite3.connect('example.db') dst = sqlite3.connect('backup.db') with dst: src.backup(dst, pages=1, progress=progress) dst.close() src.close()
مثال ۲، کپی یک پایگاه دادهی موجود به یک کپی گذرا:
src = sqlite3.connect('example.db') dst = sqlite3.connect(':memory:') src.backup(dst) dst.close() src.close()
اضافه شده در نسخهی 3.7.
همچنین ببینید
محدودیت رانتایم یک اتصال را دریافت کنید.
category (int) -- SQLite limit category که باید پرسوجو شود.
ProgrammingError -- اگر category توسط کتابخانه SQLite زیربنایی شناسایی نشود.
مثال، حداکثر طول یک دستور SQL را برای Connection con پرسوجو کنید (مقدار پیشفرض ۱۰۰۰۰۰۰۰۰۰ است):
>>> con.getlimit(sqlite3.SQLITE_LIMIT_SQL_LENGTH) 1000000000
اضافه شده در نسخهی 3.11.
یک محدودیت رانتایم اتصال را تنظیم میکند. اگر تلاش شود محدودیتی به بالاتر از کران بالایی سخت خود افزایش یابد، بدون هیچ پیامی به کران بالایی سخت تقلیل مییابد. صرفنظر از اینکه محدودیت تغییر کرده باشد یا خیر، مقدار پیشین محدودیت برگردانده میشود.
category (int) -- SQLite limit category که باید تنظیم شود.
limit (int) -- مقدار محدودیت جدید. اگر منفی باشد، محدودیت فعلی بدون تغییر میماند.
ProgrammingError -- اگر category توسط کتابخانه SQLite زیربنایی شناسایی نشود.
مثال، تعداد پایگاههای دادهی پیوستشده را برای Connection con به ۱ محدود کنید (محدودیت پیشفرض ۱۰ است):
>>> con.setlimit(sqlite3.SQLITE_LIMIT_ATTACHED, 1) 10 >>> con.getlimit(sqlite3.SQLITE_LIMIT_ATTACHED) 1
اضافه شده در نسخهی 3.11.
یک گزینهی پیکربندی اتصال بولی را پرسوجو کنید.
op (int) -- یک کد SQLITE_DBCONFIG.
اضافه شده در نسخهی 3.12.
یک گزینهی پیکربندی اتصال از نوع بولی را تنظیم کنید.
op (int) -- یک کد SQLITE_DBCONFIG.
enable (bool) -- True اگر گزینهی پیکربندی باید فعال باشد (پیشفرض)؛ False اگر باید غیرفعال باشد.
اضافه شده در نسخهی 3.12.
یک پایگاه داده را به یک شیء bytes سریالسازی میکند. برای یک پرونده پایگاه دادهی معمولی روی دیسک، سریالسازی صرفاً رونوشتی از پرونده دیسک است. برای یک پایگاه دادهی درونحافظهای یا یک پایگاه دادهی "temp"، سریالسازی همان دنبالهای از بایتها است که اگر آن پایگاه داده روی دیسک پشتیبانگیری میشد، روی دیسک نوشته میشد.
name (str) -- نام پایگاه دادهای که باید سریالسازی شود. پیشفرض "main" است.
نکته
این متد فقط در صورتی در دسترس است که کتابخانه SQLite زیرین، دارای API سریالسازی (serialize) باشد.
اضافه شده در نسخهی 3.11.
یک پایگاه دادهی سریالسازیشده را به یک Connection از سریالسازی خارج کنید. این متد موجب میشود اتصال پایگاه داده از پایگاه دادهی name قطع شود و name بهعنوان یک پایگاه دادهی درونحافظهای بر اساس سریالسازی موجود در data بازگشایی شود.
OperationalError -- اگر اتصال پایگاه داده در حال حاضر درگیر یک تراکنش خواندن یا یک عملیات پشتیبانگیری باشد.
DatabaseError -- اگر data شامل یک پایگاه داده SQLite معتبر نباشد.
OverflowError -- اگر len(data) بزرگتر از 2**63 - 1 باشد.
نکته
این متد تنها در صورتی در دسترس است که کتابخانه SQLite زیرین دارای API سریالزدایی کردن (deserialize) باشد.
اضافه شده در نسخهی 3.11.
این ویژگی رفتار تراکنش مطابق با PEP 249 را کنترل میکند. autocommit سه مقدار مجاز دارد:
False: رفتار تراکنشی مطابق PEP 249 را انتخاب میکند، به این معنا که sqlite3 تضمین میکند یک تراکنش همیشه باز است. برای بستن تراکنشها از commit() و rollback() استفاده کنید.
این مقدار توصیهشده برای autocommit است.
True: از autocommit mode SQLite استفاده کنید. در این حالت، commit() و rollback() هیچ تأثیری ندارند.
LEGACY_TRANSACTION_CONTROL: کنترل تراکنش پیش از پایتون 3.12 (ناسازگار با PEP 249). برای جزئیات بیشتر isolation_level را ببینید.
این در حال حاضر مقدار پیشفرض autocommit است.
تغییر autocommit به False یک تراکنش جدید را باز میکند، و تغییر آن به True هر تراکنش در انتظار را ثبت (commit) میکند.
برای جزئیات بیشتر به کنترل تراکنش از طریق ویژگی autocommit مراجعه کنید.
نکته
ویژگی isolation_level تأثیری ندارد، مگر اینکه autocommit برابر LEGACY_TRANSACTION_CONTROL باشد.
اضافه شده در نسخهی 3.12.
این ویژگی فقطخواندنی، متناظر با حالت autocommit mode سطح پایین در SQLite است.
اگر یک تراکنش فعال باشد (تغییرات ثبتنشدهای وجود داشته باشد)، True و در غیر این صورت False است.
اضافه شده در نسخهی 3.2.
حالت مدیریت تراکنش قدیمی در sqlite3 را کنترل میکند. اگر روی None تنظیم شود، تراکنشها هرگز بهصورت ضمنی باز نمیشوند. اگر روی یکی از "DEFERRED"، "IMMEDIATE" یا "EXCLUSIVE" تنظیم شود، مطابق با SQLite transaction behaviour زیربنایی، مدیریت ضمنی تراکنش انجام میشود.
اگر پارامتر isolation_level در connect() آن را بازنویسی نکند، مقدار پیشفرض "" است که نام مستعاری برای "DEFERRED" محسوب میشود.
نکته
استفاده از autocommit برای کنترل مدیریت تراکنش، بهجای استفاده از isolation_level توصیه میشود. isolation_level هیچ تأثیری ندارد، مگر اینکه autocommit روی LEGACY_TRANSACTION_CONTROL (پیشفرض) تنظیم شده باشد.
row_factory اولیه برای اشیای Cursor ایجادشده از این اتصال. انتساب به این ویژگی بر row_factory نشانگرهای موجود متعلق به این اتصال تأثیری نمیگذارد و فقط نشانگرهای جدید را تحت تأثیر قرار میدهد. بهطور پیشفرض None است، به این معنا که هر ردیف بهصورت یک tuple بازگردانده میشود.
برای جزئیات بیشتر نحوهی ایجاد و استفاده از کارخانههای ردیف (row factories) را ببینید.
تغییر یافته در نسخهی 3.15: حذف ویژگی row_factory دیگر مجاز نیست.
یک callable که یک پارامتر از نوع bytes را میپذیرد و یک نمایش متنی از آن را برمیگرداند. این callable برای مقادیر SQLite با نوع داده TEXT فراخوانی میشود. بهطور پیشفرض، این ویژگی روی str تنظیم شده است.
برای جزئیات بیشتر نحوهی مدیریت کدگذاریهای متن غیر UTF-8 را ببینید.
تغییر یافته در نسخهی 3.15: حذف ویژگی text_factory دیگر مجاز نیست.
تعداد کل ردیفهای پایگاه داده را که از زمان باز شدن اتصال پایگاه داده تغییریافته، درجشده یا حذفشدهاند، برمیگرداند.
یک شیء
Cursorنشاندهندهی یک database cursor است که برای اجرای دستورات SQL و مدیریت زمینهی یک عملیات واکشی استفاده میشود. نشانگرها با استفاده ازConnection.cursor()، یا با استفاده از هر یک از متدهای میانبر اتصال ایجاد میشوند.اشیاء Cursor از نوع پیمایشگر هستند، به این معنا که اگر یک پرسوجوی
SELECTراexecute()کنید، میتوانید برای واکشی ردیفهای حاصل، بهسادگی روی نشانگر پیمایش کنید:for row in cur.execute("SELECT t FROM data"): print(row)
یک نمونه Cursor دارای ویژگیها و متدهای زیر است.
یک دستور SQL واحد را اجرا کنید و بهصورت اختیاری مقادیر پایتون را با استفاده از جاینگهدارها مقید کنید.
sql (str) -- یک دستور SQL واحد.
parameters (dict | sequence) -- مقادیر پایتون برای مقیدسازی به جاینگهدارها در sql. در صورت استفاده از جاینگهدارهای نامدار، یک dict. در صورت استفاده از جاینگهدارهای بینام، یک sequence. چگونه از جاینگهدارها (placeholders) برای مقیدسازی مقادیر در پرسوجوهای SQL استفاده کنیم را ببینید.
ProgrammingError -- هنگامی که sql شامل بیش از یک دستور SQL باشد. هنگامی که از جاینگهدارهای نامگذاریشده استفاده میشود و parameters بهجای یک dict یک دنباله باشد.
اگر autocommit برابر LEGACY_TRANSACTION_CONTROL باشد، isolation_level برابر None نباشد، sql یک دستور INSERT، UPDATE، DELETE یا REPLACE باشد و هیچ تراکنش بازی وجود نداشته باشد، پیش از اجرای sql، یک تراکنش بهطور ضمنی باز میشود.
تغییر یافته در نسخهی 3.14: ProgrammingError پرتاب میشود، اگر از جاینگهدارهای نامدار استفاده شود و parameters بهجای یک dict یک دنباله باشد.
برای اجرای چندین دستور SQL از executescript() استفاده کنید.
به ازای هر آیتم در parameters، دستور SQL DML (زبان دستکاری دادهها) <DML (Data Manipulation Language)> پارامتریزه sql را بهطور مکرر اجرا کنید.
از همان مدیریت تراکنش ضمنیِ execute() استفاده میکند.
sql (str) -- یک دستور SQL DML.
parameters (iterable) -- یک iterable از پارامترها برای مقیدسازی با جاینگهدارها در sql. چگونه از جاینگهدارها (placeholders) برای مقیدسازی مقادیر در پرسوجوهای SQL استفاده کنیم را ببینید.
ProgrammingError -- هنگامی که sql شامل بیش از یک دستور SQL باشد یا یک دستور DML نباشد، هنگامی که از جاینگهدارهای نامگذاریشده استفاده شود و آیتمهای parameters به جای dicts دنباله باشند.
مثال:
rows = [ ("row1",), ("row2",), ] # cur is an sqlite3.Cursor object cur.executemany("INSERT INTO data VALUES(?)", rows)
نکته
هر ردیف حاصل دور ریخته میشود، از جمله در دستورات DML با RETURNING clauses.
تغییر یافته در نسخهی 3.14: اگر از جاینگهدارهای نامدار استفاده شود و آیتمهای درون parameters بهجای dicts دنباله باشند، ProgrammingError پرتاب میشود.
دستورات SQL موجود در sql_script را اجرا کنید. اگر autocommit برابر LEGACY_TRANSACTION_CONTROL باشد و یک تراکنش در انتظار وجود داشته باشد، ابتدا یک دستور COMMIT ضمنی اجرا میشود. هیچگونه کنترل تراکنش ضمنی دیگری انجام نمیشود؛ هرگونه کنترل تراکنش باید به sql_script اضافه شود.
sql_script باید یک رشته باشد.
مثال:
# cur is an sqlite3.Cursor object cur.executescript(""" BEGIN; CREATE TABLE person(firstname, lastname, age); CREATE TABLE book(title, author, published); CREATE TABLE publisher(name, address); COMMIT; """)
اگر row_factory None باشد، ردیف بعدی از مجموعهی نتایج پرسوجو را بهصورت یک tuple برمیگرداند. در غیر این صورت، آن را به کارخانهی ردیف (row factory) میدهد و نتیجهی آن را برمیگرداند. اگر دادهی بیشتری در دسترس نباشد، None را برمیگرداند.
برگرداندن دستهی بعدی از ردیفهای نتیجهی یک پرسوجو بهعنوان یک list. اگر دیگر ردیفی در دسترس نباشد، یک فهرست خالی برمیگرداند.
تعداد ردیفهایی که در هر فراخوانی واکشی میشوند، با پارامتر size مشخص میشود. اگر size داده نشود، arraysize تعداد ردیفهای واکشیشده را تعیین میکند. اگر کمتر از size ردیف در دسترس باشد، هر تعداد ردیفی که در دسترس باشد بازگردانده میشود.
توجه داشته باشید که ملاحظات عملکردی مرتبط با پارامتر size وجود دارد. برای عملکرد بهینه، معمولاً بهتر است از ویژگی arraysize استفاده کنید. اگر از پارامتر size استفاده میشود، بهتر است مقدار آن از یک فراخوانی fetchmany() تا فراخوانی بعدی ثابت بماند.
تغییر یافته در نسخهی 3.15: مقادیر منفی size با پرتاب ValueError رد میشوند.
تمام ردیفهای (باقیمانده) نتیجهی پرسوجو را بهصورت یک list برمیگرداند. اگر هیچ ردیفی موجود نباشد، یک فهرست خالی برمیگرداند. توجه داشته باشید که ویژگی arraysize میتواند بر عملکرد این عملیات تأثیر بگذارد.
اکنون نشانگر را ببندید (نه هر زمان که __del__ فراخوانی میشود).
از این نقطه به بعد، نشانگر غیرقابل استفاده خواهد بود؛ در صورت تلاش برای انجام هر عملیاتی با نشانگر، استثنای ProgrammingError پرتاب خواهد شد.
مورد نیاز DB-API است. در sqlite3 هیچ کاری انجام نمیدهد.
مورد نیاز DB-API است. در sqlite3 هیچ کاری انجام نمیدهد.
ویژگی خواندنی/نوشتنی که تعداد ردیفهای بازگرداندهشده توسط fetchmany() را کنترل میکند. مقدار پیشفرض ۱ است، یعنی در هر فراخوانی یک ردیف واکشی میشود.
تغییر یافته در نسخهی 3.15: مقادیر منفی با پرتاب ValueError رد میشوند.
ویژگی فقطخواندنی که Connection پایگاه دادهی SQLite متعلق به نشانگر را فراهم میکند. یک شیء Cursor که با فراخوانی con.cursor() ایجاد شده باشد، ویژگی connection خواهد داشت که به con ارجاع میدهد:
>>> con = sqlite3.connect(":memory:") >>> cur = con.cursor() >>> cur.connection == con True >>> con.close()
ویژگی فقطخواندنی که نام ستونهای آخرین پرسوجو را ارائه میدهد. برای حفظ سازگاری با Python DB API، برای هر ستون یک تاپل ۷تایی بازمیگرداند که شش آیتم پایانی هر تاپل None هستند.
این ویژگی برای دستورهای SELECT که هیچ ردیف منطبقی ندارند نیز تنظیم میشود.
ویژگی فقطخواندنی که شناسهی آخرین ردیف درجشده را فراهم میکند. این ویژگی فقط پس از دستورهای موفق INSERT یا REPLACE با استفاده از متد execute() بهروزرسانی میشود. برای دستورهای دیگر، پس از executemany() یا executescript()، یا اگر درج ناموفق باشد، مقدار lastrowid بدون تغییر باقی میماند. مقدار اولیهی lastrowid برابر None است.
نکته
درجها در جدولهای WITHOUT ROWID ثبت نمیشوند.
تغییر یافته در نسخهی 3.6: پشتیبانی از دستور REPLACE افزوده شد.
ویژگی فقطخواندنی که تعداد ردیفهای تغییرکرده توسط دستورهای INSERT، UPDATE، DELETE و REPLACE را ارائه میدهد؛ برای سایر دستورها، از جمله پرسوجوهای CTE، -1 است. این ویژگی فقط توسط متدهای execute() و executemany()، پس از اجرای کامل دستور بهروزرسانی میشود. این بدان معناست که برای بهروزرسانی rowcount باید همه ردیفهای حاصل واکشی شوند.
چگونگی بازنمایی ردیفی را که از این Cursor واکشی میشود، کنترل میکند. اگر None باشد، یک ردیف بهصورت یک tuple بازنمایی میشود. میتوان آن را روی sqlite3.Row ارائهشده تنظیم کرد؛ یا روی یک callable که دو آرگومان میپذیرد، یک شیء Cursor و tuple مقدارهای ردیف، و یک شیء سفارشی را بازمیگرداند که یک ردیف SQLite را بازنمایی میکند.
بهطور پیشفرض برابر مقداری است که Connection.row_factory هنگام ایجاد Cursor روی آن تنظیم شده است. انتساب به این ویژگی بر Connection.row_factory اتصال والد تأثیری نمیگذارد.
برای جزئیات بیشتر نحوهی ایجاد و استفاده از کارخانههای ردیف (row factories) را ببینید.
تغییر یافته در نسخهی 3.15: حذف ویژگی row_factory دیگر مجاز نیست.
نمونهای از Row بهعنوان یک row_factory بسیار بهینهشده برای اشیای Connection عمل میکند. این نمونه از تکرار، آزمون برابری، len() و دسترسی بهصورت mapping از طریق نام و اندیس ستون پشتیبانی میکند.
دو شیء Row زمانی برابر مقایسه میشوند که نامها و مقادیر ستونهای یکسانی داشته باشند.
برای جزئیات بیشتر نحوهی ایجاد و استفاده از کارخانههای ردیف (row factories) را ببینید.
یک list از نام ستونها بهصورت strings برمیگرداند. بلافاصله پس از یک پرسوجو، اولین عضو هر تاپل در Cursor.description است.
تغییر یافته در نسخهی 3.5: پشتیبانی از اسلایس افزوده شد.
اضافه شده در نسخهی 3.11.
یک نمونه از Blob یک شیء شبهپرونده است که میتواند دادهها را در یک BLOB مربوط به SQLite بخواند و بنویسد. برای دریافت اندازهی blob (یعنی تعداد بایتهای آن)، len(blob) را فراخوانی کنید. برای دسترسی مستقیم به دادههای blob، از اندیسها و اسلایسها استفاده کنید.
از Blob بهعنوان یک context manager استفاده کنید تا اطمینان حاصل شود که دستهی blob پس از استفاده بسته میشود.
con = sqlite3.connect(":memory:") con.execute("CREATE TABLE test(blob_col blob)") con.execute("INSERT INTO test(blob_col) VALUES(zeroblob(13))") # Write to our blob, using two write operations: with con.blobopen("test", "blob_col", 1) as blob: blob.write(b"hello, ") blob.write(b"world.") # Modify the first and last bytes of our blob blob[0] = ord("H") blob[-1] = ord("!") # Read the contents of our blob with con.blobopen("test", "blob_col", 1) as blob: greeting = blob.read() print(greeting) # outputs "b'Hello, world!'" con.close()
بلاب را ببندید.
این blob از این نقطه به بعد غیرقابل استفاده خواهد بود. در صورت تلاش برای انجام هر عملیات دیگری با blob، یک استثنای Error (یا زیرکلاس آن) پرتاب خواهد شد.
length بایت داده از بلاب در موقعیت فعلی آفست خوانده میشود. اگر به انتهای بلاب رسیده شود، داده تا EOF بازگردانده میشود. هنگامی که length مشخص نشده باشد یا منفی باشد، read() تا انتهای بلاب میخواند.
data را در آفست فعلی بلاب بنویسید. این تابع نمیتواند طول بلاب را تغییر دهد. نوشتن فراتر از انتهای بلاب باعث پرتاب ValueError میشود.
موقعیت دسترسی جاری بلاب را برمیگرداند.
موقعیت دسترسی فعلی بلاب را روی offset تنظیم میکند. آرگومان origin بهطور پیشفرض os.SEEK_SET (موقعیتدهی مطلق بلاب) است. مقادیر دیگر برای origin عبارتاند از os.SEEK_CUR (جابهجایی نسبت به موقعیت فعلی) و os.SEEK_END (جابهجایی نسبت به انتهای بلاب).
تنها هدف نوع PrepareProtocol این است که بهعنوان یک پروتکل تطبیق به سبک PEP 246 برای اشیایی عمل کند که میتوانند خود را وفق دهند به انواع ذاتی SQLite.
سلسلهمراتب استثنا توسط DB-API 2.0 تعریف شده است (PEP 249).
این استثنا در حال حاضر توسط ماژول sqlite3 پرتاب نمیشود، اما ممکن است توسط برنامههایی که از sqlite3 استفاده میکنند پرتاب شود، برای مثال اگر یک تابع تعریفشده توسط کاربر هنگام درج، دادهها را کوتاه کند. Warning زیرکلاسی از Exception است.
کلاس پایهی سایر استثناهای این ماژول. از این برای گرفتن همهی خطاها با یک دستور except واحد استفاده کنید. Error یک زیرکلاس از Exception است.
اگر استثنا از درون کتابخانه SQLite سرچشمه گرفته باشد، دو ویژگی زیر به استثنا اضافه میشوند:
کد خطای عددی از SQLite API
اضافه شده در نسخهی 3.11.
نام نمادینِ کد خطای عددی از SQLite API
اضافه شده در نسخهی 3.11.
استثنایی که برای استفادهی نادرست از API سطح پایین C در SQLite پرتاب میشود. به عبارت دیگر، اگر این استثنا پرتاب شد، احتمالاً نشاندهندهی یک خطا در ماژول sqlite3 است. InterfaceError زیرکلاسی از Error است.
استثنایی که برای خطاهای مرتبط با پایگاه داده پرتاب میشود. این استثنا بهعنوان استثنای پایه برای چندین نوع از خطاهای پایگاه داده عمل میکند. این استثنا تنها بهطور ضمنی از طریق زیرکلاسهای تخصصی پرتاب میشود. DatabaseError یک زیرکلاس از Error است.
استثنایی که برای خطاهای ناشی از مشکلات در دادههای پردازششده، مانند مقادیر عددی خارج از محدوده و رشتههایی که بیش از حد طولانی هستند، پرتاب میشود. DataError زیرکلاسی از DatabaseError است.
استثنایی که برای خطاهایی پرتاب میشود که به عملیات پایگاه داده مرتبط هستند و لزوماً تحت کنترل برنامهنویس نیستند. برای مثال، مسیر پایگاه داده پیدا نشود یا تراکنشی قابل پردازش نباشد. OperationalError زیرکلاسی از DatabaseError است.
استثنایی که هنگامی پرتاب میشود که یکپارچگی رابطهای پایگاه داده تحت تأثیر قرار بگیرد، برای مثال وقتی بررسی کلید خارجی ناموفق باشد. این استثنا یک زیرکلاس از DatabaseError است.
استثنایی که هنگام بروز خطای داخلی در SQLite پرتاب میشود. اگر این استثنا پرتاب شود، ممکن است نشاندهندهی وجود مشکل در کتابخانهی رانتایم SQLite باشد. InternalError زیرکلاسی از DatabaseError است.
استثنایی که برای خطاهای برنامهنویسی در API sqlite3 پرتاب میشود، برای مثال ارائه تعداد نادرست مقیدسازیها به یک کوئری، یا تلاش برای انجام عملیات روی یک Connection بسته. ProgrammingError زیرکلاسی از DatabaseError است.
استثنایی که در صورتی پرتاب میشود که یک متد یا API پایگاه داده توسط کتابخانه SQLite زیرین پشتیبانی نشود. برای مثال، تنظیم deterministic روی True در create_function()، در صورتی که کتابخانه SQLite زیرین از توابع قطعی پشتیبانی نکند. NotSupportedError زیرکلاسی از DatabaseError است.
SQLite بهصورت بومی از انواع زیر پشتیبانی میکند: NULL، INTEGER، REAL، TEXT، BLOB.
بنابراین میتوان انواع پایتون زیر را بدون هیچ مشکلی به SQLite ارسال کرد:
نوع پایتون |
نوع SQLite |
|---|---|
|
|
|
|
|
|
|
|
|
انواع SQLite بهصورت پیشفرض اینگونه به انواع پایتون تبدیل میشوند:
نوع SQLite |
نوع پایتون |
|---|---|
|
|
|
|
|
|
|
به |
|
سیستم نوع ماژول sqlite3 به ۲ روش قابلگسترش است: شما میتوانید انواع اضافی پایتون را از طریق آداپتورهای شیء (object adapters) در یک پایگاهدادهی SQLite ذخیره کنید، و میتوانید به ماژول sqlite3 اجازه دهید تا انواع SQLite را از طریق مبدلها (converters) به انواع پایتون تبدیل کند.
نکته
آداپتورها و مبدلهای پیشفرض از پایتون 3.12 منسوخ شدهاند. در عوض، از دستورپختهای آداپتور و مبدل استفاده کنید و آنها را متناسب با نیازهای خود تنظیم کنید.
آداپتورها و مبدلهای پیشفرض منسوخشده عبارتاند از:
آداپتوری برای تبدیل اشیای datetime.date به strings در قالب ISO 8601.
یک آداپتور (adapter) برای تبدیل اشیای datetime.datetime به رشتههایی در قالب ISO 8601.
مبدلی برای تبدیل انواع "date" اعلامشده به اشیای datetime.date.
مبدلی برای تبدیل انواع «timestamp» اعلامشده به اشیای datetime.datetime. بخشهای کسری به ۶ رقم کوتاه میشوند (دقت میکروثانیه).
نکته
مبدل پیشفرض "timestamp" انحرافهای UTC را در پایگاه داده نادیده میگیرد و همیشه یک شیء datetime.datetime ساده برمیگرداند. برای حفظ انحرافهای UTC در timestampها، یا مبدلها را غیرفعال نگه دارید، یا یک مبدل آگاه از انحراف را با register_converter() ثبت کنید.
منسوخ شده از نسخهی 3.12.
میتوان ماژول sqlite3 را بهعنوان یک اسکریپت، با استفاده از سوییچ -m مفسر، فراخوانی کرد تا یک پوسته ساده SQLite فراهم شود. امضای آرگومان به صورت زیر است:
python -m sqlite3 [-h] [-v] [filename] [sql]
برای خروج از پوسته، .quit یا CTRL-D را وارد کنید.
چاپ راهنمای CLI.
نسخهی کتابخانهی SQLite زیرین را چاپ میکند.
اضافه شده در نسخهی 3.12.
عملیاتهای SQL معمولاً به استفاده از مقادیر متغیرهای پایتون نیاز دارند. با این حال، از استفاده از عملیات رشتهای پایتون برای ساخت پرسوجوها برحذر باشید، زیرا در برابر حملات تزریق SQL آسیبپذیرند. برای مثال، یک مهاجم میتواند بهسادگی علامت نقلقول تکی را ببندد و OR TRUE را تزریق کند تا تمام ردیفها انتخاب شوند:
>>> # Never do this -- insecure! >>> symbol = input() ' OR TRUE; -- >>> sql = "SELECT * FROM stocks WHERE symbol = '%s'" % symbol >>> print(sql) SELECT * FROM stocks WHERE symbol = '' OR TRUE; --' >>> cur.execute(sql)
در عوض، از جایگزینی پارامترِ DB-API استفاده کنید. برای درج یک متغیر در رشتهی پرسوجو، از یک جاینگهدار در رشته استفاده کنید و مقادیر واقعی را با ارائه آنها بهصورت یک tuple از مقادیر به آرگومان دوم متد execute() نشانگر، در پرسوجو جایگزین کنید.
یک دستور SQL ممکن است از یکی از دو نوع جاینگهدار استفاده کند: علامتهای سؤال (سبک qmark) یا جاینگهدارهای نامدار (سبک named). برای سبک qmark، parameters باید یک sequence باشد که طول آن باید با تعداد جاینگهدارها برابر باشد، در غیر این صورت یک ProgrammingError پرتاب میشود. برای سبک named، parameters باید نمونهای از dict (یا یک زیرکلاس) باشد که باید شامل کلیدهایی برای همهی پارامترهای نامدار باشد؛ هر آیتم اضافی نادیده گرفته میشود. در ادامه مثالی از هر دو سبک آمده است:
con = sqlite3.connect(":memory:") cur = con.execute("CREATE TABLE lang(name, first_appeared)") # This is the named style used with executemany(): data = ( {"name": "C", "year": 1972}, {"name": "Fortran", "year": 1957}, {"name": "Python", "year": 1991}, {"name": "Go", "year": 2009}, ) cur.executemany("INSERT INTO lang VALUES(:name, :year)", data) # This is the qmark style used in a SELECT query: params = (1972,) cur.execute("SELECT * FROM lang WHERE first_appeared = ?", params) print(cur.fetchall()) con.close()
نکته
از جاینگهدارهای عددی PEP 249 پشتیبانی نمیشود. در صورت استفاده، بهعنوان جاینگهدارهای نامدار تفسیر خواهند شد.
SQLite تنها از مجموعهای محدود از انواع داده بهصورت بومی پشتیبانی میکند. برای ذخیرهی انواع پایتونی سفارشی در پایگاههای دادهی SQLite، آنها را با یکی از انواع پایتونی که SQLite بهصورت بومی میشناسد سازگار کنید.
دو روش برای تطبیق اشیای پایتون با انواع SQLite وجود دارد: اینکه بگذارید شیء شما خودش را تطبیق دهد، یا استفاده از یک فراخوانیپذیر تطبیقدهنده (adapter callable). دومی بر اولی تقدم خواهد داشت. برای کتابخانهای که یک نوع سفارشی اکسپورت میکند، ممکن است منطقی باشد که آن نوع بتواند خودش را تطبیق دهد. بهعنوان توسعهدهندهی برنامهی کاربردی، ممکن است منطقیتر باشد که با ثبت توابع تطبیقدهندهی سفارشی، کنترل مستقیم را در دست بگیرید.
فرض کنید یک کلاس Point داریم که یک جفت مختصات، x و y، را در یک دستگاه مختصات دکارتی نشان میدهد. جفت مختصات بهصورت یک رشته متنی در پایگاه داده ذخیره خواهد شد و برای جداسازی مختصات از نقطهویرگول استفاده میشود. این کار را میتوان با افزودن یک متد __conform__(self, protocol) پیادهسازی کرد که مقدار تطبیقیافته را برمیگرداند. شیء منتقلشده به protocol از نوع PrepareProtocol خواهد بود.
class Point: def __init__(self, x, y): self.x, self.y = x, y def __conform__(self, protocol): if protocol is sqlite3.PrepareProtocol: return f"{self.x};{self.y}" con = sqlite3.connect(":memory:") cur = con.cursor() cur.execute("SELECT ?", (Point(4.0, -3.2),)) print(cur.fetchone()[0]) con.close()
امکان دیگر، ساخت تابعی است که شیء پایتون را به نوعی سازگار با SQLite تبدیل میکند. سپس میتوانید این تابع را با استفاده از register_adapter() ثبت کنید.
class Point: def __init__(self, x, y): self.x, self.y = x, y def adapt_point(point): return f"{point.x};{point.y}" sqlite3.register_adapter(Point, adapt_point) con = sqlite3.connect(":memory:") cur = con.cursor() cur.execute("SELECT ?", (Point(1.0, 2.5),)) print(cur.fetchone()[0]) con.close()
نوشتن یک آداپتور امکان تبدیل از انواع سفارشی پایتون به مقادیر SQLite را به شما میدهد. برای توانایی تبدیل از مقادیر SQLite به انواع سفارشی پایتون، از مبدلها استفاده میکنیم.
بیایید به کلاس Point بازگردیم. ما مختصات x و y را بهصورت رشتههایی که با نقطهویرگول از یکدیگر جدا شدهاند، در SQLite ذخیره کردیم.
ابتدا، یک تابع تبدیلکننده تعریف میکنیم که رشته را بهعنوان پارامتر میپذیرد و از روی آن یک شیء Point میسازد.
نکته
توابع مبدل همیشه یک شیء bytes دریافت میکنند، صرفنظر از نوع دادهی زیرین SQLite.
def convert_point(s): x, y = map(float, s.split(b";")) return Point(x, y)
اکنون باید به sqlite3 بگوییم که چه زمانی باید یک مقدار SQLite مشخص را تبدیل کند. این کار هنگام اتصال به یک پایگاه داده، با استفاده از پارامتر detect_types تابع connect() انجام میشود. سه گزینه وجود دارد:
ضمنی: detect_types را روی PARSE_DECLTYPES تنظیم کنید
صریح: detect_types را روی PARSE_COLNAMES تنظیم کنید
هر دو: detect_types را روی sqlite3.PARSE_DECLTYPES | sqlite3.PARSE_COLNAMES تنظیم کنید. نام ستونها بر انواع اعلامشده اولویت دارند.
مثال زیر رویکردهای ضمنی و صریح را نشان میدهد:
class Point: def __init__(self, x, y): self.x, self.y = x, y def __repr__(self): return f"Point({self.x}, {self.y})" def adapt_point(point): return f"{point.x};{point.y}" def convert_point(s): x, y = list(map(float, s.split(b";"))) return Point(x, y) # Register the adapter and converter sqlite3.register_adapter(Point, adapt_point) sqlite3.register_converter("point", convert_point) # 1) Parse using declared types p = Point(4.0, -3.2) con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_DECLTYPES) cur = con.execute("CREATE TABLE test(p point)") cur.execute("INSERT INTO test(p) VALUES(?)", (p,)) cur.execute("SELECT p FROM test") print("with declared types:", cur.fetchone()[0]) cur.close() con.close() # 2) Parse using column names con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_COLNAMES) cur = con.execute("CREATE TABLE test(p)") cur.execute("INSERT INTO test(p) VALUES(?)", (p,)) cur.execute('SELECT p AS "p [point]" FROM test') print("with column names:", cur.fetchone()[0]) cur.close() con.close()
این بخش دستورالعملهایی برای آداپتورها و مبدلهای رایج ارائه میدهد.
import datetime as dt import sqlite3 def adapt_date_iso(val): """Adapt datetime.date to ISO 8601 date.""" return val.isoformat() def adapt_datetime_iso(val): """Adapt datetime.datetime to timezone-naive ISO 8601 date.""" return val.replace(tzinfo=None).isoformat() def adapt_datetime_epoch(val): """Adapt datetime.datetime to Unix timestamp.""" return int(val.timestamp()) sqlite3.register_adapter(dt.date, adapt_date_iso) sqlite3.register_adapter(dt.datetime, adapt_datetime_iso) sqlite3.register_adapter(dt.datetime, adapt_datetime_epoch) def convert_date(val): """Convert ISO 8601 date to datetime.date object.""" return dt.date.fromisoformat(val.decode()) def convert_datetime(val): """Convert ISO 8601 datetime to datetime.datetime object.""" return dt.datetime.fromisoformat(val.decode()) def convert_timestamp(val): """Convert Unix epoch timestamp to datetime.datetime object.""" return dt.datetime.fromtimestamp(int(val)) sqlite3.register_converter("date", convert_date) sqlite3.register_converter("datetime", convert_datetime) sqlite3.register_converter("timestamp", convert_timestamp)
با استفاده از متدهای execute()، executemany() و executescript() کلاس Connection، میتوانید کد خود را مختصرتر بنویسید، زیرا نیازی نیست اشیای Cursor را (که اغلب غیرضروری هستند) بهصورت صریح ایجاد کنید. در عوض، اشیای Cursor بهصورت ضمنی ایجاد میشوند و این متدهای میانبر اشیای cursor را برمیگردانند. به این ترتیب، میتوانید یک دستور SELECT را اجرا کرده و تنها با یک فراخوانی روی شیء Connection، مستقیماً آن را پیمایش کنید.
# Create and fill the table. con = sqlite3.connect(":memory:") con.execute("CREATE TABLE lang(name, first_appeared)") data = [ ("C++", 1985), ("Objective-C", 1984), ] con.executemany("INSERT INTO lang(name, first_appeared) VALUES(?, ?)", data) # Print the table contents for row in con.execute("SELECT name, first_appeared FROM lang"): print(row) print("I just deleted", con.execute("DELETE FROM lang").rowcount, "rows") # close() is not a shortcut method and it's not called automatically; # the connection object should be closed manually con.close()
یک شیء Connection میتواند بهعنوان یک مدیر زمینه استفاده شود که هنگام خروج از بدنهی مدیر زمینه، تراکنشهای باز را بهطور خودکار ثبت یا بازگردانی میکند. اگر بدنهی دستور with بدون استثنا به پایان برسد، تراکنش ثبت میشود. اگر این ثبت ناموفق باشد، یا اگر بدنهی دستور with یک استثنای گرفتهنشده پرتاب کند، تراکنش بازگردانی میشود. اگر autocommit برابر False باشد، پس از ثبت یا بازگردانی، یک تراکنش جدید بهطور ضمنی باز میشود.
اگر هنگام خروج از بدنهی دستور with هیچ تراکنش بازی وجود نداشته باشد، یا اگر autocommit برابر True باشد، مدیر زمینه هیچ کاری انجام نمیدهد.
نکته
این مدیر زمینه نه بهطور ضمنی تراکنش جدیدی را باز میکند و نه اتصال را میبندد. اگر به یک مدیر زمینه برای بستن نیاز دارید، استفاده از contextlib.closing() را در نظر بگیرید.
con = sqlite3.connect(":memory:") con.execute("CREATE TABLE lang(id INTEGER PRIMARY KEY, name VARCHAR UNIQUE)") # Successful, con.commit() is called automatically afterwards with con: con.execute("INSERT INTO lang(name) VALUES(?)", ("Python",)) # con.rollback() is called after the with block finishes with an exception, # the exception is still raised and must be caught try: with con: con.execute("INSERT INTO lang(name) VALUES(?)", ("Python",)) except sqlite3.IntegrityError: print("couldn't add Python twice") # Connection object used as context manager only commits or rollbacks transactions, # so the connection object should be closed manually con.close()
برخی ترفندهای مفید URI عبارتند از:
باز کردن یک پایگاه داده در حالت فقطخواندنی:
>>> con = sqlite3.connect("file:tutorial.db?mode=ro", uri=True) >>> con.execute("CREATE TABLE readonly(data)") Traceback (most recent call last): OperationalError: attempt to write a readonly database >>> con.close()
اگر پرونده پایگاه داده جدید از قبل وجود نداشته باشد، بهطور ضمنی یک پرونده پایگاه داده جدید ایجاد نمیشود؛ اگر امکان ایجاد پرونده جدید وجود نداشته باشد، OperationalError پرتاب میشود:
>>> con = sqlite3.connect("file:nosuchdb.db?mode=rw", uri=True) Traceback (most recent call last): OperationalError: unable to open database file
ایجاد یک پایگاه دادهی درونحافظهای نامدار مشترک:
db = "file:mem1?mode=memory&cache=shared" con1 = sqlite3.connect(db, uri=True) con2 = sqlite3.connect(db, uri=True) with con1: con1.execute("CREATE TABLE shared(data)") con1.execute("INSERT INTO shared VALUES(28)") res = con2.execute("SELECT data FROM shared") assert res.fetchone() == (28,) con1.close() con2.close()
اطلاعات بیشتر درباره این قابلیت، از جمله فهرستی از پارامترها، در SQLite URI documentation یافت میشود.
بهطور پیشفرض، sqlite3 هر ردیف را بهصورت یک tuple نمایش میدهد. اگر یک tuple نیاز شما را برآورده نمیکند، میتوانید از کلاس sqlite3.Row یا یک row_factory سفارشی استفاده کنید.
اگرچه row_factory بهعنوان یک ویژگی هم در Cursor و هم در Connection وجود دارد، توصیه میشود Connection.row_factory را تنظیم کنید تا تمام نشانگرهایی که از اتصال ایجاد میشوند از همان کارخانهی ردیف (row factory) استفاده کنند.
Row دسترسی اندیسی و دسترسی نامی بدون حساسیت به بزرگی و کوچکی حروف به ستونها را با حداقل سربار حافظه و تأثیر بر عملکرد نسبت به یک tuple فراهم میکند. برای استفاده از Row بهعنوان کارخانهی ردیف (row factory)، آن را به ویژگی row_factory انتساب دهید:
>>> con = sqlite3.connect(":memory:") >>> con.row_factory = sqlite3.Row
پرسوجوها اکنون اشیای Row را برمیگردانند:
>>> res = con.execute("SELECT 'Earth' AS name, 6378 AS radius") >>> row = res.fetchone() >>> row.keys() ['name', 'radius'] >>> row[0] # Access by index. 'Earth' >>> row["name"] # Access by name. 'Earth' >>> row["RADIUS"] # Column names are case-insensitive. 6378 >>> con.close()
نکته
میتوان بند FROM را در دستور SELECT حذف کرد، همانطور که در مثال بالا آمده است. در این موارد، SQLite یک ردیف واحد با ستونهای تعریفشده توسط عبارتها، برای مثال مقادیر لفظی، با نامهای مستعار دادهشده به صورت expr AS alias برمیگرداند.
شما میتوانید یک row_factory سفارشی ایجاد کنید که هر ردیف را بهصورت یک dict برمیگرداند، بهطوری که نام ستونها به مقادیر نگاشته شدهاند:
def dict_factory(cursor, row): fields = [column[0] for column in cursor.description] return {key: value for key, value in zip(fields, row)}
با استفاده از آن، پرسوجوها اکنون یک dict بهجای یک tuple برمیگردانند:
>>> con = sqlite3.connect(":memory:") >>> con.row_factory = dict_factory >>> for row in con.execute("SELECT 1 AS a, 2 AS b"): ... print(row) {'a': 1, 'b': 2} >>> con.close()
کارخانه ردیف (row factory) زیر یک named tuple برمیگرداند:
from collections import namedtuple def namedtuple_factory(cursor, row): fields = [column[0] for column in cursor.description] cls = namedtuple("Row", fields) return cls._make(row)
میتوان از namedtuple_factory() بهصورت زیر استفاده کرد:
>>> con = sqlite3.connect(":memory:") >>> con.row_factory = namedtuple_factory >>> cur = con.execute("SELECT 1 AS a, 2 AS b") >>> row = cur.fetchone() >>> row Row(a=1, b=2) >>> row[0] # Indexed access. 1 >>> row.b # Attribute access. 2 >>> con.close()
با برخی تنظیمات، میتوان دستور بالا را برای استفاده از یک dataclass یا هر کلاس سفارشی دیگری، بهجای یک namedtuple تطبیق داد.
بهطور پیشفرض، sqlite3 از str برای تطبیق مقادیر SQLite با نوع داده TEXT استفاده میکند. این روش برای متنهای کدگذاریشده با UTF-8 بهخوبی کار میکند، اما ممکن است برای کدگذاریهای دیگر و UTF-8 نامعتبر شکست بخورد. میتوانید از یک text_factory سفارشی برای رسیدگی به چنین مواردی استفاده کنید.
به دلیل flexible typing در SQLite، مواجه شدن با ستونهای جدول با نوع داده TEXT که شامل کدگذاریهای غیر UTF-8 یا حتی دادههای دلخواه هستند، چندان غیرمعمول نیست. برای نمایش، فرض کنیم پایگاه دادهای با متن کدگذاریشده بهصورت ISO-8859-2 (Latin-2) داریم، برای مثال جدولی از ورودیهای فرهنگ لغت چکی-انگلیسی. با فرض اینکه اکنون یک نمونه Connection به نام con داریم که به این پایگاه داده متصل است، میتوانیم متن کدگذاریشده با Latin-2 را با استفاده از این text_factory کدگشایی کنیم:
con.text_factory = lambda data: str(data, encoding="latin2")
برای UTF-8 نامعتبر یا دادههای دلخواه ذخیرهشده در ستونهای جدول TEXT، میتوانید از روش زیر استفاده کنید، که از راهنمای عملی یونیکد وام گرفته شده است:
con.text_factory = lambda data: str(data, errors="surrogateescape")
نکته
API ماژول sqlite3 از رشتههای حاوی نویسههای جانشین (surrogates) پشتیبانی نمیکند.
همچنین ببینید
sqlite3 روشهای متعددی برای کنترل اینکه آیا، چه زمانی و چگونه تراکنشهای پایگاه داده باز و بسته میشوند، ارائه میدهد. کنترل تراکنش از طریق ویژگی autocommit توصیه میشود، در حالی که کنترل تراکنش از طریق ویژگی isolation_level رفتار پیش از Python 3.12 را حفظ میکند.
autocommit¶روش توصیهشده برای کنترل رفتار تراکنش، از طریق ویژگی Connection.autocommit است که بهتر است با پارامتر autocommit در connect() تنظیم شود.
پیشنهاد میشود autocommit را روی False تنظیم کنید، که به معنای کنترل تراکنش مطابق PEP 249 است. این یعنی:
sqlite3 تضمین میکند که یک تراکنش همیشه باز است، بنابراین connect()، Connection.commit() و Connection.rollback() بهطور ضمنی یک تراکنش جدید باز میکنند (بلافاصله پس از بستن تراکنش در انتظار، برای دو مورد آخر). sqlite3 هنگام باز کردن تراکنشها از دستورات BEGIN DEFERRED استفاده میکند.
تراکنشها باید بهصورت صریح با استفاده از commit() کامیت شوند.
تراکنشها باید بهصراحت با استفاده از rollback() بازگردانی شوند.
اگر پایگاه داده در حالی که تغییرات در انتظار دارد با close() بسته شود، یک بازگردانی (rollback) ضمنی انجام میشود.
برای فعالسازی autocommit mode در SQLite، autocommit را روی True تنظیم کنید. در این حالت، Connection.commit() و Connection.rollback() هیچ اثری ندارند. توجه داشته باشید که حالت autocommit در SQLite از ویژگی Connection.autocommit سازگار با PEP 249 متمایز است؛ برای پرسوجوی حالت autocommit سطح پایین SQLite از Connection.in_transaction استفاده کنید.
برای اینکه رفتار کنترل تراکنش به ویژگی Connection.isolation_level واگذار شود، autocommit را روی LEGACY_TRANSACTION_CONTROL تنظیم کنید. برای اطلاعات بیشتر کنترل تراکنش از طریق ویژگی isolation_level را ببینید.
isolation_level¶نکته
روش توصیهشده برای کنترل تراکنشها، استفاده از ویژگی autocommit است. کنترل تراکنش از طریق ویژگی autocommit را ببینید.
اگر Connection.autocommit روی LEGACY_TRANSACTION_CONTROL (پیشفرض) تنظیم شده باشد، رفتار تراکنش با استفاده از ویژگی Connection.isolation_level کنترل میشود. در غیر این صورت، isolation_level اثری ندارد.
اگر ویژگی اتصال isolation_level برابر None نباشد، پیش از اجرای دستورات INSERT، UPDATE، DELETE یا REPLACE توسط execute() و executemany()، تراکنشهای جدید بهطور ضمنی باز میشوند؛ برای سایر دستورات، هیچ مدیریت تراکنش ضمنیای انجام نمیشود. از متدهای commit() و rollback() بهترتیب برای ثبت (commit) و بازگرداندن (rollback) تراکنشهای در انتظار استفاده کنید. شما میتوانید رفتار زیربنایی SQLite transaction behaviour — یعنی اینکه آیا و چه نوع دستورات BEGIN توسط sqlite3 بهطور ضمنی اجرا میشوند – را از طریق ویژگی isolation_level انتخاب کنید.
اگر isolation_level روی None تنظیم شده باشد، اصلاً هیچ تراکنشی بهطور ضمنی باز نمیشود. این امر باعث میشود کتابخانه SQLite زیرین در autocommit mode باقی بماند، اما همچنین به کاربر اجازه میدهد مدیریت تراکنش خود را با استفاده از دستورات صریح SQL انجام دهد. حالت کامیت خودکار کتابخانه SQLite زیرین را میتوان از طریق ویژگی in_transaction پرسوجو کرد.
متد executescript() بهطور ضمنی هر تراکنش در حال انتظاری را پیش از اجرای اسکریپت SQL دادهشده، صرفنظر از مقدار isolation_level، ثبت (commit) میکند.
تغییر یافته در نسخهی 3.6: sqlite3 پیشتر یک تراکنش باز را پیش از دستورات DDL بهصورت ضمنی ثبت (commit) میکرد. این موضوع دیگر صدق نمیکند.
تغییر یافته در نسخهی 3.12: روش توصیهشده برای کنترل تراکنشها اکنون از طریق ویژگی autocommit است.