Python. Выгрузка sql запроса в xml
Столкнулся с проблемой выгрузки в xml нескольких связных таблиц. Получается, что при связке 1 к многим повторяются заголовки,то есть в 1 накладной несколько ресурсов и выводится все построчно. Поэтому не могу сделать объединение наименований накладных для ресурсов.
Требуется: Накладная:ресурс+ресурс
Спасибо!
import os,cx_Oracle,lxml
def fetchall_xml(cur, pretty_print=True):
import lxml.etree
fields_value = cur.fetchall()
fields_name = tuple(i[0] for i in cur.description)
Message=lxml.etree.Element('Message', attrib={'xmlns': 't'})
elements = lxml.etree.SubElement(Message,'Body', attrib={'xmlns': 't'})
for el in fields_value:
element = lxml.etree.SubElement(elements, 'Накладная')
lxml.etree.SubElement(element, str(fields_name[0])).text = '{}'.format(el[0])
S_GUID = lxml.etree.SubElement(element, 'Ключевыесвойства')
S_GUID2 = lxml.etree.SubElement(S_GUID, 'Данные')
lxml.etree.SubElement(S_GUID2, str(fields_name[1])).text = '{}'.format(el[1])
lxml.etree.SubElement(S_GUID2, str(fields_name[2])).text = '{}'.format(el[2])
lxml.etree.SubElement(element, str(fields_name[3])).text = '{}'.format(el[3])
return lxml.etree.tounicode(Message, pretty_print=pretty_print)
def main():
dbb = cx_Oracle.connect("admin","1234","pentagon")
cur = dbb.cursor()
cur.execute("SELECT N.STRCODE AS STRCODE, NS.POSITION_NAME,NS.QUANTITY,NS.RES_ID AS RES_ID FROM N , Ns WHERE ns.n_id = n.id AND n.id in (486558,480055)")
xml = fetchall_xml(cur)
print(xml)
with open("output2222.xml", 'w',encoding = 'utf-8') as doc:
doc.write(xml)
main()
Ответы (1 шт):
Автор решения: Александр Александров
→ Ссылка
Так как идет выгрузка из oracle, то лучше формировать структуру xml в запросе, а результат записывать в файл. В статье описано как формировать нужную структуру https://oracle-base.com/articles/misc/sqlxml-sqlx-generating-xml-content-using-sql
код будет похож на ниже представленный:
import os,cx_Oracle,itertools
os.chdir("D:/py")
db =cx_Oracle.connect("admin","1234","pentagon")
cursor = db.cursor()
#sql=('SELECT XMLELEMENT("contract_list",XMLAGG (XMLELEMENT("contract",XMLATTRIBUTES(ch.STRCODE AS "STRCODE"),XMLFOREST((SELECT XMLAGG(XMLELEMENT("res",XMLFOREST(cS.NAMERES AS "pos"))) FROM M2_ALL.contractspecification cs WHERE cS.con_ID = ch.con_id) "res_list")))).getClobVal() AS "depts" FROM m2_All.contracthistory ch where ch.flaghist=1 ')
#sql='SELECT XMLELEMENT ("rs_list",XMLAGG (XMLELEMENT ("rs",XMLATTRIBUTES (rs.STRCODE AS "STRCODE")))).getClobVal () AS "depts"FROM m2_All.resources rs where rownum=1'
sql= """
SELECT XMLELEMENT (
"Message",
XMLAttributes ('http://www.1c.ru/SSL/Exchange/Message' as "xmlns:msg",
'http://www.w3.org/2001/XMLSchema' as "xmlns:xs",
'http://www.w3.org/2001/XMLSchema-instance' as "xmlns:xsi" ),
(XMLELEMENT("msg:Header",
XMLELEMENT("msg:Format",'http://v8.1c.ru/edi/edi_stnd/EnterpriseData/1.8'),
XMLELEMENT("msg:CreationDate",(select (sysdate) from dual)),
XMLELEMENT("msg:Confirmation",
XMLELEMENT("msg:ExchangePlan",'СинхронизацияДанныхЧерезУниверсальныйФормат'),
XMLELEMENT("msg:To",'3dadf8ee-4098-4cef-9f9e-e5b4d37848c6'),
XMLELEMENT("msg:MessageNo",'0'),
XMLELEMENT("msg:ReceivedNo",'1') ) ,
XMLELEMENT("msg:AvailableVersion",'1.8'),
XMLELEMENT("msg:AvailableVersion",'1.7') ,
XMLELEMENT("msg:AvailableVersion",'1.6') ,
XMLELEMENT("msg:AvailableVersion",'1.5') ,
XMLELEMENT("msg:AvailableVersion",'1.4') ,
XMLELEMENT("msg:AvailableVersion",'1.3'),
XMLELEMENT("msg:Prefix",'B1') ))
,(XMLELEMENT (
"body",
XMLAttributes (
'http://v8.1c.ru/edi/edi_stnd/EnterpriseData/1.8' AS "xmlns"
),
XMLAGG(XMLELEMENT (
"Справочник.ЕдиницыИзмерения",
(XMLELEMENT (
"КлючевыеСвойства",
(XMLELEMENT (
"Ссылка", ( SUBSTR (SYS_GUID (), 1, 8)|| '-'|| SUBSTR (SYS_GUID (), 9, 4)|| '-'|| SUBSTR (SYS_GUID (), 13, 4)|| '-'|| SUBSTR (SYS_GUID (), 17, 4)|| '-'|| SUBSTR (SYS_GUID (), 21))
)),
XMLELEMENT ("ДанныеКлассификатора",
(XMLELEMENT ("Код", u.strcode)),
(XMLELEMENT ("Наименованиие", u.name)))
))
, XMLELEMENT ("НаименованиеПолное",U.FULLNAME )
))
))
).getClobVal ()
AS "ui"
FROM table.unit u
group by sysdate """
s=cursor.execute(sql)
myString = ''.join(map(str, itertools.chain(*s)))
with open("EI.xml", 'w',encoding = 'utf-8') as doc:
doc.write(myString)
cursor.close()
db.close()