Fiosrúcháin SQL amh a dhéanamhLink to this heading
Tugann Django dhá bhealach duit chun ceisteanna SQL amh a dhéanamh: is féidir leat: meth: `Manager.raw () `a úsáid chun `fiosruithe amh a dhéanamh agus instancí samhail a thabhairt ar ais `__, nó is féidir leat an ciseal samhail a sheachaint go hiomlán agus `SQL saincheaptha a fhorghníomhú go díreach `__.
Fiosrúcháin amh a dhéanamhLink to this heading
Is féidir an modh bainisteora ``raw () `a úsáid chun ceisteanna SQL amh a dhéanamh a thugann cásanna samhail ar ais:
- Manager.raw(raw_query, params=(), translations=None)Link to this definition
Tógann an modh seo fiosrúchán SQL amh, cuireann sé i bhfeidhm é, agus filleann sé sampla Django.db.Models.Query.RawQuerySet ``ar ais. Is féidir an sampla ``RawQuerySet seo a athrú cosúil le gnáth:class: ~django.db.models.query.querySet chun cásanna réada a sholáthar.
Is fearr é seo a léiriú le sampla. Cuir i gcás go bhfuil an tsamhail seo a leanas agat:
class Person(models.Model):
first_name = models.CharField(...)
last_name = models.CharField(...)
birth_date = models.DateField(...)
Ansin d'fhéadfá SQL saincheaptha a fhorghníomhú mar sin:
>>> for p in Person.objects.raw("SELECT * FROM myapp_person"):
... print(p)
...
John Smith
Jane Jones
Níl an sampla seo an-spreagúil - tá sé díreach mar an gcéanna le rith ``Person.Objects.all () ``. Mar sin féin, tá dornán roghanna eile ag ``raw () ``a fhágann go bhfuil sé an-chumhachtach.
Réimsí fiosrúcháin a mapáil go réimsíLink to this heading
Léarscáil ``raw () ``réimsí san fhiosrúchán go réimsí ar an tsamhail go huathoibríoch.
Ní cuma ord na réimsí i d'fhiosrúchán. Is é sin le rá, oibríonn an dá cheist seo a leanas go comhionann:
>>> Person.objects.raw("SELECT id, first_name, last_name, birth_date FROM myapp_person")
>>> Person.objects.raw("SELECT last_name, birth_date, first_name, id FROM myapp_person")
Déantar meaitseáil de réir ainm. Ciallaíonn sé seo gur féidir leat clásail ``AS ``SQL a úsáid chun réimsí a mhapáil sna réimsí fiosrúcháin go réimsí samhlacha. Mar sin dá mbeadh tábla éigin eile agat ina raibh sonraí ``Person` ann, d'fhéadfá é a mhapáil go héasca i gcásanna ``Person`:
>>> Person.objects.raw("""
... SELECT first AS first_name,
... last AS last_name,
... bd AS birth_date,
... pk AS id,
... FROM some_other_table
... """)
...
Chomh fada agus a mheaitseálann na hainmneacha, cruthófar na cásanna samhail i gceart.
De rogha air sin, is féidir leat réimsí san fhiosrúchán a mhapáil chuig réimsí samhlacha ag baint úsáide as an argóint aistriúcháin ``go `raw (). Is foclóir é seo a mhapáil ainmneacha réimsí san fhiosrúchán ar ainmneacha réimsí ar an tsamhail. Mar shampla, d'fhéadfaí an cheist thuas a scríobh freisin:
>>> name_map = {"first": "first_name", "last": "last_name", "bd": "birth_date", "pk": "id"}
>>> Person.objects.raw("SELECT * FROM some_other_table", translations=name_map)
Cuardaigh innéacsLink to this heading
Tacaíonn ``raw () ``le hinnéacsú, mar sin mura dteastaíonn ach an chéad toradh uait is féidir leat scríobh:
>>> first_person = Person.objects.raw("SELECT * FROM myapp_person")[0]
Mar sin féin, ní dhéantar an t-innéacsú agus an slisnú ag leibhéal an bhunachar sonraí. Má tá líon mór rudaí ``Person` agat i do bhunachar sonraí, tá sé níos éifeachtaí an cheist a theorannú ag an leibhéal SQL:
>>> first_person = Person.objects.raw("SELECT * FROM myapp_person LIMIT 1")[0]
Réimsí samhail a chur ar iarchurLink to this heading
Féadfar réimsí a fhágáil amach freisin:
>>> people = Person.objects.raw("SELECT id, first_name FROM myapp_person")
Is cásanna samhail iarchurtha iad na rudaí Person a thugtar ar ais leis an gceist seo (féach: meth: `~django.db.models.query.queryset.defer () `). Ciallaíonn sé seo go luchtálfar na réimsí a fhágtar ón gceist ar éileamh. Mar shampla:
>>> for p in Person.objects.raw("SELECT id, first_name FROM myapp_person"):
... print(
... p.first_name, # This will be retrieved by the original query
... p.last_name, # This will be retrieved on demand
... )
...
John Smith
Jane Jones
Ó láithreacha seachtracha, is cosúil go bhfuil an chéad ainm agus an t-ainm deireanach aisghabháilte ag an gceist. Mar sin féin, d'eisigh an sampla seo 3 cheist i ndáiríre. Ní aisghabhadh ach na céadainmneacha tríd an bhfiosrúchán ``raw () ``- aisghabhadh na hainmneacha deireanacha araon ar éileamh nuair a cuireadh priontáil iad.
Níl ach réimse amháin ann nach féidir leat a fhágáil amach - an príomhréimse. Úsáideann Django an príomh-eochair chun cásanna samhail a aithint, mar sin caithfear é a áireamh i gcónaí i gceist amh. A: Class: Ardófar eisceacht ~django.core.exceptions.fieldDoesNotExist má dhéanann tú dearmad an príomh-eochair a áireamh.
Anótaí a chur leisLink to this heading
Is féidir leat ceisteanna a fhorghníomhú ina bhfuil réimsí nach bhfuil sainmhínithe ar an tsamhail. Mar shampla, d'fhéadfaimis feidhm `aois () PostgreSQL a úsáid `__ chun liosta daoine a bhfuil a n-aoiseanna a ríomh ag an mbunachar sonraí a fháil:
>>> people = Person.objects.raw("SELECT *, age(birth_date) AS age FROM myapp_person")
>>> for p in people:
... print("%s is %s." % (p.first_name, p.age))
...
John is 37.
Jane is 42.
...
<func-expressions>Is minic gur féidir leat SQL amh a úsáid chun anótaí a ríomh a sheachaint trí a: ref: `Func () abairt `a úsáid ina ionad sin.
Paraiméadair a chur isteach i ``raw () ``Link to this heading
Más gá duit ceisteanna paraiméadair a dhéanamh, is féidir leat an argóint params` a úsáid chun raw () `:
>>> lname = "Doe"
>>> Person.objects.raw("SELECT * FROM myapp_person WHERE last_name = %s", [lname])
Is liosta nó foclóir paraiméadair é params'. Úsáidfidh tú áitealbhóirí ``%s` sa teaghrán fiosrúcháin le haghaidh liosta, nó % (key) s sealbhóirí áiteacha do fhoclóir (áit a gcuirtear eochair foclóra in ionad eochair), beag beann ar d'inneall bunachar sonraí. Cuirfear paraiméadair ón argóint `params' in ionad sealbhóirí áiteanna den sórt sin.
SQL saincheaptha a fhorghníomhúLink to this heading
Uaireanta fion:meth: ní leor Manager.raw: b'fhéidir go mbeidh ort ceisteanna nach léarscálann go glan ar mhúnlaí a dhéanamh, nó ceisteanna UPDATE, INSERT`, nó DELETE` a fhorghníomhú go díreach.
Sna cásanna seo, is féidir leat rochtain a fháil ar an mbunachar sonraí go díreach i gcónaí, ag ródú timpeall an chiseal múnla
Léiríonn an réad django.db.connection an nasc réamhshocraithe bunachar sonraí. Chun an nasc bunachar sonraí a úsáid, glaoigh ar connection.cursor () ``chun réad cúrsóra a fháil. Ansin, glaoigh ar `cursor.execute (sql, [params]) ``chun an SQL agus `cursor.fetchone () nó `cursor.fetchall () ``a fhorghníomhú chun na sraitheanna mar thoradh air a thabhairt ar ais.
Mar shampla:
from django.db import connection
def my_custom_sql(self):
with connection.cursor() as cursor:
cursor.execute("UPDATE bar SET foo = 1 WHERE baz = %s", [self.baz])
cursor.execute("SELECT foo FROM bar WHERE baz = %s", [self.baz])
row = cursor.fetchone()
return row
Chun cosaint a dhéanamh ar instealladh SQL, níor chóir duit luachana a áireamh timpeall na sealbhóirí %s` sa sreangán SQL.
Tabhair faoi deara más mian leat comharthaí litriúla faoin gcéad a áireamh sa cheist, caithfidh tú iad a dhúbailt sa chás go bhfuil tú ag dul ar pharaiméadair:
cursor.execute("SELECT foo FROM bar WHERE baz = '30%'")
cursor.execute("SELECT foo FROM bar WHERE baz = '30%%' AND id = %s", [self.id])
Má tá tú ag baint úsáidea:doc: níos mó ná bunachar sonraí amháin ', is féidir leat ``django.db.connections` </topics/db/multi-db> a úsáid chun an nasc (agus an cúrsóir) a fháil le haghaidh bunachar sonraí ar leith. Is réad cosúil le foclóir é django.db.connections a ligeann duit nasc ar leith a aisghabháil ag baint úsáide as a ainm:
from django.db import connections
with connections["my_db_alias"].cursor() as cursor:
# Your code here
...
De réir réamhshocraithe, cuirfidh an Python DB API torthaí ar ais gan a n-ainmneacha réimse, rud a chiallaíonn go mbeidh liosta ``luachanna agat, seachas ``dict`. Ar chostas beag feidhmíochta agus cuimhne, is féidir leat torthaí a thabhairt ar ais mar dict trí rud éigin mar seo a úsáid:
def dictfetchall(cursor):
"""
Return all rows from a cursor as a dict.
Assume the column names are unique.
"""
columns = [col[0] for col in cursor.description]
return [dict(zip(columns, row)) for row in cursor.fetchall()]
Rogha eile is ea úsáid:func: collections.namedtuple ó leabharlann caighdeánach Python. Is réad cosúil le feadán é namedtuple a bhfuil réimsí inrochtana ag cuardach tréithe; tá sé innéacsaithe agus in-athraithe freisin. Tá na torthaí inathraithe agus inrochtana trí ainmneacha réimse nó innéacsanna, rud a d'fhéadfadh a bheith úsáideach:
from collections import namedtuple
def namedtuplefetchall(cursor):
"""
Return all rows from a cursor as a namedtuple.
Assume the column names are unique.
"""
desc = cursor.description
nt_result = namedtuple("Result", [col[0] for col in desc])
return [nt_result(*row) for row in cursor.fetchall()]
Glacann na samplaí dictfetchall () ``agus ``namedtuplefetchall () ainmneacha colún uathúla, ós rud é nach féidir le cúrsóir idirdhealú a dhéanamh idir colúin ó tháblaí éagsúla.
Seo sampla den difríocht idir na trí cinn:
>>> cursor.execute("SELECT id, parent_id FROM test LIMIT 2")
>>> cursor.fetchall()
((54360982, None), (54360880, None))
>>> cursor.execute("SELECT id, parent_id FROM test LIMIT 2")
>>> dictfetchall(cursor)
[{'parent_id': None, 'id': 54360982}, {'parent_id': None, 'id': 54360880}]
>>> cursor.execute("SELECT id, parent_id FROM test LIMIT 2")
>>> results = namedtuplefetchall(cursor)
>>> results
[Result(id=54360982, parent_id=None), Result(id=54360880, parent_id=None)]
>>> results[0].id
54360982
>>> results[0][0]
54360982
Naisc agus cúrsaíLink to this heading
Forfheidhmíonn nasc agus cursor den chuid is mó an Python DB-API caighdeánach a thuairiscítear in:pep: 249 - ach </topics/db/transactions> amháin maidir le: doc: láimhseáil idirbhearta.
Mura bhfuil tú eolach ar an Python DB-API, tabhair faoi deara go n-úsáideann an ráiteas SQL i cursor.execute () ``sealbhóirí ionaid, `"%s"`, seachas paraiméadair a chur go díreach laistigh den SQL. Má úsáideann tú an teicníc seo, éalóidh an leabharlann bunachar sonraí bunúsach do pharaiméadair go huathoi
Tabhair faoi deara freisin go bhfuil Django ag súil leis an áitealbhóir "%s", * ní* an ``”? ``sealbhóir áit, a úsáideann na ceangail SQLite Python. Tá sé seo ar mhaithe le comhsheasmhacht agus sláine.
Cúrsóir a úsáid mar bhainisteoir comhthéacs:
with connection.cursor() as c:
c.execute(...)
atá coibhéiseach le:
c = connection.cursor()
try:
c.execute(...)
finally:
c.close()
Nósanna imeachta stóráilteLink to this heading
- CursorWrapper.callproc(procname, params=None, kparams=None)Link to this definition
Glaonn sé nós imeachta stóráilte bunachar sonraí leis an ainm tugtha. Féadfar seicheamh (params`) nó foclóir (kparams`) de pharaiméadair ionchuir a sholáthar. Ní thacaíonn an chuid is mó de na bunachair sonraí le
kparams. De chúltaca ionsuite Django, ní thacaíonn ach Oracle leis.Mar shampla, de bharr an nós imeachta stóráilte seo i mbunachar sonraí Oracle:
CREATE PROCEDURE "TEST_PROCEDURE"(v_i INTEGER, v_text NVARCHAR2(10)) AS p_i INTEGER; p_text NVARCHAR2(10); BEGIN p_i := v_i; p_text := v_text; ... END;Déanfaidh sé seo glaoch air:
with connection.cursor() as cursor: cursor.callproc("test_procedure", [1, "test"])