স্কেলচেমি: এক কোয়েরিতে কয়েকটি টেবিল কীভাবে যোগদান করবেন?


98

আমার কাছে নিম্নলিখিত এসকিউএলএলচেমি ম্যাপযুক্ত ক্লাস রয়েছে:

class User(Base):
    __tablename__ = 'users'
    email = Column(String, primary_key=True)
    name = Column(String)

class Document(Base):
    __tablename__ = "documents"
    name = Column(String, primary_key=True)
    author = Column(String, ForeignKey("users.email"))

class DocumentsPermissions(Base):
    __tablename__ = "documents_permissions"
    readAllowed = Column(Boolean)
    writeAllowed = Column(Boolean)

    document = Column(String, ForeignKey("documents.name"))

আমাকে এর জন্য একটি টেবিল পেতে হবে user.email = "user@email.com":

email | name | document_name | document_readAllowed | document_writeAllowed

কীভাবে এটি এসকিউএএলএলচেমির জন্য একটি প্রশ্নের অনুরোধ ব্যবহার করে তৈরি করা যেতে পারে? নীচের কোডটি আমার পক্ষে কাজ করে না:

result = session.query(User, Document, DocumentPermission).filter_by(email = "user@email.com").all()

ধন্যবাদ,


আমি দেখতে পেয়েছি যে নিম্নলিখিত দুটি সারণিতে যোগদানের জন্য কাজ করে: result = session.query(User, Document).select_from(join(User, Document)).filter(User.email=='user@email.com').all()তবে তিনটি টেবিলের জন্য কীভাবে কাজটি একইভাবে করা যায় তা আমি এখনও পরিচালনা করতে পারি নি (ডকুমেন্টপার্মিকেশন অন্তর্ভুক্ত করতে)। কোন ধারণা?
বারানকিন

আমি যখন অনুরূপ টাস্কটি সম্পাদন করি তখন আমি সিনট্যাক্স এরর পাই: কীওয়ার্ডটি এক্সপ্রেশন হতে পারে না
Isশান তোমার

উত্তর:


98

এটা চেষ্টা কর

q = Session.query(
         User, Document, DocumentPermissions,
    ).filter(
         User.email == Document.author,
    ).filter(
         Document.name == DocumentPermissions.document,
    ).filter(
        User.email == 'someemail',
    ).all()

7
এটি কি ধরণের কাজ joinকরে? অভ্যন্তরীণ, বাহ্যিক, ক্রস বা কি?
নওয়াজ

7
এটি আসলে কোনও অংশেই যোগ দেয় না, এটি একটি টিউপলে সারি বস্তুগুলি দেয় returns এই ক্ষেত্রে, এটি ফিরে আসবে [(<user>, <document>, <documentpermissions>),...]/
নকল নাম

37
"কিছুতেই যোগদান করবেন না" - এটি কিছুটা বিভ্রান্তিকর। এটিতে স্কয়ার যুক্ত হবে select x from a, b ,cযা ক্রস জোড়। ফিল্টারগুলি তারপরে এটি একটি অভ্যন্তরীণ যোগদান করে।
আইদান কেন

7
আপনি এটিকে ছেড়ে क्वेरीটি মুদ্রণ করতে পারেন .all()। সুতরাং print Session.query....এটি ঠিক কি করছে তা দেখতে।
নৌকোডার

4
আমি এসকিউএলএলচেমিতে নতুন। আমি লক্ষ্য করেছি .filter()কমা বিচ্ছিন্ন হয়ে গেলে একাধিক মানদণ্ড পেতে পারে। .filter()প্রথম বন্ধনের অভ্যন্তরে কমা বিচ্ছেদ সহ একটি ব্যবহার করা বা .filter()উপরের উত্তরের মতো একাধিক ব্যবহার করা ভাল ?
ইন্ট্রাস্টেলার এক্সপ্লোরার

53

অনুমতিগুলির জন্য কিছু সম্পর্ক এবং প্রাথমিক কী সেটআপ করা ভাল শৈলী হ'ল (আসলে, সাধারণত সমস্ত কিছুর জন্য পূর্ণসংখ্যার প্রাথমিক কীগুলি সেটআপ করা ভাল স্টাইল , তবে যাই হোক না কেন):

class User(Base):
    __tablename__ = 'users'
    email = Column(String, primary_key=True)
    name = Column(String)

class Document(Base):
    __tablename__ = "documents"
    name = Column(String, primary_key=True)
    author_email = Column(String, ForeignKey("users.email"))
    author = relation(User, backref='documents')

class DocumentsPermissions(Base):
    __tablename__ = "documents_permissions"
    id = Column(Integer, primary_key=True)
    readAllowed = Column(Boolean)
    writeAllowed = Column(Boolean)
    document_name = Column(String, ForeignKey("documents.name"))
    document = relation(Document, backref = 'permissions')

তারপরে যোগদানের সাথে একটি সাধারণ ক্যোয়ারী করুন:

