জ্যাঙ্গো গতিশীল মডেল ক্ষেত্র


161

আমি একটি বহু-ভাড়াটে অ্যাপ্লিকেশন নিয়ে কাজ করছি যাতে কিছু ব্যবহারকারী ফর্মগুলিতে অতিরিক্ত ডেটা সংগ্রহ করতে এবং ডেটা সম্পর্কে রিপোর্ট করতে তাদের নিজস্ব ডেটা ক্ষেত্রগুলি (অ্যাডমিনের মাধ্যমে) সংজ্ঞায়িত করতে পারেন। আধুনিক বিট জেএসনফিল্ডকে দুর্দান্ত বিকল্প হিসাবে তৈরি করে না, সুতরাং এর পরিবর্তে আমার কাছে নিম্নলিখিত সমাধান রয়েছে:

class CustomDataField(models.Model):
    """
    Abstract specification for arbitrary data fields.
    Not used for holding data itself, but metadata about the fields.
    """
    site = models.ForeignKey(Site, default=settings.SITE_ID)
    name = models.CharField(max_length=64)

    class Meta:
        abstract = True

class CustomDataValue(models.Model):
    """
    Abstract specification for arbitrary data.
    """
    value = models.CharField(max_length=1024)

    class Meta:
        abstract = True

কাস্টমডাটাফিল্ড কীভাবে সাইটে একটি বিদেশী কী আছে তা নোট করুন - প্রতিটি সাইটে কাস্টম ডেটা ক্ষেত্রের আলাদা সেট থাকবে, তবে একই ডাটাবেসটি ব্যবহার করবে। তারপরে বিভিন্ন কংক্রিট ডেটা ফিল্ডগুলি সংজ্ঞায়িত করা যেতে পারে:

class UserCustomDataField(CustomDataField):
    pass

class UserCustomDataValue(CustomDataValue):
    custom_field = models.ForeignKey(UserCustomDataField)
    user = models.ForeignKey(User, related_name='custom_data')

    class Meta:
        unique_together=(('user','custom_field'),)

এটি নিম্নলিখিত ব্যবহারের দিকে নিয়ে যায়:

custom_field = UserCustomDataField.objects.create(name='zodiac', site=my_site) #probably created in the admin
user = User.objects.create(username='foo')
user_sign = UserCustomDataValue(custom_field=custom_field, user=user, data='Libra')
user.custom_data.add(user_sign) #actually, what does this even do?

তবে এটি খুব বিশৃঙ্খল বোধ করে, বিশেষত সম্পর্কিত ডেটা ম্যানুয়ালি তৈরি করা এবং এটি কংক্রিটের মডেলের সাথে সংযুক্ত করার প্রয়োজনের সাথে। একটি ভাল পদ্ধতির আছে কি?

প্রাক-শূন্যতার সাথে বাতিল করা হয়েছে এমন বিকল্পগুলি:

  • অন ​​ফ্লাই টেবিলগুলি পরিবর্তন করতে কাস্টম এসকিউএল। আংশিক কারণ এটি স্কেল করবে না এবং আংশিক কারণ এটি হ্যাকের খুব বেশি।
  • NoSQL এর মতো স্কিমা-কম সমাধান। তাদের বিরুদ্ধে আমার কিছু নেই, তবে তারা এখনও ভাল ফিট নয়। পরিশেষে এই তথ্য নেই টাইপ করা, এবং সম্ভাবনা একটি তৃতীয় পক্ষের প্রতিবেদনের অ্যাপ্লিকেশন ব্যবহার করে এর বিদ্যমান।
  • উপরে তালিকাভুক্ত জেএসএনফিল্ড, কারণ এটি কোয়েরিগুলির সাথে ভাল কাজ করে না।

6
: প্রাক emptively, এই এই প্রশ্নগুলোর কোন হল stackoverflow.com/questions/7801729/... stackoverflow.com/questions/2854656/...
GDorn

