如何编写子查询?

时间:2017-03-12 14:49:48

标签: python sqlalchemy

我正在尝试使用SQL Alchemy

将此SQL表达式转换为子查询

我正在尝试阅读子查询的文档,但我迷路了。任何人都可以在SqlAlchemy中写这个,这样我就能理解如何做到这一点吗?

internal static string createAPage(string space, string title, string body, string objectType, int ancestorId = -1)
        {
            string json = string.Empty;
            try
            {

                CreateContentWithParentJson createContentWithParentJson = JsonConvert.DeserializeObject<CreateContentWithParentJson>(_jsonCreatePageWithParentSample);
                createContentWithParentJson.space.key = space;
                createContentWithParentJson.title = title;
                body = body.Replace("&", "&amp;");
                createContentWithParentJson.body.storage.value = "<p>" + body + "</p>";
                Ancestor a = new Ancestor();
                a.id = ancestorId;
                createContentWithParentJson.ancestors = new List<Ancestor>();
                createContentWithParentJson.ancestors.Add(a);
                json = JsonConvert.SerializeObject(createContentWithParentJson, Utils.getJsonSettings());

        }
        catch (Exception) {  // handle exception 
        }
        return Utils.contentPost(json, _baseUrl);

    }


  internal static string contentPost(string postData, string url, string method = "POST")
        {
            string encodedCred = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(ConfAPI._confUser + ":" + ConfAPI._confPass));
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            request.Headers.Add("Authorization", "Basic " + encodedCred);
            request.Headers.Add("X-Atlassian-Token", "no-check");
            request.Method = method;
            request.Accept = "application/json";
            request.ContentType = "application/json";

            // request.KeepAlive = false;
            if (postData != null)
            {
                byte[] data = Encoding.UTF8.GetBytes(postData);
                request.ContentLength = data.Length;
                using (var stream = request.GetRequestStream())
                {
                    stream.Write(data, 0, data.Length);
                }
            }
            WebResponse response;

            try
            {
                response = (HttpWebResponse)request.GetResponse();
            }
            catch (WebException e)
            {
                return e.Message + " " + e.StackTrace.ToString();
            }

            var responsestring = new StreamReader(response.GetResponseStream()).ReadToEnd();
            return responsestring;
        }

  public class CreateContentWithParentJson
    {
        public string type { get; set; }
        public string title { get; set; }
        public List<Ancestor> ancestors { get; set; }
        public Space space { get; set; }
        public Body body { get; set; }
    }

 internal static string _baseUrl = "http://localhost:8090/rest/api/content";
 internal static string _jsonCreatePageWithParentSample = @"{'type':'page','title':'new page', 'ancestors':[{'id':456}], 'space':{'key':'TST'},'body':{'storage':{'value':'<p>This is a new page</p>','representation':'storage'}}}";

3 个答案:

答案 0 :(得分:1)

如何使用左连接而不是子查询:

SELECT from_ 
FROM uploaded_emails1 ue 
LEFT JOIN candidate_emails2 ce ON ue.from_ = ce.email 
WHERE ce.email IS NULL AND from_! = "test@email.com"

这可以在SQLAlchemy中表示为:

emails = dbsession.query(
    UploadedEmail.from_
).outerjoin(
    CandidateEmail, CandidateEmail.email == UploadedEmail.from_
).filter(
    CandidateEmail.email == None,
    UploadedEmail.from_ != 'test@email.com',
)

答案 1 :(得分:0)

首先,我认为你可能会尝试在这里深入研究一下(SQL查询可能不是实现你想要的正确方法)所以你可能想要考虑获得一些SQL概念在深入了解sqlalchemy的子查询之前,你的脑子里有点清醒。与此相关,拥有名为uploaded_emails1candidate_emails2的表表明您的基础数据库架构设计可能需要进行一些调整。

话虽如此,这是一个应该做你想做的最小例子(获取上传电子邮件中不在候选电子邮件表中的所有电子邮件地址)

from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
import sqlalchemy as sq
from sqlalchemy.orm import sessionmaker

engine = create_engine('sqlite://', echo=True)

Base = declarative_base()


class UploadedUser(Base):
    __tablename__ = 'uploaded_user'
    uploaded_user_id = sq.Column(sq.Integer, primary_key=True)
    email_address = sq.Column(sq.Text(100))


class CandidateUser(Base):
    __tablename__ = 'candidate_user'

    candidate_user_id = sq.Column(sq.Integer, primary_key=True)
    email_address = sq.Column(sq.Text(100))

    def __repr__(self):
        return '<Candidate User with email: {}>'.format(self.email_address)


Base.metadata.create_all(engine)

Session = sessionmaker(bind=engine)
session = Session()

uploaded_user = UploadedUser(email_address='email1@foo.com')
session.add(uploaded_user)

for idx in range(1, 3):
    candidate_user = CandidateUser(email_address='email{}@foo.com'.format(idx))
    session.add(candidate_user)

session.commit()

query_result = session.query(CandidateUser.email_address,
                             UploadedUser.email_address).outerjoin(UploadedUser,
                                                                   CandidateUser.email_address == UploadedUser.email_address).filter(
    UploadedUser.email_address.isnot(None)).with_entities(UploadedUser.email_address).all()

print(query_result)

echo=True告诉sqlalchemy打印它正在执行的实际查询,因此您正在执行的查询是:

SELECT uploaded_user.email_address AS uploaded_user_email_address 
FROM candidate_user LEFT OUTER JOIN uploaded_user ON
candidate_user.email_address = uploaded_user.email_address 
WHERE uploaded_user.email_address IS NOT NULL

如果您正在编写原始SQL,那么它非常接近您要编写的查询。

答案 2 :(得分:0)

for email, in db_session.query(Uploaded_Emails1.from_).filter(
        Uploaded_Emails1.from_ != 'test@email.com').filter(
        ~Uploaded_Emails1.from_.in_(db_session.query(Candidate_Emails2.email))):
    print(email)

这很有用