از طریق منوی جستجو مطلب مورد نظر خود در وبلاگ را به سرعت پیدا کنید
راهنمای استفاده از موتور جنگو MongoDB با پایتون
سرفصلهای مطلب
معرفی
در این مقاله خواهیم دید که چگونه می توان از MongoDB ، یک پایگاه داده غیر مرتبط ، با Django ، یک چارچوب وب پایتون استفاده کرد.
Django معمولاً با PostgreSQL، MariaDB یا MySQL، همه پایگاههای داده رابطهای، به دلیل ORM زیر هود استفاده میشود. MongoDB ، کاملاً انعطاف پذیر ، معمولاً با چارچوب های سبک وزن مانند فلاسک برای سهولت نمونه سازی جفت می شود. با این حال ، همچنین به دلیل مقیاس پذیری ، ساختارهای پویا و پشتیبانی پرس و جو به طور فزاینده ای در پروژه های بزرگتر مورد استفاده قرار می گیرد.
از موتور جنگو MongoDB برای تعریف طرحواره ها استفاده می شود.
توجه داشته باشید: در زمان نوشتن ، این موتور پشتیبانی نمی کند پایتون 3.x. آخرین نسخه پشتیبانی شده است پایتون 2.7.
پایگاه های داده غیر رابطه ای در مقابل رابطه ای
تفاوت اصلی این موتور در مقایسه با سایر موتورهای محبوب این است که با یک پایگاه داده غیر رابطه ای کار می کند، در حالی که برنامه های جنگو بیشتر با پایگاه داده های رابطه ای توسعه می یابند.
انتخاب بین این دو رویکرد به پروژه مورد نظر شما کاهش می یابد روی، همانطور که هر نوع بسته به جوانب مثبت و منفی دارد روی موقعیت. پایگاه داده های غیر رابطه ای معمولاً انعطاف پذیرتر هستند (هر دو طرفدار و مخالف)، در حالی که پایگاه داده های رابطه ای منطبق تر هستند (همچنین، هر دو طرفدار و مخالف).
پایگاه داده های غیر رابطه ای نیز عبارتند از معمولا، برای سیستم های مقیاس پذیر که نگه دارند بهتر است داده های زیادی. با این حال ، برای سیستم های کوچک تا میانی ، سهولت در حفظ پایگاه داده های رابطه ای اغلب غالب است.
پایگاه داده رابطه ای
یک بانک اطلاعاتی رابطه ای داده ها را در جداول ذخیره می کند ، که از ستون ها و ردیف ها تشکیل شده است.
- آ ردیف نشان دهنده یک وجود، موجودیت (مثلا الف
Movie
) - آ ستون نشان دهنده یک صفت موجودیت (مثلا
name
از فیلم، آنlength
،year
انتشار و غیره) - آ ردیف یکی را نشان می دهد ورود در یک پایگاه داده (مثلا
{"The Matrix", 2h 16min, 1999.}
).
هر ردیف جدول باید یک کلید منحصر به فرد داشته باشد (یک شناسه) که تنها یک ردیف را نشان می دهد.
برخی از معروف ترین پایگاه داده های رابطه ای عبارتند از: Oracle، PostgreSQL، MySQL و MariaDB.
پایگاه داده غیر رابطه ای
یک بانک اطلاعاتی غیر مرتبط داده ها را در جداول ذخیره نمی کند ، بلکه بستگی دارد روی نوع داده ها چهار نوع مختلف از پایگاه داده های غیر مرتبط وجود دارد:
- پایگاه داده سند محور (یا فروشگاه اسناد)
- مجموعه ای از فیلدهای رشته نامگذاری شده را معمولاً به شکل اسناد JSON، XML یا YAML مدیریت می کند. این قالب ها می توانند مشتقاتی نیز داشته باشند.
- فروشگاه عریض
- داده ها را در ستون ها ، در ساختار مشابه با پایگاه داده های رابطه ای سازماندهی می کند
- فروشگاه نمودار
- روابط بین نهادها را ذخیره می کند (پیچیده ترین نوع بانک اطلاعاتی غیر مرتبط)
- زمانی استفاده میشود که دادهها به طور گسترده به هم مرتبط باشند
- فروشگاه Key-Value
- مجموعه جفت کلید-مقدار ساده
برخی از مشهورترین پایگاه داده های غیر مرتبط: MongoDB، کاساندرا، ردیس.
MongoDB هست یک مبتنی بر سند پایگاه داده غیر رابطه ای که اسناد را در آن ذخیره می کند BSON (JSON باینری) قالب – مشتق شده از JSON.
نصب و راه اندازی
برای پیاده سازی موتور جنگو MongoDB در یک پروژه ، ما می خواهیم سه مورد را نصب کنیم:
- Django-nonrel – پشتیبانی از پایگاه داده های غیر مرتبط (این همچنین Django 1.5 را برای شما نصب می کند و نسخه قبلی را نصب کرده است).
- djangotoolbox – ابزارهایی برای برنامه های غیر رابطه ای جنگو.
- موتور جنگو MongoDB – خود موتور.
بیایید آنها را از طریق نصب کنیم pip
، در کنار خود جنگو:
$ pip install django
$ pip install git+https://github.com/django-nonrel/(email protected)
$ pip install git+https://github.com/django-nonrel/djangotoolbox
$ pip install git+https://github.com/django-nonrel/mongodb-engine
بیایید یک پروژه جنگو را از طریق command-line برای رسیدن به نقطه شروع:
$ django-admin.py startproject djangomongodbengine
اکنون، با یک پروژه اسکلت که حاوی چند فایل اساسی است، میخواهیم به جنگو اطلاع دهیم که از کدام موتور میخواهیم استفاده کنیم. برای انجام این کار، ما خود را به روز می کنیم settings.py
فایل، و به طور خاص تر، DATABASES
ویژگی:
DATABASES = {
'default' : {
'ENGINE' : 'django_mongodb_engine',
'NAME' : 'example_database'
}
}
پس از نصب و راه اندازی، اجازه دهید نگاهی به برخی از کارهایی که می توانیم با موتور جنگو MongoDB انجام دهیم بیاندازیم.
مدل ها و زمینه ها
وقتی صحبت از کار با مدل ها، در یک استاندارد MVC (Model-View-Controller) معماری، رویکرد کلاسیک استفاده از django.db.models
مدول. این Model
کلاس دارد CharField
اس، TextField
s و غیره که به شما امکان می دهد اساساً طرح واره مدل های خود و روش نگاشت آنها به پایگاه داده توسط ORM جنگو را تعریف کنید.
بیایید یک را اضافه کنیم Movie
الگوی ما models.py
:
from django.db import models
class Movie(models.Model)
name = models.CharField()
length = models.IntegerField()
در اینجا، ما یک Movie
مدلی که دو فیلد دارد – name
و length
. هر کدام از اینها یک هستند Field
پیاده سازی، که نشان دهنده یک ستون پایگاه داده با نوع داده داده شده است.
در حالی که وجود دارد کمی منصفانه از انواع میدان، models
ماژول از فیلدهایی که چندین مقدار دارند پشتیبانی نمی کند.
این عمدتا به این دلیل است که models
ماژول عمدتاً با پایگاه داده های رابطه ای استفاده می شود. هنگامی که یک شی دارای یک فیلد با چندین مقدار است، مانند a Movie
داشتن بسیاری Actor
s، شما باید یک یک به چند رابطه با جدول دیگر
با MongoDB، می توانید آنها را به عنوان یک ذخیره کنید فهرست در آن سند، بدون نیاز به ارجاع پایگاه داده به جدول یا سند دیگری. این جایی است که کمبود رشته هایی مانند ListField
و DictField
.
ListField
ListField
یک ویژگی از نوع لیست است، ویژگی که می تواند چندین مقدار را در خود جای دهد. متعلق به djangotoolbox.fields
ماژول، و می تواند برای تعیین فیلدهایی استفاده شود که حاوی مقادیر فهرست مانند هستند، که سپس در سند BSON ذخیره می شوند.
بیایید خودمان را اصلاح کنیم Movie
مدل قبلی:
from django.db import models
from djangotoolbox.fields import ListField
class Movie(models.Model):
name = models.CharField()
length = models.IntegerField()
year = models.IntegerField()
actors = ListField()
توجه داشته باشید که ما آن را مشخص نکردیم id
رشته. نیازی به آن نیست، زیرا MongoDB به طور ضمنی آن را به نمونه ای اختصاص می دهد Model
. علاوه بر این، ما را اضافه کردیم actors
میدان، که یک ListField
.
حال، هنگام ایجاد یک Movie
به عنوان مثال، ما می توانیم لیستی را به آن اختصاص دهیم actors
و بدون ایجاد جدول جداگانه ای که حاوی آن است، آن را در پایگاه داده MongoDB خود ذخیره کنید Actor
نمونه ها و ارجاع به آنها در ما Movie
اسناد:
movie = Movie.objects.create(
name = "The Matrix",
length = 136,
year = 1999,
actors = ("Keanu Reeves", "Laurence Fishburne")
)
اجرای این قطعه کد منجر به یک سند MongoDB می شود:
{
"_id" : ObjectId("..."),
"name" : "The Matrix",
"length" : 136,
"year" : 1999,
"actors" : (
"Keanu Reeves",
"Laurence Fishburne"
)
}
ما همچنین میتوانیم extend()
را ListField
و مقادیر بیشتری به آن اضافه کنید:
movie.actors.extend(('Carrie-Ann Moss'))
این منجر به یک سند BSON به روز شده می شود:
{
"_id" : ObjectId("..."),
"name" : "The Matrix",
"length" : 136,
"year" : 1999,
"actors" : (
"Keanu Reeves",
"Laurence Fishburne",
"Carrie-Ann Moss",
"Carrie-Ann Moss"
)
}
SetField
SetField
مثل این هست که ListField
به جز اینکه به عنوان یک مجموعه پایتون تفسیر می شود، به این معنی که هیچ تکراری مجاز نیست.
اگر یک بازیگر را دو بار اضافه کنیم:
movie.actors.extend(('Carrie-Ann Moss'))
ما به سرعت متوجه می شویم که خروجی کمی عجیب است:
{
"_id" : ObjectId("..."),
"name" : "The Matrix",
"length" : 136,
"year" : 1999,
"actors" : (
"Keanu Reeves",
"Laurence Fishburne",
"Carrie-Ann Moss"
)
}
از آنجایی که میخواهیم از ورودیهای تکراری جلوگیری کنیم، اینکه هر فرد یک فرد واقعی بماند، منطقیتر است که actors
آ SetField
به جای الف ListField
:
from django.db import models
from djangotoolbox.fields import ListField
class Movie(models.Model):
name = models.CharField()
length = models.IntegerField()
year = models.IntegerField()
actors = SetField()
اکنون، میتوانیم چندین بازیگر اضافه کنیم که برخی از آنها تکراری هستند، و فقط اضافههای منحصربهفردی خواهیم داشت:
movie = Movie.objects.create(
name = "John Wick",
length = 102,
year = 2014,
actors = ("Keanu Reeves", "Keanu Reeves", "Bridget Moynahan")
)
با این حال، سند حاصل فقط یک ورودی برای خواهد داشت "Keanu Reeves"
، یک و تنها:
{
"_id" : ObjectId("..."),
"name" : "John Wick",
"length" : 102,
"year" : 2014,
"actors" : (
"Keanu Reeves",
"Bridget Moynahan"
)
}
DictField
DictField
دیکشنری های پایتون را به عنوان دیکشنری دیگر ذخیره می کند BSON سند، در سند خودتان. زمانی که مطمئن نیستید دیکشنری ممکن است چه شکلی باشد – و ساختار از پیش تعریف شده ای برای آن ندارید، اینها ترجیح داده می شوند.
از طرف دیگر در صورت آشنا بودن سازه، استفاده از آن توصیه می شود مدل های تعبیه شده، به عنوان مدل های درون مدل ها. به عنوان مثال، یک Actor
می تواند مدلی برای خودش باشد و ما می توانیم اجازه دهیم Movie
مدل چند تعبیه شده است Actor
مدل ها. از سوی دیگر، اگر مجموعه ای متغیر از مقادیر اضافه شود، می توان آنها را به عنوان عناصر کلیدی-مقدار نگاشت کرد و از طریق یک ذخیره کرد. DictField
.
به عنوان مثال، بیایید یک را اضافه کنیم reviews
زمینه، که می تواند داشته باشد 0..n
بررسی ها در حالی که reviews
انجام دادن دارای ساختار قابل پیش بینی (name
، grade
، comment
)، ما آنها را به عنوان یک پیاده سازی خواهیم کرد DictField
، قبل از ساختن جداگانه Model
برای actors
و reviews
:
from django.db import models
from djangotoolbox.fields import SetField
from djangotoolbox.fields import DictField
class Movie(models.Model):
name = models.CharField()
length = models.IntegerField()
year = models.IntegerField()
actors = SetField()
reviews = DictField()
اکنون، هنگام ایجاد فیلم، میتوانیم فرهنگ لغت منتقدان و نظرات آنها را درباره فیلمها اضافه کنیم:
movie = Movie.objects.create(
name = "Good Will Hunting",
length = 126,
year = 1997,
actors = ("Matt Damon", "Stellan Skarsgard"),
reviews = (
{"Portland Oregonian" : "With its sweet soul and sharp mind..."},
{"Newsweek" : "Gus Van Sant, working from the tangy, well-written script..."}
)
)
اجرای این کد نتیجه می دهد:
{
"_id" : ObjectId("..."),
"name" : "Good Will Hunting",
"length" : 126,
"year" : 1997,
"actors" : (
"Matt Damon",
"Stellan Skarsgard"
),
"reviews" : (
{"Portland Oregonian" : "With its sweet soul and sharp mind..."},
{"Newsweek": "Gus Van Sant, working from the tangy, well-written script..."}
)
}
مدل های تعبیه شده
در حال حاضر reviews
میدان، مسلماً از همان نوع ساختار پیروی خواهد کرد – name
به دنبال comment
. actors
بیش از نام آنها است – آنها یک last_name
، date_of_birth
و خصوصیات دیگر
برای هر دو از اینها، ما میتوانیم مدلهای مستقل بسازیم، دقیقاً شبیه به پایگاههای داده رابطهای. با این حال، با پایگاههای داده رابطهای، ما آنها را در جداول خود ذخیره میکنیم و از آن به آنها پیوند میدهیم Movie
جدول.
با MongoDB میتوانیم آنها را تبدیل کنیم مدل های تعبیه شده – کل اسناد، در یک سند دیگر تعبیه شده است.
بیا خودمونو عوض کنیم Movie
یک بار دیگر:
from django.db import models
from djangotoolbox.fields import ListField, EmbeddedModelField
class Movie(models.Model):
name = models.CharField(max_length=100)
length = models.IntegerField()
year = models.IntegerField()
actors = SetField(EmbeddedModelField("Actor"))
reviews = SetField(EmbeddedModelField("Review"))
در اینجا، ما ساخته ایم SetField
(که می توانست چیزی شبیه الف باشد ListField
) برای هردو actors
و reviews
. با این حال، این بار، ما آنها را ساخته ایم SetField
اس از مدل های دیگر، با عبور EmbeddedModelField
به سازنده های SetField
س
ما هم مشخص کرده ایم که مدل ها در سازنده از EmbeddedModelField
کلاس
حال، بیایید آن دو را نیز در قسمت تعریف کنیم models.py
فایل:
class Actor(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
date_of_birth = models.CharField(max_length=11)
class Review(models.Model):
name = models.CharField(max_length=30)
comment = models.CharField(max_length=300)
حال، هنگام ایجاد یک Movie
شی، و با ذخیره آن در پایگاه داده، می توانیم موارد جدید را نیز اضافه کنیم Actor
و Review
نمونه هایی از آن:
movie = Movie.objects.create(
name = "Focus",
length = 105,
year = 2015,
actors = (
Actor(
first_name="Will",
last_name="Smith",
date_of_birth="25.09.1968."
)
),
reviews = (
Review(
name = "Portland Oregonian",
comment = "With its sweet soul and sharp mind..."
),
Review(
name = "Newsweek",
comment = "Gus Van Sant, working from the tangy, well-written script..."
)
)
)
این اسناد BSON جدید برای هر یک ایجاد می کند Actor
و Review
در مجموعه ها، و آنها را به عنوان اشیاء تعبیه شده در ما ذخیره می کند movie
سند:
{
"_id" : ObjectId("..."),
"name" : "Focus",
"length" : 105,
"year" : 2015,
"actors" : (
{
"name" : "Will",
"last_name" : "Smith",
"date_of_birth" : "25.09.1968"
}
),
"reviews" : (
{
"name" : "Portland Oregonian",
"comment" : "With its sweet soul and sharp mind..."
},
{
"name" : "Newsweek",
"comment" : "Gus Van Sant, working from the tangy, well-written script..."
}
)
}
هر ورودی در reviews
آرایه BSON یک فرد است Review
نمونه، مثال. همینطور است actors
.
مدیریت فایل
MongoDB دارای مشخصات داخلی برای ذخیره/بازیابی فایل ها در سیستم فایل به نام است GridFS، که در موتور جنگو MongoDB نیز استفاده می شود.
توجه داشته باشید: MongoDB فایل ها را با جدا کردن آنها در اندازه های کوچک ذخیره می کند 255 kB
هر یک. وقتی به فایل دسترسی پیدا کرد، GridFS قطعات را جمع آوری کرده و آنها را ادغام می کند.
به import سیستم GridFS، ما به آن دسترسی خواهیم داشت django_mongodb_engine_storage
مدول:
from django_mongodb_engine.storage import GridFSStorage
gridfs = GridFSStorage()
uploads_location = GridFSStorage(location = '/uploaded_files')
زمینه دیگری که می توانیم از آن استفاده کنیم این است GridFSField()
، که به ما امکان می دهد فیلدهایی را مشخص کنیم که از سیستم GridFS برای ذخیره داده ها استفاده می کنند:
class Movie(models.Model):
name = models.CharField()
length = models.IntegerField()
year = models.IntegerField()
actors = SetField(EmbeddedModelField("Actor"))
reviews = SetField(EmbeddedModelField("Review"))
poster = GridFSField()
اکنون این تصویر به صورت تکه ای ذخیره می شود و تنبل بار شده فقط روی تقاضا
نتیجه
به طور خلاصه، Django MongoDB Engine یک موتور نسبتاً قدرتمند است و نقطه ضعف اصلی استفاده از آن این است که با نسخه های قدیمی جنگو (1.5) و Python (2.7) کار می کند، در حالی که جنگو اکنون در 3.2 LTS و پشتیبانی از 1.5 است. خیلی وقت پیش تمام شد پایتون 3.9 است و پشتیبانی از 2.7 در سال گذشته به پایان رسیده است. علاوه بر همه اینها، به نظر می رسد که موتور جنگو MongoDB در سال 2015 توسعه بیشتر را متوقف کرده است.
(برچسبها به ترجمه)# python
منتشر شده در 1403-01-11 03:40:04