উত্তর:


278

আজ অবধি, চারটি উপলব্ধ পন্থা রয়েছে, এর মধ্যে দুটি নির্দিষ্ট স্টোরেজ ব্যাকএন্ডের প্রয়োজন:

  1. জ্যাঙ্গো-ইভ (মূল প্যাকেজটি আর মেন্টেন্ট নয় তবে এর কিছু সমৃদ্ধ কাঁটাচামচ রয়েছে )

    এই সমাধানটি অ্যান্টি অ্যাট্রিবিউট মান ডেটা মডেলের উপর ভিত্তি করে , মূলত, এটি অবজেক্টগুলির গতিশীল বৈশিষ্ট্যগুলি সংরক্ষণ করতে বেশ কয়েকটি সারণী ব্যবহার করে। এই সমাধানটি সম্পর্কে দুর্দান্ত অংশগুলি হ'ল:

    • গতিশীল ক্ষেত্রগুলি উপস্থাপন করতে বেশ কয়েকটি খাঁটি এবং সাধারণ জ্যাঙ্গো মডেল ব্যবহার করে, যা বোঝার জন্য সহজ করে তোলে এবং ডাটাবেস-অজোনস্টিককে;
    • আপনাকে জাজানো মডেলের সাথে সাধারণ কমান্ডগুলির মতো কার্যকরভাবে ডায়নামিক অ্যাট্রিবিউট স্টোরেজ সংযুক্ত / বিচ্ছিন্ন করতে দেয়:

      eav.unregister(Encounter)
      eav.register(Patient)
      
    • জ্যাঙ্গো অ্যাডমিনের সাথে সুন্দরভাবে সংহত হয়েছে ;

    • একই সঙ্গে সত্যই ক্ষমতাবান।

    downsides:

    • খুব দক্ষ নয়। এটি নিজেই ইএভি প্যাটার্নের একটি সমালোচনা, যার জন্য কলাম বিন্যাস থেকে ম্যানুয়ালি কী-মান জোড়ার সেটগুলিতে ম্যানুয়ালি ডেটা মার্জ করা প্রয়োজন।
    • কঠিন বজায় রাখা। ডেটা অখণ্ডতা বজায় রাখার জন্য একাধিক কলামের অনন্য কী বাধা দরকার যা কিছু ডাটাবেসে অকার্যকর হতে পারে।
    • আপনার কাঁটাচামড়ার একটি নির্বাচন করতে হবে , যেহেতু অফিসিয়াল প্যাকেজটি আর রক্ষণাবেক্ষণ করা হয় না এবং কোনও স্পষ্ট নেতা নেই।

    ব্যবহারটি বেশ সহজবোধ্য:

    import eav
    from app.models import Patient, Encounter
    
    eav.register(Encounter)
    eav.register(Patient)
    Attribute.objects.create(name='age', datatype=Attribute.TYPE_INT)
    Attribute.objects.create(name='height', datatype=Attribute.TYPE_FLOAT)
    Attribute.objects.create(name='weight', datatype=Attribute.TYPE_FLOAT)
    Attribute.objects.create(name='city', datatype=Attribute.TYPE_TEXT)
    Attribute.objects.create(name='country', datatype=Attribute.TYPE_TEXT)
    
    self.yes = EnumValue.objects.create(value='yes')
    self.no = EnumValue.objects.create(value='no')
    self.unkown = EnumValue.objects.create(value='unkown')
    ynu = EnumGroup.objects.create(name='Yes / No / Unknown')
    ynu.enums.add(self.yes)
    ynu.enums.add(self.no)
    ynu.enums.add(self.unkown)
    
    Attribute.objects.create(name='fever', datatype=Attribute.TYPE_ENUM,\
                                           enum_group=ynu)
    
    # When you register a model within EAV,
    # you can access all of EAV attributes:
    
    Patient.objects.create(name='Bob', eav__age=12,
                               eav__fever=no, eav__city='New York',
                               eav__country='USA')
    # You can filter queries based on their EAV fields:
    
    query1 = Patient.objects.filter(Q(eav__city__contains='Y'))
    query2 = Q(eav__city__contains='Y') |  Q(eav__fever=no)
    
  2. পোস্টগ্র্রেএসকিউএলে হস্টোর, জেএসএন বা জেএসএনবি ক্ষেত্র

    PostgreSQL আরও বেশ কয়েকটি জটিল ডাটা টাইপ সমর্থন করে। বেশিরভাগ তৃতীয় পক্ষের প্যাকেজগুলির মাধ্যমে সমর্থিত, তবে সাম্প্রতিক বছরগুলিতে জ্যাঙ্গো সেগুলি django.contrib.postgres.fields এ গ্রহণ করেছে।

    এইচস্টোরফিল্ড :

    জ্যাঙ্গো-হস্টোর মূলত একটি তৃতীয় পক্ষের প্যাকেজ ছিল, তবে জ্যাঙ্গো 1.8 এইচস্টোরফিল্ডকে অন্তর্নির্মিত হিসাবে যুক্ত করেছে , আরও বেশ কয়েকটি পোস্টগ্র্রেএসকিউএল-সমর্থিত ক্ষেত্র প্রকারের সাথে।

    এই পদ্ধতিকে এক অর্থে ভাল যে এটি আপনাকে উভয় পৃথিবীর মধ্যে সেরা: গতিশীল ক্ষেত্র এবং সম্পর্কযুক্ত ডাটাবেস পেতে দেয়। তবে, hstore আদর্শ পারফরম্যান্স ভিত্তিক নয় , বিশেষত যদি আপনি এক ক্ষেত্রে হাজার হাজার আইটেম সঞ্চয় করতে চলেছেন। এটি শুধুমাত্র মানগুলির জন্য স্ট্রিং সমর্থন করে।

    #app/models.py
    from django.contrib.postgres.fields import HStoreField
    class Something(models.Model):
        name = models.CharField(max_length=32)
        data = models.HStoreField(db_index=True)
    

    জ্যাঙ্গোর শেল এ আপনি এটি ব্যবহার করতে পারেন:

    >>> instance = Something.objects.create(
                     name='something',
                     data={'a': '1', 'b': '2'}
               )
    >>> instance.data['a']
    '1'        
    >>> empty = Something.objects.create(name='empty')
    >>> empty.data
    {}
    >>> empty.data['a'] = '1'
    >>> empty.save()
    >>> Something.objects.get(name='something').data['a']
    '1'
    

    আপনি hstore ক্ষেত্রের বিরুদ্ধে সূচিকৃত প্রশ্নগুলি ইস্যু করতে পারেন:

    # equivalence
    Something.objects.filter(data={'a': '1', 'b': '2'})
    
    # subset by key/value mapping
    Something.objects.filter(data__a='1')
    
    # subset by list of keys
    Something.objects.filter(data__has_keys=['a', 'b'])
    
    # subset by single key
    Something.objects.filter(data__has_key='a')    
    

    জেএসনফিল্ড :

    জেএসএন / জেএসওএনবি ক্ষেত্রগুলি যে কোনও জেএসওন-এনকোডেবল ডেটা টাইপকে সমর্থন করে, কেবল কী / মান জোড়া নয়, তবে হস্টোরের চেয়ে আরও দ্রুত এবং (জেএসওএনবির পক্ষে) আরও কমপ্যাক্ট থাকে। বেশ কয়েকটি প্যাকেজগুলি জেএসওএন / জেএসওএনবি ক্ষেত্রগুলিকে জ্যাঙ্গো -পিজিফিল্ডগুলি প্রয়োগ করে , তবে জ্যাঙ্গো ১.৯ অনুসারে, জেএসএনফিল্ড স্টোরের জন্য জেএসওএনবি ব্যবহার করে একটি বিল্ট-ইন। জেএসএনফিল্ড এইচস্টোরফিল্ডের মতো, এবং বৃহত অভিধানের সাথে আরও ভাল সম্পাদন করতে পারে। এটি স্ট্রিং ব্যতীত অন্যান্য ধরণের, যেমন ইন্টিজার, বুলেট এবং নেস্টেড ডিকশনারিগুলিকে সমর্থন করে।

    #app/models.py
    from django.contrib.postgres.fields import JSONField
    class Something(models.Model):
        name = models.CharField(max_length=32)
        data = JSONField(db_index=True)
    

    শেলের মধ্যে তৈরি করা হচ্ছে:

    >>> instance = Something.objects.create(
                     name='something',
                     data={'a': 1, 'b': 2, 'nested': {'c':3}}
               )
    

    সূচিকৃত প্রশ্নগুলি এইচস্টোরফিল্ডের মতো প্রায় অভিন্ন, বাদে বাসা বাঁধাই সম্ভব। কমপ্লেক্স সূচকগুলিতে ম্যানুয়ালি তৈরি (অথবা একটি স্ক্রিপ্টেড মাইগ্রেশন) প্রয়োজন হতে পারে।

    >>> Something.objects.filter(data__a=1)
    >>> Something.objects.filter(data__nested__c=3)
    >>> Something.objects.filter(data__has_key='a')
    
  3. জ্যাঙ্গো মঙ্গোডিবি

    বা অন্যান্য নোএসকিউএল জ্যাঙ্গো অভিযোজন - তাদের সাথে আপনার পুরো গতিশীল মডেল থাকতে পারে।

    নোএসকিউএল জ্যাঙ্গো গ্রন্থাগারগুলি দুর্দান্ত, তবে মনে রাখবেন যে এগুলি 100% জ্যাঙ্গো-সামঞ্জস্যপূর্ণ নয়, উদাহরণস্বরূপ, স্ট্যান্ডার্ড জাজানো থেকে জ্যাঙ্গো-ননরেলে স্থানান্তরিত করার জন্য আপনাকে মন্টিটোম্যানিকে অন্য জিনিসগুলির মধ্যে তালিকাফিল্ডের সাথে প্রতিস্থাপন করতে হবে ।

    এই জ্যাঙ্গো মঙ্গোডিবি উদাহরণটি দেখুন:

    from djangotoolbox.fields import DictField
    
    class Image(models.Model):
        exif = DictField()
    ...
    
    >>> image = Image.objects.create(exif=get_exif_data(...))
    >>> image.exif
    {u'camera_model' : 'Spamcams 4242', 'exposure_time' : 0.3, ...}
    

    আপনি যে কোনও জ্যাঙ্গো মডেলের এম্বেড তালিকা তৈরি করতে পারেন :

    class Container(models.Model):
        stuff = ListField(EmbeddedModelField())
    
    class FooModel(models.Model):
        foo = models.IntegerField()
    
    class BarModel(models.Model):
        bar = models.CharField()
    ...
    
    >>> Container.objects.create(
        stuff=[FooModel(foo=42), BarModel(bar='spam')]
    )
    
  4. জ্যাঙ্গো-মিউট্যান্ট: সিঙ্কডিবি এবং সাউথ-হুকের উপর ভিত্তি করে গতিশীল মডেল

    জ্যাঙ্গো-মিউট্যান্ট সম্পূর্ণ গতিশীল বিদেশী কী এবং এম 2 এম ক্ষেত্র প্রয়োগ করে। এবং উইল হার্ডি এবং মাইকেল হলের অবিশ্বাস্য তবে কিছুটা হ্যাকিশ সমাধান দ্বারা অনুপ্রাণিত ।

    এগুলি সমস্ত জ্যাঙ্গো সাউথ হুকের উপর ভিত্তি করে তৈরি করা হয়েছে, যা জঙ্গোকন ২০১১-তে উইল হার্ডির বক্তব্য অনুসারে (এটি দেখুন!) তবুও দৃ in় এবং উত্পাদনে পরীক্ষামূলক ( প্রাসঙ্গিক উত্স কোড )।

    প্রথম এই বাস্তবায়ন ছিল মাইকেল হল

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

    আপনি যদি মাইকেল হলস লিব ব্যবহার করেন তবে আপনার কোডটি এর মতো দেখাবে:

    from dynamo import models
    
    test_app, created = models.DynamicApp.objects.get_or_create(
                          name='dynamo'
                        )
    test, created = models.DynamicModel.objects.get_or_create(
                      name='Test',
                      verbose_name='Test Model',
                      app=test_app
                   )
    foo, created = models.DynamicModelField.objects.get_or_create(
                      name = 'foo',
                      verbose_name = 'Foo Field',
                      model = test,
                      field_type = 'dynamiccharfield',
                      null = True,
                      blank = True,
                      unique = False,
                      help_text = 'Test field for Foo',
                   )
    bar, created = models.DynamicModelField.objects.get_or_create(
                      name = 'bar',
                      verbose_name = 'Bar Field',
                      model = test,
                      field_type = 'dynamicintegerfield',
                      null = True,
                      blank = True,
                      unique = False,
                      help_text = 'Test field for Bar',
                   )
    

