কোনও কলামটি (প্রাথমিক কী) কোনও ইউইউডি হিসাবে হিসাবে সংজ্ঞায়িত করার কোনও উপায় আছে? SQLAlchemy যদি ব্যবহার পোস্টগ্রি (Postgres)?
কোনও কলামটি (প্রাথমিক কী) কোনও ইউইউডি হিসাবে হিসাবে সংজ্ঞায়িত করার কোনও উপায় আছে? SQLAlchemy যদি ব্যবহার পোস্টগ্রি (Postgres)?
উত্তর:
স্ক্লাচেমি ডায়ালগটি ইউআইডি কলামগুলিকে সমর্থন করে। এটি সহজ (এবং প্রশ্নটি বিশেষত পোস্টগ্রিজ) - অন্য উত্তরগুলি এত জটিল কেন তা আমি বুঝতে পারি না।
এখানে একটি উদাহরণ:
from sqlalchemy.dialects.postgresql import UUID
from flask_sqlalchemy import SQLAlchemy
import uuid
db = SQLAlchemy()
class Foo(db.Model):
# id = db.Column(db.Integer, primary_key=True)
id = db.Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4, unique=True, nullable=False)
callable
uuid.uuid4
ফাংশনটি নিজেই কল করার পরিবর্তে কলাম সংজ্ঞায় উত্তীর্ণ না হওয়ার বিষয়ে সতর্ক হন uuid.uuid4()
। অন্যথায়, এই শ্রেণীর সমস্ত দৃষ্টান্তগুলির জন্য আপনার কাছে একই স্কেলারের মান থাকবে। আরও বিশদ এখানে :
এই কলামটির জন্য ডিফল্ট মানকে উপস্থাপনকারী একটি স্কেলার, পাইথন কলযোগ্য বা কলামিলেমেন্ট এক্সপ্রেশন যা এই কলামটি অন্যথায় সন্নিবেশের VALUES ধারাটিতে নির্দিষ্ট না করা থাকলে সন্নিবেষ্টিত হবে।
uuid.uuid4
)।
Column(UUID(as_uuid=True) ...)
Column
এবং Integer
কোড স্নিপেট উপরের আমদানি করা হয়, অথবা পড়তে পরিবর্তন করা হয়েছে db.Column
এবংdb.Integer
আমি এটি লিখেছিলাম এবং ডোমেন চলে গেছে তবে এখানে সাহস আছে ...
আমার সহকর্মীরা যারা যথাযথ ডাটাবেস ডিজাইনের বিষয়ে সত্যই যত্নশীল তা কী ক্ষেত্রগুলির জন্য ব্যবহৃত ইউআইডি এবং জিইউডি সম্পর্কে কীভাবে অনুভব করে। আমি প্রায়শই এটি করার দরকার মনে করি। আমি মনে করি এটির স্বায়ত্তশাসনের চেয়ে কিছু সুবিধা রয়েছে যা এটি এটিকে সার্থক করে তোলে।
আমি গত কয়েক মাস ধরে একটি ইউআইডি কলামের ধরণটি সংশোধন করছি এবং আমার মনে হয় আমি শেষ পর্যন্ত এটি শক্ত হয়ে গিয়েছি।
from sqlalchemy import types
from sqlalchemy.dialects.mysql.base import MSBinary
from sqlalchemy.schema import Column
import uuid
class UUID(types.TypeDecorator):
impl = MSBinary
def __init__(self):
self.impl.length = 16
types.TypeDecorator.__init__(self,length=self.impl.length)
def process_bind_param(self,value,dialect=None):
if value and isinstance(value,uuid.UUID):
return value.bytes
elif value and not isinstance(value,uuid.UUID):
raise ValueError,'value %s is not a valid uuid.UUID' % value
else:
return None
def process_result_value(self,value,dialect=None):
if value:
return uuid.UUID(bytes=value)
else:
return None
def is_mutable(self):
return False
id_column_name = "id"
def id_column():
import uuid
return Column(id_column_name,UUID(),primary_key=True,default=uuid.uuid4)
# Usage
my_table = Table('test',
metadata,
id_column(),
Column('parent_id',
UUID(),
ForeignKey(table_parent.c.id)))
আমি বিশ্বাস করি যে বাইনারি (16 বাইট) হিসাবে স্ট্রিংটি স্ট্রিং প্রতিনিধিত্বের চেয়ে বেশি দক্ষ হওয়া উচিত (36 বাইট?), এবং কিছু ইঙ্গিত রয়েছে যে 16 বাইট ব্লককে স্ট্রিংয়ের চেয়ে মাইএসকিএলে আরও দক্ষ হওয়া উচিত। আমি যাইহোক এটি খারাপ হতে আশা করব না।
একটি অসুবিধা যা আমি পেয়েছি তা হল কমপক্ষে ফাইপাইম্যাডমিনে আপনি রেকর্ডগুলি সম্পাদনা করতে পারবেন না কারণ এটি স্পষ্টত "টেবিল থেকে আইডি = ..." নির্বাচন করুন এবং বিবিধ ডিসপ্লে সমস্যা রয়েছে এমন জন্য কিছু ধরণের চরিত্র রূপান্তর করার চেষ্টা করে।
এটি ব্যতীত সবকিছু ঠিকঠাক বলে মনে হচ্ছে এবং তাই আমি এটি এখানে ফেলে দিচ্ছি। আপনি যদি এর সাথে একটি সুস্পষ্ট ত্রুটি দেখতে পান তবে একটি মন্তব্য করুন। আমি এর উন্নতির জন্য কোন পরামর্শ স্বাগত জানাই।
যদি আমি কিছু হারিয়ে না দিই তবে উপরের সমাধানটি কাজ করবে যদি অন্তর্নিহিত ডাটাবেসের কোনও ইউআইডি টাইপ থাকে। যদি এটি না হয়, সারণীটি তৈরি হওয়ার সময় আপনি সম্ভবত ত্রুটিগুলি পেতে পারেন। আমি যে সমাধানটি নিয়ে এসেছি আমি মূলত এমএসএসকিএল সার্ভারকে টার্গেট করছিলাম এবং তারপরে শেষ পর্যন্ত মাইএসকিউএল চলে এসেছি, তাই আমি মনে করি যে আমার সমাধানটি আরও বেশি নমনীয় বলে মনে হচ্ছে এটি মাইএসকিএল এবং স্ক্লাইটে কাজ করে fine পোস্টগ্রাগেস এখনও চেক করতে বিরক্ত করেননি।
sqlalchemy.dialects.postgresql.UUID
সরাসরি ব্যবহার করুন । দেখতে ব্যাক-এন্ড-অজ্ঞেয়বাদী GUID প্রকার
আপনি যদি 'স্ট্রিং' কলামে ইউইউডিউ মান সহ খুশি হন তবে এখানে একটি সহজ সমাধান পাওয়া যায়:
def generate_uuid():
return str(uuid.uuid4())
class MyTable(Base):
__tablename__ = 'my_table'
uuid = Column(String, name="uuid", primary_key=True, default=generate_uuid)
আমি UUIDType
এই SQLAlchemy-Utils
প্যাকেজটি ব্যবহার করেছি : http://sqlalchemy-utils.readthedocs.org/en/latest/data_types.html#module-sqlalchemy_utils.types.uuid
raise InvalidStatus("notfound: {k}. (cls={cls})".format(k=k, cls=cls))
alchemyjsonschema.InvalidStatus: notfound: BINARY(16). (cls=<class 'sqlalchemy_utils.types.uuid.UUIDType'>)
NameError: name 'sqlalchemy_utils' is not defined
?
SQLAlchemy-Utils
একটি তৃতীয় পক্ষের প্যাকেজ, আপনাকে প্রথমে এটি ইনস্টল করতে হবে:pip install sqlalchemy-utils
যেহেতু আপনি পোস্টগ্রিজ ব্যবহার করছেন এটি কাজ করা উচিত:
from app.main import db
from sqlalchemy.dialects.postgresql import UUID
class Foo(db.Model):
id = db.Column(UUID(as_uuid=True), primary_key=True)
name = db.Column(db.String, nullable=False)
এখানে এসকিউএএলএলচেমি ডক্স থেকে ব্যাকএন্ড অ্যাগনোস্টিক জিইউইডের উপর ভিত্তি করে একটি পদ্ধতির কথা রয়েছে , তবে ইউআইডিগুলিকে পোস্ট-পোস্টস্ক্রাকল ডাটাবেসে সংরক্ষণ করার জন্য বিনয়ের ক্ষেত্র ব্যবহার করে।
import uuid
from sqlalchemy.types import TypeDecorator, BINARY
from sqlalchemy.dialects.postgresql import UUID as psqlUUID
class UUID(TypeDecorator):
"""Platform-independent GUID type.
Uses Postgresql's UUID type, otherwise uses
BINARY(16), to store UUID.
"""
impl = BINARY
def load_dialect_impl(self, dialect):
if dialect.name == 'postgresql':
return dialect.type_descriptor(psqlUUID())
else:
return dialect.type_descriptor(BINARY(16))
def process_bind_param(self, value, dialect):
if value is None:
return value
else:
if not isinstance(value, uuid.UUID):
if isinstance(value, bytes):
value = uuid.UUID(bytes=value)
elif isinstance(value, int):
value = uuid.UUID(int=value)
elif isinstance(value, str):
value = uuid.UUID(value)
if dialect.name == 'postgresql':
return str(value)
else:
return value.bytes
def process_result_value(self, value, dialect):
if value is None:
return value
if dialect.name == 'postgresql':
return uuid.UUID(value)
else:
return uuid.UUID(bytes=value)
যদি কেউ আগ্রহী হয় তবে আমি টম উইলিস উত্তরটি ব্যবহার করছি, তবে ইউইডিতে একটি স্ট্রিং যুক্ত করতে দরকারী বলে মনে করেছি। প্রক্রিয়া_বিন্দ_প্যারাম পদ্ধতিতে ইউআইডি রূপান্তর
class UUID(types.TypeDecorator):
impl = types.LargeBinary
def __init__(self):
self.impl.length = 16
types.TypeDecorator.__init__(self, length=self.impl.length)
def process_bind_param(self, value, dialect=None):
if value and isinstance(value, uuid.UUID):
return value.bytes
elif value and isinstance(value, basestring):
return uuid.UUID(value).bytes
elif value:
raise ValueError('value %s is not a valid uuid.UUId' % value)
else:
return None
def process_result_value(self, value, dialect=None):
if value:
return uuid.UUID(bytes=value)
else:
return None
def is_mutable(self):
return False
আপনি একটি কাস্টম প্রকার লেখার চেষ্টা করতে পারেন , উদাহরণস্বরূপ:
import sqlalchemy.types as types
class UUID(types.TypeEngine):
def get_col_spec(self):
return "uuid"
def bind_processor(self, dialect):
def process(value):
return value
return process
def result_processor(self, dialect):
def process(value):
return value
return process
table = Table('foo', meta,
Column('id', UUID(), primary_key=True),
)
types.TypeDecorator
পরিবর্তে সাবক্ল্যাসিং ব্যতীত অনুরূপ দেখাচ্ছে types.TypeEngine
। না হয় পদ্ধতির কি অন্যের তুলনায় কোনও সুবিধা বা অসুবিধা রয়েছে?
default=?
? উদাহরণস্বরূপColumn('id', UUID(), primary_key=True, default=<someautouuidgeneratingthing>)