query = session.query(User, Document, DocumentsPermissions).join(Document).join(DocumentsPermissions)

queryশেষ লাইনে কী সেট করা আছে এবং আপনি এতে যুক্ত হওয়া রেকর্ডগুলিতে কীভাবে অ্যাক্সেস করবেন?
পেট্রাস থেরন

@ প্যাট আমি নিশ্চিত না যে আপনি 'কী জিজ্ঞাসা সেট করা হয়েছে' বলতে কী বোঝায়, তবে এটি সম্পর্ক এবং ফলন 3-টিউপস অনুসারে যোগ দেবে। ক্যোয়ারী () কলটিতে যুক্তিগুলি মূলত স্কেলচেমির মধ্যে নির্বাচিত তালিকা।
লেটিবি

Documentক্যোরি রেজাল্ট সেটে আমি কীভাবে (২ য় টুপল মান) অ্যাক্সেস করব ?
পেট্রাস থেরন

4
@ পেট্রাসথেরন যেমনটি আমি বলেছিলাম, ক্যোয়ারী থেকে 3 টি টিপল পাওয়া যাবে। আপনি উপাদানগুলি সূচী করতে পারেন, বা কেবল আনপ্যাক করতে পারেন:for (user, doc, perm) in query: print "Document: %s" % doc
লিখিত e

4
ওহ, অতীত থেকে বিস্ফোরণ। 'অনুমতি' হ'ল ডকুমেন্ট অবজেক্টের একটি বৈশিষ্ট্য, যা আপনাকে ডকুমেন্টপার্মেশন অবজেক্টের সেট দেয়। অতএব পিছনে।
লেটবি

41

@ লেল্টবি যেমন বলেছিলেন, টেবিলগুলিতে প্রাথমিক কীগুলি বরাদ্দ করা এবং যথাযথ ওআরএম অনুসন্ধানের জন্য সম্পর্কগুলি সঠিকভাবে সংজ্ঞায়িত করার সর্বোত্তম অনুশীলন। বলা হচ্ছে যে...

আপনি যদি এই লাইন বরাবর একটি কোয়েরি লিখতে আগ্রহী হন:

SELECT
    user.email,
    user.name,
    document.name,
    documents_permissions.readAllowed,
    documents_permissions.writeAllowed
FROM
    user, document, documents_permissions
WHERE
    user.email = "user@email.com";

তারপরে আপনার এমন কিছু সন্ধান করা উচিত:

session.query(
    User, 
    Document, 
    DocumentsPermissions
).filter(
    User.email == Document.author
).filter(
    Document.name == DocumentsPermissions.document
).filter(
    User.email == "user@email.com"
).all()

পরিবর্তে, আপনি যেমন কিছু করতে চান:

SELECT 'all the columns'
FROM user
JOIN document ON document.author_id = user.id AND document.author == User.email
JOIN document_permissions ON document_permissions.document_id = document.id AND document_permissions.document = document.name

তারপরে আপনার কিছু করা উচিত:

session.query(
    User
).join(
    Document
).join(
    DocumentsPermissions
).filter(
    User.email == "user@email.com"
).all()

সে সম্পর্কে একটি নোট ...

query.join(Address, User.id==Address.user_id) # explicit condition
query.join(User.addresses)                    # specify relationship from left to right
query.join(Address, User.addresses)           # same, with explicit target
query.join('addresses')                       # same, using a string

আরো তথ্যের জন্য, দেখার জন্য দস্তাবেজ


4
এটা কর. দেখুন - যোগদানের জন্য নির্দিষ্ট অনেকগুলি জিনিস নয়। কারণ এই টেবিলগুলির মধ্যে যদি টেবিলগুলি / ডিবি-মডেলটি ইতিমধ্যে সঠিক বিদেশী কীগুলি সেট আপ করে থাকে - এসকিউএলএলচেমি আপনার জন্য উপযুক্ত কলামগুলিতে যোগদানের যত্ন নেবে।
ব্র্যাড

8

আবদুলের জবাব প্রসারিত করে, আপনি KeyedTupleকলামগুলিতে যোগদান করে সারিগুলির একটি পৃথক সংগ্রহের পরিবর্তে পেতে পারেন :

q = Session.query(*User.__table__.columns + Document.__table__.columns).\
        select_from(User).\
        join(Document, User.email == Document.author).\
        filter(User.email == 'someemail').all()

4
এইটা কাজ করে. যাইহোক, বস্তুর ক্রমিকায়নের সময় সেগুলির নাম কমে যায়।
লুকাস

2

এই ফাংশনটি টিউপসগুলির তালিকা হিসাবে প্রয়োজনীয় সারণী তৈরি করবে।

def get_documents_by_user_email(email):
    query = session.query(
       User.email, 
       User.name, 
       Document.name, 
       DocumentsPermissions.readAllowed, 
       DocumentsPermissions.writeAllowed,
    )
    join_query = query.join(Document).join(DocumentsPermissions)

    return join_query.filter(User.email == email).all()

user_docs = get_documents_by_user_email(email)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.