3
: এই বিষয়ে সম্প্রতি DjangoCon 2013 ইউরোপ এ কথা বলেছেন হয়েছিল slideshare.net/schacki/... এবং youtube.com/watch?v=67wcGdk4aCc
Aleck Landgraf

এটি লক্ষণীয়ও হতে পারে যে Postgres> = 9.2 এ জ্যাঙ্গো-পিজিজেসন ব্যবহার করে পোস্টগ্র্যাস্কিলের জসন ক্ষেত্রটি সরাসরি ব্যবহারের অনুমতি দেয়। জ্যাঙ্গো> = 1.7 এ, প্রশ্নের জন্য ফিল্টার এপিআই তুলনামূলক বুদ্ধিমান। পোস্টগ্রিজ> = 9.4 দ্রুত অনুসন্ধানের জন্য আরও ভাল সূচী সহ জসনব ক্ষেত্রগুলিকে মঞ্জুরি দেয়।
জিডর্ন

1
অবদানের জন্য জ্যাঙ্গোর এইচস্টোরফিল্ড এবং জেএসএনফিল্ড গ্রহণের বিষয়টি নোট করে আজ আপডেট হয়েছে। এটিতে এমন কিছু ফর্ম উইজেট রয়েছে যা অসাধারণ নয়, তবে আপনার যদি অ্যাডমিনে ডেটা টুইট করার দরকার হয় তবে কাজ করুন।
জিডর্ন

13

আমি জ্যাঙ্গো-ডায়নামো ধারণাটি আরও এগিয়ে দেওয়ার কাজ করছি। প্রকল্পটি এখনও অনথিভুক্ত তবে আপনি https://github.com/charettes/django-mutant এ কোডটি পড়তে পারেন ।

প্রকৃতপক্ষে এফকে এবং এম 2 এম ক্ষেত্রগুলি (অবদানের সাথে সম্পর্কিত দেখুন) এছাড়াও কাজ করে এবং আপনার নিজস্ব কাস্টম ক্ষেত্রগুলির জন্য মোড়কের সংজ্ঞা দেওয়া এমনকি সম্ভব।

মডেল বিকল্পগুলির জন্য যেমন ইউনিক_ টুগেদার এবং অর্ডার প্লাস মডেল ঘাঁটিগুলির জন্যও সমর্থন রয়েছে যাতে আপনি মডেল প্রক্সি, বিমূর্ত বা মিক্সিনগুলিকে সাবক্লাস করতে পারেন।

অপ্রচলিত সংজ্ঞা ব্যবহার করে প্রতিরোধ করার সময় মডেল সংজ্ঞাগুলি একাধিক জ্যাঙ্গো চলমান দৃষ্টান্তগুলিতে ভাগ করা যায় তা নিশ্চিত করার জন্য আমি আসলে একটি মেমরি লক মেকানিজমে কাজ করছি।

প্রকল্পটি এখনও খুব আলফা তবে এটি আমার প্রকল্পের একটির জন্য একটি ভিত্তি প্রযুক্তি। সুতরাং আমি এটি উত্পাদন প্রস্তুত নিতে হবে। বড় পরিকল্পনাটি জাঙ্গো-ননরেলকেও সমর্থন করছে যাতে আমরা মঙ্গোদব চালককে কাজে লাগাতে পারি।


1
হাই, সাইমন! আপনি গিথুবটিতে এটি তৈরি করার ঠিক পরে আমি আমার উইকি উত্তরে আপনার প্রকল্পের একটি লিঙ্ক অন্তর্ভুক্ত করেছি। :))) স্ট্যাকওভারফ্লোতে আপনাকে দেখে ভাল লাগল!
ইভান খারলামভ

4

আরও গবেষণায় প্রকাশিত হয় যে এটি সত্তা গুণাবলীর মান নকশার ধরণের কিছুটা বিশেষ কেস , যা বেশ কয়েকটি প্যাকেজ দ্বারা জাঙ্গোর জন্য প্রয়োগ করা হয়েছে।

প্রথমত, আসল ইভা-জাজানো প্রকল্প রয়েছে, যা পাইপিতে রয়েছে।

দ্বিতীয়ত, প্রথম প্রকল্পের আরও একটি সাম্প্রতিক কাঁটা রয়েছে, জ্যাঙ্গো-ইভ যা তৃতীয় পক্ষের অ্যাপগুলিতে জাঙ্গোর নিজস্ব মডেল বা মডেলগুলির সাথে ইএভি ব্যবহারের অনুমতি দেওয়ার জন্য প্রাথমিকভাবে প্রতিরোধক।


আমি এটি উইকিতে অন্তর্ভুক্ত করব।
ইভান খারলামভ

1
আমি অন্য উপায়ে তর্ক করব, যে EAV গতিশীল মডেলিংয়ের একটি বিশেষ ক্ষেত্রে। এটি "সিমেন্টিক ওয়েব" সম্প্রদায়ে খুব বেশি ব্যবহৃত হয় যেখানে এটিতে একটি অনন্য আইডি অন্তর্ভুক্ত থাকলে "ট্রিপল" বা "কোয়াড" বলা হয়। তবে, এসকিউএল টেবিলগুলি গতিযুক্তরূপে তৈরি এবং সংশোধন করতে পারে এমন কোনও প্রক্রিয়া হিসাবে এটি আর দক্ষ হওয়ার সম্ভাবনা কম।
সেরিন

@ জিডম ইভা-জাজানো আপনার প্রথম পছন্দ? মানে আপনি উপরের কোন বিকল্পটি বেছে নিয়েছেন?
মোরেনো

1
@ মোরেনো সঠিক পছন্দটি আপনার নির্দিষ্ট ব্যবহারের ক্ষেত্রে খুব বেশি নির্ভর করে। আমি ইএভি এবং জসনফিল্ড উভয়ই বিভিন্ন কারণে ব্যবহার করেছি। পরবর্তীটি এখন সরাসরি জ্যাঙ্গো দ্বারা সমর্থিত, সুতরাং নতুন প্রকল্পের জন্য আমি প্রথমে এটি ব্যবহার করব যদি না আমার EAV টেবিলটিতে কোয়েরি করতে সক্ষম হওয়ার নির্দিষ্ট প্রয়োজন না থাকে। নোট করুন যে আপনি জাসনফিল্ডগুলিতেও জিজ্ঞাসা করতে পারেন।
জিডর্ন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.