{"id":32760,"date":"2025-10-25T17:32:38","date_gmt":"2025-10-25T14:32:38","guid":{"rendered":"https:\/\/fatihsoysal.com\/blog\/veritabani-iliskileri-neden-hayati-onem-tasir-temel-kavramlara-giris\/"},"modified":"2025-10-25T17:32:38","modified_gmt":"2025-10-25T14:32:38","slug":"veritabani-iliskileri-neden-hayati-onem-tasir-temel-kavramlara-giris","status":"publish","type":"post","link":"https:\/\/fatihsoysal.com\/blog\/veritabani-iliskileri-neden-hayati-onem-tasir-temel-kavramlara-giris\/","title":{"rendered":"Veritaban\u0131 \u0130li\u015fkileri Neden Hayati \u00d6nem Ta\u015f\u0131r? Temel Kavramlara Giri\u015f"},"content":{"rendered":"<p><body><\/p>\n<h1>Flask-SQLAlchemy \u0130li\u015fkilerini Anlama: <code>relationship<\/code> ve <code>association_proxy<\/code><\/h1>\n<p>Flask-SQLAlchemy ile veritaban\u0131 ili\u015fkilerini anlamak ve etkili y\u00f6netmek, sa\u011flam web uygulamalar\u0131 i\u00e7in hayati. Bu makale, <code>db.relationship<\/code> ve <code>association_proxy<\/code>&#8216;yi derinlemesine inceleyerek veri modellerinizi g\u00fc\u00e7lendirmenin yollar\u0131n\u0131 sunuyor. Uygulamalar\u0131n\u0131zda karma\u015f\u0131k veri yap\u0131lar\u0131n\u0131 basit ve anla\u015f\u0131l\u0131r bir \u015fekilde temsil etmek, gelecekteki bak\u0131m\u0131n\u0131 ve geni\u015flemesini do\u011frudan etkiler. Flask uygulamalar\u0131n\u0131zda veritaban\u0131 ili\u015fkileri konusunda zorlan\u0131yorsan\u0131z veya bilginizi peki\u015ftirmek istiyorsan\u0131z, do\u011fru yerdesiniz.<\/p>\n<p>G\u00fcn\u00fcm\u00fcz uygulamalar\u0131n\u0131n neredeyse tamam\u0131, birbirinden farkl\u0131 ancak ili\u015fkili veri par\u00e7ac\u0131klar\u0131yla \u00e7al\u0131\u015f\u0131r. \u00d6rne\u011fin, bir sosyal medya platformunda kullan\u0131c\u0131lar, g\u00f6nderiler ve yorumlar aras\u0131nda mant\u0131ksal ba\u011flant\u0131lar vard\u0131r. Bu ba\u011flant\u0131lar\u0131 veritaban\u0131 seviyesinde do\u011fru bir \u015fekilde kurmak, verilerin tutarl\u0131l\u0131\u011f\u0131n\u0131 sa\u011flamak, gereksiz tekrar\u0131 \u00f6nlemek ve sorgulama i\u015flemlerini optimize etmek i\u00e7in kritik \u00f6neme sahiptir. Flask-SQLAlchemy, bu ili\u015fkisel yap\u0131y\u0131 Python objeleri arac\u0131l\u0131\u011f\u0131yla y\u00f6netmemizi sa\u011flayan g\u00fc\u00e7l\u00fc bir Nesne \u0130li\u015fkisel E\u015fleyici (ORM) arac\u0131d\u0131r.<\/p>\n<p>Veritaban\u0131 ili\u015fkileri genellikle \u00fc\u00e7 ana kategoride incelenir:<\/p>\n<ul>\n<li>\n            <strong>Bire \u00c7ok (One-to-Many):<\/strong> Bir varl\u0131\u011f\u0131n (\u00f6rne\u011fin bir yazar\u0131n) birden \u00e7ok ili\u015fkili varl\u0131\u011fa (\u00f6rne\u011fin kitaplar\u0131na) sahip oldu\u011fu durumu ifade eder. Bu senaryoda, yazar tablosundaki her sat\u0131r, kitap tablosundaki birden \u00e7ok sat\u0131rla ili\u015fkilendirilebilir. Kitap tablosunda, yazar\u0131n birincil anahtar\u0131n\u0131 g\u00f6steren bir <a href=\"#\" title=\"Yabanc\u0131 Anahtar Nedir?\">yabanc\u0131 anahtar (Foreign Key)<\/a> bulunur.\n        <\/li>\n<li>\n            <strong>\u00c7o\u011fa Bir (Many-to-One):<\/strong> Bire \u00c7ok ili\u015fkisinin tersidir. Birden \u00e7ok varl\u0131\u011f\u0131n (\u00f6rne\u011fin bir\u00e7ok kitab\u0131n) tek bir varl\u0131kla (\u00f6rne\u011fin tek bir yazarla) ili\u015fkili olmas\u0131d\u0131r. Asl\u0131nda Bire \u00c7ok ili\u015fkisinin di\u011fer taraftan bak\u0131\u015f a\u00e7\u0131s\u0131d\u0131r.\n        <\/li>\n<li>\n            <strong>\u00c7o\u011fa \u00c7ok (Many-to-Many):<\/strong> Daha karma\u015f\u0131k bir ili\u015fkidir. Bir varl\u0131\u011f\u0131n birden \u00e7ok ili\u015fkili varl\u0131\u011fa sahip olabildi\u011fi ve bu ili\u015fkili varl\u0131klar\u0131n da ayn\u0131 \u015fekilde birden \u00e7ok ana varl\u0131\u011fa sahip olabildi\u011fi durumu tan\u0131mlar. \u00d6rne\u011fin, bir \u00fcr\u00fcn\u00fcn birden \u00e7ok etiketi olabilir ve bir etiket de birden \u00e7ok \u00fcr\u00fcne sahip olabilir. Bu t\u00fcr ili\u015fkiler, genellikle arac\u0131 bir tablo (association table) arac\u0131l\u0131\u011f\u0131yla kurulur. Bu arac\u0131 tablo, her iki ana tablonun birincil anahtarlar\u0131n\u0131 yabanc\u0131 anahtar olarak i\u00e7erir.\n        <\/li>\n<\/ul>\n<p class=\"interactive-tip\">Uzman \u0130pucu: \u0130li\u015fkisel veritaban\u0131 tasar\u0131m\u0131nda yabanc\u0131 anahtarlar\u0131n do\u011fru tan\u0131mlanmas\u0131, veri b\u00fct\u00fcnl\u00fc\u011f\u00fcn\u00fc sa\u011flar ve ili\u015fkili veriler \u00fczerinde silme (CASCADE) veya g\u00fcncelleme (SET NULL) gibi operasyonlar\u0131n nas\u0131l davranaca\u011f\u0131n\u0131 belirler. Bu, uygulaman\u0131z\u0131n kararl\u0131l\u0131\u011f\u0131 i\u00e7in temel bir ad\u0131md\u0131r.<\/p>\n<p>Flask-SQLAlchemy, bu ili\u015fkisel yap\u0131lar\u0131 Python s\u0131n\u0131flar\u0131 ve \u00f6zellikleri arac\u0131l\u0131\u011f\u0131yla tan\u0131mlamam\u0131za olanak tan\u0131r. Veritaban\u0131 tablolar\u0131n\u0131z, Python s\u0131n\u0131flar\u0131na, tablolar\u0131n s\u00fctunlar\u0131 ise bu s\u0131n\u0131flar\u0131n \u00f6zelliklerine kar\u015f\u0131l\u0131k gelir. \u0130li\u015fkiler ise <code>db.relationship<\/code> fonksiyonu ile tan\u0131mlanarak, iki model aras\u0131nda gezinebilir bir k\u00f6pr\u00fc olu\u015fturur. Bu sayede SQL sorgular\u0131 yazmak yerine, Python objeleri \u00fczerinde metod \u00e7a\u011f\u0131rarak veya \u00f6zelliklere eri\u015ferek verilerle \u00e7al\u0131\u015fabiliriz. Bu yakla\u015f\u0131m, geli\u015ftirme h\u0131z\u0131n\u0131 art\u0131r\u0131r ve kodun okunabilirli\u011fini \u00f6nemli \u00f6l\u00e7\u00fcde iyile\u015ftirir.<\/p>\n<h2><code>db.relationship<\/code> ile Modeller Aras\u0131 K\u00f6pr\u00fcler Kurmak: Ad\u0131m Ad\u0131m Rehber<\/h2>\n<p><code>db.relationship<\/code>, SQLAlchemy&#8217;nin en g\u00fc\u00e7l\u00fc \u00f6zelliklerinden biridir ve Python objeleri aras\u0131nda gezinebilir ba\u011flant\u0131lar kurman\u0131z\u0131 sa\u011flar. Bu sayede, bir <code>Yazar<\/code> objesinden o yazar\u0131n t\u00fcm <code>Kitap<\/code> objelerine veya bir <code>Kitap<\/code> objesinden yazar\u0131n\u0131n <code>Yazar<\/code> objesine kolayca eri\u015febilirsiniz. \u0130li\u015fkileri do\u011fru bir \u015fekilde tan\u0131mlamak, uygulaman\u0131z\u0131n veri modelini mant\u0131ksal olarak g\u00fc\u00e7l\u00fc k\u0131lar ve sorgulama i\u015flemlerini basitle\u015ftirir. \u015eimdi gelin, bu ili\u015fkileri pratik \u00f6rneklerle inceleyelim.<\/p>\n<h3>Bire \u00c7ok \u0130li\u015fkileri Nas\u0131l Olu\u015ftururuz? (Yazar-Kitap \u00d6rne\u011fi)<\/h3>\n<p>En basit ve yayg\u0131n ili\u015fki t\u00fcrlerinden biri Bire \u00c7ok ili\u015fkidir. Bir yazar\u0131n birden \u00e7ok kitab\u0131 oldu\u011funu varsayal\u0131m. Her kitab\u0131n bir yazar\u0131 olmal\u0131, ancak bir yazar\u0131n birden \u00e7ok kitab\u0131 olabilir. \u0130\u015fte bu senaryoyu Flask-SQLAlchemy ile nas\u0131l modelleyece\u011fimize dair bir \u00f6rnek:<\/p>\n<pre><code>\nfrom flask import Flask\nfrom flask_sqlalchemy import SQLAlchemy\n\napp = Flask(__name__)\napp.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:\/\/\/site.db'\napp.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False\ndb = SQLAlchemy(app)\n\nclass Yazar(db.Model):\n    id = db.Column(db.Integer, primary_key=True)\n    isim = db.Column(db.String(100), nullable=False)\n    # Bir yazar\u0131n birden \u00e7ok kitab\u0131 olabilir\n    kitaplar = db.relationship('Kitap', backref='yazar', lazy=True)\n\n    def __repr__(self):\n        return f\"Yazar('{self.isim}')\"\n\nclass Kitap(db.Model):\n    id = db.Column(db.Integer, primary_key=True)\n    baslik = db.Column(db.String(200), nullable=False)\n    yayin_yili = db.Column(db.Integer)\n    # Her kitab\u0131n bir yazar\u0131 olmal\u0131 (Yabanc\u0131 Anahtar)\n    yazar_id = db.Column(db.Integer, db.ForeignKey('yazar.id'), nullable=False)\n\n    def __repr__(self):\n        return f\"Kitap('{self.baslik}', '{self.yazar_id}')\"\n\n# Uygulama ba\u011flam\u0131nda veritaban\u0131 tablolar\u0131n\u0131 olu\u015fturma ve \u00f6rnek veri ekleme\nwith app.app_context():\n    db.create_all()\n\n    # E\u011fer veriler yoksa ekle\n    if not Yazar.query.first():\n        yazar1 = Yazar(isim='George Orwell')\n        yazar2 = Yazar(isim='Aldous Huxley')\n        db.session.add_all([yazar1, yazar2])\n        db.session.commit()\n\n        kitap1 = Kitap(baslik='1984', yayin_yili=1949, yazar=yazar1)\n        kitap2 = Kitap(baslik='Hayvan \u00c7iftli\u011fi', yayin_yili=1945, yazar=yazar1)\n        kitap3 = Kitap(baslik='Cesur Yeni D\u00fcnya', yayin_yili=1932, yazar=yazar2)\n        db.session.add_all([kitap1, kitap2, kitap3])\n        db.session.commit()\n\n    # Verileri sorgulama ve ili\u015fki \u00fczerinden eri\u015fim\n    orwell = Yazar.query.filter_by(isim='George Orwell').first()\n    if orwell:\n        print(f\"{orwell.isim}'in kitaplar\u0131:\")\n        for kitap in orwell.kitaplar: # <code>db.relationship<\/code> sayesinde do\u011frudan eri\u015fim\n            print(f\"  - {kitap.baslik}\")\n\n    kitap_1984 = Kitap.query.filter_by(baslik='1984').first()\n    if kitap_1984:\n        print(f\"'1984' kitab\u0131n\u0131n yazar\u0131: {kitap_1984.yazar.isim}\") # <code>backref<\/code> sayesinde do\u011frudan eri\u015fim\n    <\/pre>\n<p><\/code><\/p>\n<p>Bu \u00f6rnekte, <code>Yazar<\/code> modelindeki <code>kitaplar<\/code> \u00f6zelli\u011fi, <code>Kitap<\/code> modeline bir ili\u015fki tan\u0131mlar. <code>backref=&#039;yazar&#039;<\/code> parametresi, <code>Kitap<\/code> modeli \u00fczerinde otomatik olarak <code>yazar<\/code> ad\u0131nda bir \u00f6zellik olu\u015fturur ve bu \u00f6zellik sayesinde bir kitaptan yazar\u0131na kolayca eri\u015febiliriz. <code>lazy=True<\/code> ise, ili\u015fkili verilerin (\u00f6rne\u011fin bir yazar\u0131n kitaplar\u0131n\u0131n) ancak ihtiya\u00e7 duyuldu\u011funda y\u00fcklenece\u011fini belirtir. Bu, gereksiz veritaban\u0131 sorgular\u0131n\u0131 \u00f6nleyerek performans\u0131 art\u0131r\u0131r.<\/p>\n<h3>\u00c7o\u011fa \u00c7ok \u0130li\u015fkiler ve Yard\u0131mc\u0131 Tablolar Nas\u0131l Tan\u0131mlan\u0131r? (Kitap-Kategori \u00d6rne\u011fi)<\/h3>\n<p>\u00c7o\u011fa \u00c7ok ili\u015fkiler, <code>db.relationship<\/code> ile biraz daha farkl\u0131 bir yakla\u015f\u0131mla ele al\u0131n\u0131r. Bu t\u00fcr ili\u015fkilerde, iki ana tablo aras\u0131nda do\u011frudan bir yabanc\u0131 anahtar ili\u015fkisi kurmak yerine, arac\u0131 bir tablo (association table) kullan\u0131l\u0131r. Bu arac\u0131 tablo, her iki ana tablonun birincil anahtarlar\u0131n\u0131 yabanc\u0131 anahtar olarak tutar. \u00d6rne\u011fin, bir kitab\u0131n birden \u00e7ok kategorisi olabilir ve bir kategori de birden \u00e7ok kitaba sahip olabilir.<\/p>\n<pre><code>\n# ... \u00f6nceki kodlar (app, db, Yazar, Kitap s\u0131n\u0131flar\u0131) ...\n\n# \u00c7o\u011fa \u00c7ok ili\u015fkisi i\u00e7in yard\u0131mc\u0131 tablo\nkitap_kategorileri = db.Table('kitap_kategorileri',\n    db.Column('kitap_id', db.Integer, db.ForeignKey('kitap.id'), primary_key=True),\n    db.Column('kategori_id', db.Integer, db.ForeignKey('kategori.id'), primary_key=True)\n)\n\nclass Kategori(db.Model):\n    id = db.Column(db.Integer, primary_key=True)\n    isim = db.Column(db.String(50), unique=True, nullable=False)\n    # Bir kategorinin birden \u00e7ok kitab\u0131 olabilir\n    kitaplar = db.relationship('Kitap', secondary=kitap_kategorileri,\n                               backref=db.backref('kategoriler', lazy=True), lazy=True)\n\n    def __repr__(self):\n        return f\"Kategori('{self.isim}')\"\n\n# Uygulama ba\u011flam\u0131nda veritaban\u0131 tablolar\u0131n\u0131 olu\u015fturma ve \u00f6rnek veri ekleme\nwith app.app_context():\n    db.create_all()\n\n    # \u00d6rnek veri ekleme\n    if not Kategori.query.first():\n        kategori_bilimkurgu = Kategori(isim='Bilim Kurgu')\n        kategori_distopya = Kategori(isim='Distopya')\n        kategori_klasik = Kategori(isim='Klasik')\n        db.session.add_all([kategori_bilimkurgu, kategori_distopya, kategori_klasik])\n        db.session.commit()\n\n        kitap_1984 = Kitap.query.filter_by(baslik='1984').first()\n        kitap_hayvan_ciftligi = Kitap.query.filter_by(baslik='Hayvan \u00c7iftli\u011fi').first()\n        kitap_cesur_yeni_dunya = Kitap.query.filter_by(baslik='Cesur Yeni D\u00fcnya').first()\n\n        if kitap_1984 and kategori_bilimkurgu and kategori_distopya:\n            kitap_1984.kategoriler.append(kategori_bilimkurgu)\n            kitap_1984.kategoriler.append(kategori_distopya)\n        if kitap_hayvan_ciftligi and kategori_klasik:\n            kitap_hayvan_ciftligi.kategoriler.append(kategori_klasik)\n        if kitap_cesur_yeni_dunya and kategori_bilimkurgu and kategori_distopya:\n            kitap_cesur_yeni_dunya.kategoriler.append(kategori_bilimkurgu)\n            kitap_cesur_yeni_dunya.kategoriler.append(kategori_distopya)\n        db.session.commit()\n\n    # \u0130li\u015fki \u00fczerinden sorgulama\n    bilim_kurgu_kategorisi = Kategori.query.filter_by(isim='Bilim Kurgu').first()\n    if bilim_kurgu_kategorisi:\n        print(f\"'{bilim_kurgu_kategorisi.isim}' kategorisindeki kitaplar:\")\n        for kitap in bilim_kurgu_kategorisi.kitaplar:\n            print(f\"  - {kitap.baslik}\")\n\n    kitap_1984_sorgu = Kitap.query.filter_by(baslik='1984').first()\n    if kitap_1984_sorgu:\n        print(f\"'{kitap_1984_sorgu.baslik}' kitab\u0131n\u0131n kategorileri:\")\n        for kategori in kitap_1984_sorgu.kategoriler:\n            print(f\"  - {kategori.isim}\")\n    <\/pre>\n<p><\/code><\/p>\n<p>Burada <code>kitap_kategorileri<\/code> ad\u0131nda ayr\u0131 bir tablo olu\u015fturduk. Bu tablo, ne bir <code>Kitap<\/code> modelidir ne de bir <code>Kategori<\/code> modeli, sadece ikisi aras\u0131ndaki ba\u011flant\u0131y\u0131 kurmaya yarayan bir arac\u0131 tablodur. <code>Kategori<\/code> modelindeki <code>db.relationship<\/code>, <code>secondary=kitap_kategorileri<\/code> parametresiyle bu arac\u0131 tabloyu kullanaca\u011f\u0131n\u0131 belirtir. <code>backref<\/code> ile <code>Kitap<\/code> modelinden <code>kategoriler<\/code> \u00f6zelli\u011fine eri\u015fim sa\u011flan\u0131r. Bu yap\u0131, \u00c7o\u011fa \u00c7ok ili\u015fkilerin esnekli\u011fini ve y\u00f6netimini basitle\u015ftirir.<\/p>\n<h2><code>association_proxy<\/code> Nedir ve Ne Zaman Kullanmal\u0131y\u0131z?<\/h2>\n<p>\u00c7o\u011fa \u00c7ok ili\u015fkilerde arac\u0131 tablolar\u0131n kullan\u0131lmas\u0131 ka\u00e7\u0131n\u0131lmazd\u0131r. Ancak bazen bu arac\u0131 tablolara do\u011frudan eri\u015fmek yerine, hedef tablodaki belirli bir \u00f6zelli\u011fe daha do\u011frudan ve temiz bir \u015fekilde eri\u015fmek isteyebiliriz. \u0130\u015fte bu noktada <code>association_proxy<\/code> devreye girer. <code>association_proxy<\/code>, ara ili\u015fkisel nesneyi gizleyerek, koleksiyon veya tekil nesne \u00fczerinde istenen bir \u00f6zelli\u011fe do\u011frudan eri\u015fim sa\u011flar. B\u00f6ylece kodumuz daha okunakl\u0131 ve sezgisel hale gelir.<\/p>\n<h3><code>association_proxy<\/code> ile Basitle\u015ftirilmi\u015f Eri\u015fim Nas\u0131l Sa\u011flan\u0131r?<\/h3>\n<p>Yukar\u0131daki Kitap-Kategori \u00f6rne\u011fine geri d\u00f6nelim. Bir <code>Kitap<\/code> nesnesinden kategorilerin isimlerine do\u011frudan eri\u015fmek istedi\u011fimizde, \u015fu anda <code>kitap.kategoriler[0].isim<\/code> gibi bir yap\u0131 kullanmam\u0131z gerekiyor. E\u011fer sadece kategorilerin isimlerini i\u00e7eren bir liste isteseydik, <code>[k.isim for k in kitap.kategoriler]<\/code> gibi bir liste tamamlama kullanmam\u0131z gerekirdi. <code>association_proxy<\/code> bu t\u00fcr senaryolar\u0131 daha Pythonic ve okunabilir hale getirir.<\/p>\n<p><code>association_proxy<\/code>'yi kullanmak i\u00e7in <code>sqlalchemy.ext.associationproxy<\/code> mod\u00fcl\u00fcnden i\u00e7e aktarmam\u0131z gerekir:<\/p>\n<pre><code>\n# ... \u00f6nceki kodlar (app, db, Yazar, Kitap, Kategori s\u0131n\u0131flar\u0131 ve kitap_kategorileri tablosu) ...\nfrom sqlalchemy.ext.associationproxy import association_proxy\n\nclass Kitap(db.Model):\n    id = db.Column(db.Integer, primary_key=True)\n    baslik = db.Column(db.String(200), nullable=False)\n    yayin_yili = db.Column(db.Integer)\n    yazar_id = db.Column(db.Integer, db.ForeignKey('yazar.id'), nullable=False)\n\n    yazar = db.relationship('Yazar', backref='kitaplar', lazy=True)\n    kategoriler_iliskisi = db.relationship('Kategori', secondary=kitap_kategorileri,\n                                       backref=db.backref('kitaplar', lazy=True), lazy=True)\n\n    # <code>association_proxy<\/code> kullanarak kategorilerin isimlerine do\u011frudan eri\u015fim\n    kategori_isimleri = association_proxy('kategoriler_iliskisi', 'isim')\n\n    def __repr__(self):\n        return f\"Kitap('{self.baslik}', '{self.yazar_id}')\"\n\n# Uygulama ba\u011flam\u0131nda veritaban\u0131 tablolar\u0131n\u0131 olu\u015fturma (\u00d6nceki veri ekleme ad\u0131mlar\u0131n\u0131 tekrarlay\u0131n)\nwith app.app_context():\n    # ... (\u00d6nceki Yazar, Kitap ve Kategori veri ekleme ad\u0131mlar\u0131 burada tekrar \u00e7al\u0131\u015ft\u0131r\u0131labilir) ...\n\n    kitap_1984_sorgu = Kitap.query.filter_by(baslik='1984').first()\n    if kitap_1984_sorgu:\n        print(f\"'{kitap_1984_sorgu.baslik}' kitab\u0131n\u0131n kategori isimleri (proxy ile):\")\n        for isim in kitap_1984_sorgu.kategori_isimleri:\n            print(f\"  - {isim}\")\n\n    # Yeni bir kategori ismi eklemeyi deneyelim (proxy \u00fczerinden)\n    # NOT: Bu basit haliyle, 'Modern Klasik' ad\u0131nda yeni bir Kategori objesi otomatik olu\u015fturulmaz.\n    # Bunun i\u00e7in 'creator' parametresiyle bir fonksiyon tan\u0131mlamak gerekir.\n    # \u00d6rne\u011fin: kategori_isimleri = association_proxy('kategoriler_iliskisi', 'isim', creator=lambda isim: Kategori(isim=isim))\n    # Bu \u00f6rnekte sadece proxy'nin okuma yetene\u011fini g\u00f6steriyoruz.\n    if 'Modern Klasik' not in kitap_1984_sorgu.kategori_isimleri:\n        # E\u011fer creator tan\u0131mlanmam\u0131\u015fsa, bu kod Kategori objesi olu\u015fturmaz,\n        # sadece proxy'nin bir string eklemesini sim\u00fcle eder. Ger\u00e7ek ekleme i\u00e7in creator gerekir.\n        pass # print(\"Yeni kategori eklemek i\u00e7in 'creator' parametresi gereklidir.\")\n\n    # Kontrol edelim (Yukar\u0131daki append i\u015flemi ger\u00e7ek veritaban\u0131 de\u011fi\u015fikli\u011fi yapmazd\u0131 bu haliyle)\n    kitap_1984_sorgu_yeniden = Kitap.query.filter_by(baslik='1984').first()\n    if kitap_1984_sorgu_yeniden:\n        print(f\"'{kitap_1984_sorgu_yeniden.baslik}' kitab\u0131n\u0131n g\u00fcncel kategori isimleri:\")\n        for isim in kitap_1984_sorgu_yeniden.kategori_isimleri:\n            print(f\"  - {isim}\")\n    <\/pre>\n<p><\/code><\/p>\n<p>Yukar\u0131daki \u00f6rnekte, <code>Kitap<\/code> modeline <code>kategori_isimleri<\/code> ad\u0131nda bir <code>association_proxy<\/code> ekledik. Bu proxy, <code>kategoriler_iliskisi<\/code> ad\u0131n\u0131 verdi\u011fimiz <code>db.relationship<\/code> \u00fczerinden <code>Kategori<\/code> nesnelerinin <code>isim<\/code> \u00f6zelli\u011fine do\u011frudan eri\u015fim sa\u011flar. Art\u0131k bir kitab\u0131n kategorilerine, aradaki <code>Kategori<\/code> objesini d\u00fc\u015f\u00fcnmeden, sanki do\u011frudan bir string listesiymi\u015f gibi eri\u015febiliriz: <code>kitap.kategori_isimleri<\/code>. Proxy'ler sadece okuma ama\u00e7l\u0131 de\u011fildir; <code>creator<\/code> ve <code>setter<\/code> parametreleri ile \u00f6zelle\u015ftirilerek yeni de\u011ferler eklemek veya mevcut de\u011ferleri de\u011fi\u015ftirmek i\u00e7in de kullan\u0131labilirler. Ancak, yeni bir kategori eklerken <code>association_proxy<\/code> taraf\u0131ndan ger\u00e7ek <code>Kategori<\/code> objesinin otomatik olarak olu\u015fturulmas\u0131 i\u00e7in <code>creator<\/code> parametresiyle bir fonksiyon tan\u0131mlamak gerekir.<\/p>\n<p class=\"interactive-tip\">Uzman \u0130pucu: <code>association_proxy<\/code>'yi kullan\u0131rken, \u00f6zellikle yazma i\u015flemleri i\u00e7in (ekleme, g\u00fcncelleme), proxy'nin arkas\u0131ndaki karma\u015f\u0131k mant\u0131\u011f\u0131 iyi anlamak \u00f6nemlidir. <code>creator<\/code> ve <code>setter<\/code> arg\u00fcmanlar\u0131n\u0131 kullanarak, proxy'nin bu i\u015flemleri nas\u0131l ger\u00e7ekle\u015ftirece\u011fini \u00f6zelle\u015ftirebilirsiniz. Bu sayede, arac\u0131 tabloya manuel m\u00fcdahale etmeden veri ekleme veya silme i\u015flemlerini ger\u00e7ekle\u015ftirebilirsiniz.<\/p>\n<h2>Ger\u00e7ek D\u00fcnya Uygulamas\u0131: E-ticaret Sepeti ve \u0130li\u015fkisel Veri Modeli<\/h2>\n<p>\u015eimdiye kadar \u00f6\u011frendiklerimizi bir araya getirerek, ger\u00e7ek bir e-ticaret uygulamas\u0131 senaryosunu inceleyelim. Bir e-ticaret uygulamas\u0131nda genellikle Kullan\u0131c\u0131lar, \u00dcr\u00fcnler, Sipari\u015fler ve bu sipari\u015flerin i\u00e7indeki \u00fcr\u00fcnler (Sipari\u015f Kalemleri) gibi bir\u00e7ok farkl\u0131 varl\u0131k bulunur. Bu varl\u0131klar aras\u0131ndaki ili\u015fkileri Flask-SQLAlchemy ile nas\u0131l modelleyebiliriz ve <code>association_proxy<\/code>'nin burada bize ne gibi kolayl\u0131klar sa\u011flayaca\u011f\u0131n\u0131 g\u00f6relim. \u00d6zellikle Sipari\u015f Kalemi gibi arac\u0131 modeller, ek \u00f6zellikler bar\u0131nd\u0131rd\u0131\u011f\u0131nda <code>association_proxy<\/code> ile daha temiz eri\u015fim elde edilebilir.<\/p>\n<pre><code>\nfrom flask import Flask\nfrom flask_sqlalchemy import SQLAlchemy\nfrom sqlalchemy.ext.associationproxy import association_proxy\nfrom datetime import datetime\n\napp = Flask(__name__)\napp.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:\/\/\/ecommerce.db'\napp.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False\ndb = SQLAlchemy(app)\n\nclass Kullanici(db.Model):\n    id = db.Column(db.Integer, primary_key=True)\n    isim = db.Column(db.String(100), nullable=False)\n    email = db.Column(db.String(120), unique=True, nullable=False)\n    siparisler = db.relationship('Siparis', backref='kullanici', lazy=True)\n\n    def __repr__(self):\n        return f\"Kullanici('{self.isim}', '{self.email}')\"\n\nclass Urun(db.Model):\n    id = db.Column(db.Integer, primary_key=True)\n    ad = db.Column(db.String(100), nullable=False)\n    fiyat = db.Column(db.Float, nullable=False)\n    stok = db.Column(db.Integer, default=0)\n\n    def __repr__(self):\n        return f\"Urun('{self.ad}', {self.fiyat})\"\n\nclass Siparis(db.Model):\n    id = db.Column(db.Integer, primary_key=True)\n    kullanici_id = db.Column(db.Integer, db.ForeignKey('kullanici.id'), nullable=False)\n    siparis_tarihi = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)\n    toplam_fiyat = db.Column(db.Float, default=0.0)\n\n    siparis_kalemleri = db.relationship('SiparisKalemi', backref='siparis', lazy=True, cascade=\"all, delete-orphan\")\n\n    # Sipari\u015fteki \u00fcr\u00fcnlerin isimlerine do\u011frudan eri\u015fim i\u00e7in association_proxy\n    urun_isimleri = association_proxy('siparis_kalemleri', 'urun_ad')\n\n    def __repr__(self):\n        return f\"Siparis('{self.id}', Kullanici:'{self.kullanici_id}', Tarih:'{self.siparis_tarihi}')\"\n\nclass SiparisKalemi(db.Model):\n    id = db.Column(db.Integer, primary_key=True)\n    siparis_id = db.Column(db.Integer, db.ForeignKey('siparis.id'), nullable=False)\n    urun_id = db.Column(db.Integer, db.ForeignKey('urun.id'), nullable=False)\n    adet = db.Column(db.Integer, nullable=False, default=1)\n    birim_fiyat = db.Column(db.Float, nullable=False)\n\n    urun = db.relationship('Urun', lazy=True)\n\n    @property # association_proxy i\u00e7in gerekli olan yard\u0131mc\u0131 \u00f6zellik\n    def urun_ad(self):\n        return self.urun.ad if self.urun else None\n\n    def __repr__(self):\n        return f\"SiparisKalemi(Urun:'{self.urun_id}', Adet:'{self.adet}')\"\n\n# Uygulama ba\u011flam\u0131nda veritaban\u0131 tablolar\u0131n\u0131 olu\u015fturma ve \u00f6rnek veri ekleme\nwith app.app_context():\n    db.create_all()\n\n    if not Kullanici.query.first(): # Sadece veri taban\u0131 bo\u015fsa ekle\n        kullanici1 = Kullanici(isim='Mehmet Y\u0131lmaz', email='mehmet@example.com')\n        kullanici2 = Kullanici(isim='Ay\u015fe Demir', email='ayse@example.com')\n        db.session.add_all([kullanici1, kullanici2])\n        db.session.commit()\n\n        urun1 = Urun(ad='Laptop', fiyat=1200.0, stok=10)\n        urun2 = Urun(ad='Mouse', fiyat=25.0, stok=50)\n        urun3 = Urun(ad='Klavye', fiyat=75.0, stok=20)\n        db.session.add_all([urun1, urun2, urun3])\n        db.session.commit()\n\n        siparis1 = Siparis(kullanici=kullanici1)\n        db.session.add(siparis1)\n        db.session.commit()\n\n        kalem1 = SiparisKalemi(siparis=siparis1, urun=urun1, adet=1, birim_fiyat=urun1.fiyat)\n        kalem2 = SiparisKalemi(siparis=siparis1, urun=urun2, adet=2, birim_fiyat=urun2.fiyat)\n        db.session.add_all([kalem1, kalem2])\n        db.session.commit()\n\n        siparis1.toplam_fiyat = sum(kalem.adet * kalem.birim_fiyat for kalem in siparis1.siparis_kalemleri)\n        db.session.commit()\n\n    # Verileri sorgulama ve ili\u015fki \u00fczerinden eri\u015fim\n    mehmet = Kullanici.query.filter_by(isim='Mehmet Y\u0131lmaz').first()\n    if mehmet:\n        print(f\"{mehmet.isim}'in sipari\u015fleri:\")\n        for siparis in mehmet.siparisler:\n            print(f\"  Sipari\u015f ID: {siparis.id}, Toplam Fiyat: {siparis.toplam_fiyat}\")\n            print(\"    \u00dcr\u00fcnler (proxy ile):\")\n            for urun_ad in siparis.urun_isimleri:\n                print(f\"      - {urun_ad}\")\n    <\/pre>\n<p><\/code><\/p>\n<p>Bu senaryoda, <code>SiparisKalemi<\/code> modeli asl\u0131nda <code>Siparis<\/code> ve <code>Urun<\/code> aras\u0131ndaki \u00c7o\u011fa \u00c7ok ili\u015fkisini temsil eden bir arac\u0131 tablodur. Ancak bu tablo, sadece ID'leri tutmakla kalm\u0131yor, ayn\u0131 zamanda <code>adet<\/code> ve <code>birim_fiyat<\/code> gibi ili\u015fkiye \u00f6zg\u00fc ek \u00f6zellikler de bar\u0131nd\u0131r\u0131yor. Bu, saf bir association table'dan farkl\u0131 olarak, do\u011frudan bir model haline gelmesini gerektiriyor. Burada <code>association_proxy<\/code>'nin g\u00fcc\u00fcn\u00fc <code>Siparis<\/code> modelindeki <code>urun_isimleri<\/code> \u00f6zelli\u011finde g\u00f6r\u00fcyoruz.<\/p>\n<p><code>SiparisKalemi<\/code> modelinde <code>urun_ad<\/code> ad\u0131nda bir <code>@property<\/code> tan\u0131mlayarak, bu kalemin ili\u015fkili oldu\u011fu \u00fcr\u00fcn\u00fcn ad\u0131n\u0131 kolayca alabiliyoruz. Ard\u0131ndan, <code>Siparis<\/code> modelinde <code>association_proxy(&#039;siparis_kalemleri&#039;, &#039;urun_ad&#039;)<\/code> tan\u0131m\u0131yla, bir sipari\u015fe ait \u00fcr\u00fcnlerin isimlerine do\u011frudan <code>siparis.urun_isimleri<\/code> \u00fczerinden eri\u015febiliyoruz. Bu, kodun okunabilirli\u011fini art\u0131r\u0131rken, arac\u0131 <code>SiparisKalemi<\/code> objesini do\u011frudan dola\u015fma ihtiyac\u0131n\u0131 ortadan kald\u0131r\u0131yor. B\u00f6ylece, bir sipari\u015fin i\u00e7indeki \u00fcr\u00fcnleri listelemek i\u00e7in daha temiz ve sezgisel bir yol sa\u011flam\u0131\u015f oluyoruz.<\/p>\n<p class=\"interactive-tip\">Uzman \u0130pucu: \u00c7o\u011fa \u00c7ok ili\u015fkilerde arac\u0131 tabloda ek s\u00fctunlar varsa, bu tabloyu ayr\u0131 bir model olarak tan\u0131mlamak ve ili\u015fkileri bu model \u00fczerinden kurmak daha do\u011fru bir yakla\u015f\u0131md\u0131r. <code>association_proxy<\/code> ise bu arac\u0131 modelin arkas\u0131ndaki detaylar\u0131 soyutlamak i\u00e7in harika bir ara\u00e7t\u0131r.<\/p>\n<h2>\u0130leri Seviye \u0130li\u015fki Y\u00f6netimi ve Optimizasyon Teknikleri<\/h2>\n<p>Flask-SQLAlchemy ile ili\u015fkileri y\u00f6netmek, sadece <code>db.relationship<\/code> ve <code>association_proxy<\/code> kullanmaktan ibaret de\u011fildir. Uygulaman\u0131z b\u00fcy\u00fcd\u00fck\u00e7e ve veritaban\u0131 etkile\u015fimleri karma\u015f\u0131kla\u015ft\u0131k\u00e7a, performans ve esneklik i\u00e7in baz\u0131 ileri seviye tekniklere ihtiya\u00e7 duyabilirsiniz. Bu b\u00f6l\u00fcmde, ili\u015fkinizin davran\u0131\u015f\u0131n\u0131 daha iyi kontrol etmek ve uygulaman\u0131z\u0131n performans\u0131n\u0131 optimize etmek i\u00e7in kullanabilece\u011finiz baz\u0131 \u00f6nemli kavramlar\u0131 ele alaca\u011f\u0131z.<\/p>\n<ul>\n<li>\n            <strong><code>lazy<\/code> Y\u00fckleme Stratejileri:<\/strong> \u0130li\u015fkili verilerin ne zaman y\u00fcklenece\u011fini belirler.<\/p>\n<ul>\n<li><code>lazy=&#039;select&#039;<\/code> (Varsay\u0131lan): Her eri\u015fim i\u00e7in ayr\u0131 bir SELECT sorgusu yapar (N+1 sorununa yol a\u00e7abilir).<\/li>\n<li><code>lazy=&#039;joined&#039;<\/code>: \u0130li\u015fkili verileri ana tablo sorgusuyla JOIN kullanarak y\u00fckler.<\/li>\n<li><code>lazy=&#039;subquery&#039;<\/code>: \u0130li\u015fkili verileri ana tabloya alt sorgu (subquery) ile y\u00fckler.<\/li>\n<li><code>lazy=&#039;dynamic&#039;<\/code>: \u0130li\u015fkili veriler bir sorgu nesnesi olarak d\u00f6ner, bu sayede filtrelenebilir veya s\u0131ralanabilir. B\u00fcy\u00fck koleksiyonlar i\u00e7in kullan\u0131\u015fl\u0131d\u0131r.<\/li>\n<\/ul>\n<\/li>\n<li>\n            <strong><code>backref<\/code> ve <code>back_populates<\/code>:<\/strong> \u0130kisi de \u00e7ift y\u00f6nl\u00fc ili\u015fki kurar ancak <code>back_populates<\/code> daha belirgin ve hata ay\u0131klamas\u0131 daha kolay olabilir, \u00e7\u00fcnk\u00fc her iki tarafta da a\u00e7\u0131k\u00e7a tan\u0131mlan\u0131r. <code>backref<\/code> ise tek tarafl\u0131 tan\u0131mla di\u011fer tarafa otomatik \u00f6zellik ekler.\n        <\/li>\n<li>\n            <strong><code>cascade<\/code> Se\u00e7enekleri:<\/strong> Bir ana nesne silindi\u011finde veya g\u00fcncellendi\u011finde ili\u015fkili nesnelere ne olaca\u011f\u0131n\u0131 kontrol eder.<\/p>\n<ul>\n<li><code>cascade=\"all, delete-orphan\"<\/code>: En agresif se\u00e7enektir. Ana nesne silindi\u011finde ili\u015fkili nesneleri de siler ve e\u011fer bir ili\u015fkili nesne koleksiyondan kald\u0131r\u0131l\u0131rsa da onu siler. Dikkatli kullan\u0131lmal\u0131d\u0131r!<\/li>\n<\/ul>\n<\/li>\n<li>\n            <strong>Veritaban\u0131 Migration'lar\u0131 (Alembic):<\/strong> Uygulaman\u0131z\u0131n ya\u015fam d\u00f6ng\u00fcs\u00fc boyunca model de\u011fi\u015fiklikleri ka\u00e7\u0131n\u0131lmazd\u0131r. \u0130li\u015fkisel yap\u0131lardaki de\u011fi\u015fiklikleri veritaban\u0131na g\u00fcvenli bir \u015fekilde uygulamak i\u00e7in Alembic gibi bir migration arac\u0131 kullanmak esast\u0131r. Bu ara\u00e7, modelinizdeki de\u011fi\u015fiklikleri alg\u0131lar ve veritaban\u0131 \u015femas\u0131n\u0131 g\u00fcncelleyen SQL betikleri olu\u015fturur.\n        <\/li>\n<li>\n            <strong>\u0130li\u015fkisel Sorgularda Performans Optimizasyonu:<\/strong> N+1 sorununu \u00e7\u00f6zmek ve veritaban\u0131 sorgular\u0131n\u0131 azaltmak i\u00e7in <code>joinedload<\/code> ve <code>selectinload<\/code> gibi eager loading tekniklerini kullanmak \u00e7ok \u00f6nemlidir.<\/p>\n<pre><code>\n# Yazar ve kitaplar\u0131n\u0131 tek sorguda y\u00fckler\nyazar = Yazar.query.options(db.joinedload(Yazar.kitaplar)).filter_by(isim='George Orwell').first()\n# veya\n# yazar = Yazar.query.options(db.selectinload(Yazar.kitaplar)).filter_by(isim='George Orwell').first()\n            <\/pre>\n<p><\/code><\/p>\n<p><code>joinedload<\/code> JOIN kullanarak, <code>selectinload<\/code> ise ayr\u0131 bir IN sorgusu ile ili\u015fkili nesneleri y\u00fckler. Hangi stratejinin daha iyi oldu\u011fu, veritaban\u0131n\u0131n yap\u0131s\u0131na ve sorgu y\u00fck\u00fcne ba\u011fl\u0131d\u0131r.<\/p>\n<\/li>\n<\/ul>\n<p>Bu ileri seviye teknikleri anlamak ve do\u011fru yerde kullanmak, Flask-SQLAlchemy uygulamalar\u0131n\u0131z\u0131n sadece i\u015flevsel olmakla kalmay\u0131p, ayn\u0131 zamanda y\u00fcksek performansl\u0131 ve bak\u0131m\u0131 kolay olmas\u0131n\u0131 da sa\u011flayacakt\u0131r. \u00d6zellikle b\u00fcy\u00fck ve karma\u015f\u0131k veri setleriyle \u00e7al\u0131\u015f\u0131rken bu optimizasyonlar kritik hale gelir.<\/p>\n<h2>Sonu\u00e7 ve S\u0131k\u00e7a Sorulan Sorular<\/h2>\n<p>Flask-SQLAlchemy'nin <code>db.relationship<\/code> ve <code>association_proxy<\/code> \u00f6zellikleri, Python tabanl\u0131 web uygulamalar\u0131nda veritaban\u0131 ili\u015fkilerini y\u00f6netmek i\u00e7in muazzam bir g\u00fc\u00e7 ve esneklik sunar. <code>db.relationship<\/code> ile modelleriniz aras\u0131nda anlaml\u0131 ve gezinebilir ba\u011flant\u0131lar kurarken, <code>association_proxy<\/code> ile bu ili\u015fkilerdeki arac\u0131 tablolar\u0131n karma\u015f\u0131kl\u0131\u011f\u0131n\u0131 soyutlayarak kodunuzu daha temiz ve okunabilir hale getirebilirsiniz. Ger\u00e7ek d\u00fcnya senaryolar\u0131nda, bu ara\u00e7lar\u0131n do\u011fru kullan\u0131m\u0131, geli\u015ftirme s\u00fcrecini h\u0131zland\u0131r\u0131r, kod bak\u0131m\u0131n\u0131 kolayla\u015ft\u0131r\u0131r ve uygulaman\u0131z\u0131n genel performans\u0131n\u0131 art\u0131r\u0131r.<\/p>\n<p>Unutmay\u0131n ki veritaban\u0131 ili\u015fkileri, sadece veri depolama \u015feklinden ibaret de\u011fildir; ayn\u0131 zamanda uygulaman\u0131z\u0131n i\u015f mant\u0131\u011f\u0131n\u0131 ve kullan\u0131c\u0131 deneyimini do\u011frudan etkileyen bir unsurdur. Bu nedenle, model tasar\u0131mlar\u0131n\u0131z\u0131 yaparken ili\u015fkilerin t\u00fcr\u00fcn\u00fc, y\u00fckleme stratejilerini ve olas\u0131 performans etkilerini dikkatlice de\u011ferlendirmek \u00f6nemlidir. Pratik yaparak ve farkl\u0131 senaryolar\u0131 deneyimleyerek bu ara\u00e7lara olan hakimiyetinizi art\u0131rabilirsiniz.<\/p>\n<h3>S\u0131k\u00e7a Sorulan Sorular<\/h3>\n<dl>\n<dt><code>db.relationship<\/code> ve <code>relationship<\/code> aras\u0131ndaki fark nedir?<\/dt>\n<dd><code>db.relationship<\/code>, Flask-SQLAlchemy ba\u011flam\u0131nda kullan\u0131lan bir k\u0131saltmad\u0131r ve temel olarak SQLAlchemy'nin <code>relationship<\/code> fonksiyonunu \u00e7a\u011f\u0131r\u0131r. Flask-SQLAlchemy, <code>db<\/code> objesini (<code>SQLAlchemy(app)<\/code>) tan\u0131mlad\u0131\u011f\u0131n\u0131zda, t\u00fcm SQLAlchemy nesnelerine bu <code>db<\/code> objesi \u00fczerinden eri\u015fmenizi kolayla\u015ft\u0131r\u0131r. Yani, teknik olarak ayn\u0131 anlama gelirler ancak <code>db.relationship<\/code> Flask-SQLAlchemy uygulamalar\u0131nda tercih edilen kullan\u0131m \u015feklidir.<\/dd>\n<dt><code>association_proxy<\/code> yerine manuel olarak arac\u0131 tabloyu y\u00f6netmek ne zaman daha iyidir?<\/dt>\n<dd>E\u011fer arac\u0131 tablonuz sadece iki ana tablonun anahtarlar\u0131n\u0131 tutuyorsa ve bu ili\u015fkiye \u00f6zg\u00fc ba\u015fka hi\u00e7bir veri i\u00e7ermiyorsa, <code>association_proxy<\/code> harika bir se\u00e7enektir. Ancak, E-ticaret sepeti \u00f6rne\u011fimizdeki <code>SiparisKalemi<\/code> gibi arac\u0131 tablonun <code>adet<\/code> veya <code>birim_fiyat<\/code> gibi ek s\u00fctunlar\u0131 varsa, bu arac\u0131 tabloyu ayr\u0131 bir model olarak tan\u0131mlamak ve ili\u015fkileri bu model \u00fczerinden y\u00f6netmek daha mant\u0131kl\u0131d\u0131r. <code>association_proxy<\/code>, bu durumda bile arac\u0131 modelin belirli bir \u00f6zelli\u011fine (\u00f6rne\u011fin \u00fcr\u00fcn ad\u0131) do\u011frudan eri\u015fmek i\u00e7in kullan\u0131labilir, ancak do\u011frudan y\u00f6netim (CRUD) i\u015flemleri i\u00e7in arac\u0131 modele ihtiya\u00e7 duyulacakt\u0131r.<\/dd>\n<dt>\u0130li\u015fki tan\u0131mlar\u0131nda performans\u0131 etkileyen fakt\u00f6rler nelerdir?<\/dt>\n<dd>En b\u00fcy\u00fck performans fakt\u00f6rleri <strong>y\u00fckleme stratejileri<\/strong> (<code>lazy<\/code> parametresi) ve <strong>N+1 sorgu problemi<\/strong>dir. Yanl\u0131\u015f <code>lazy<\/code> stratejisi (\u00f6zellikle <code>lazy=&#039;select&#039;<\/code>) \u00e7ok say\u0131da ili\u015fkili nesneye eri\u015fti\u011finizde her biri i\u00e7in ayr\u0131 bir sorgu tetikleyerek veritaban\u0131 y\u00fck\u00fcn\u00fc art\u0131r\u0131r. <code>joinedload<\/code> ve <code>selectinload<\/code> gibi eager loading teknikleri bu sorunu \u00e7\u00f6zmek i\u00e7in kullan\u0131l\u0131r. Ayr\u0131ca, karma\u015f\u0131k ili\u015fkilerde indekslerin do\u011fru kullan\u0131m\u0131 da sorgu performans\u0131n\u0131 b\u00fcy\u00fck \u00f6l\u00e7\u00fcde etkiler.<\/dd>\n<dt><code>cascade=\"all, delete-orphan\"<\/code> kullan\u0131rken nelere dikkat etmeliyiz?<\/dt>\n<dd>Bu se\u00e7enek \u00e7ok g\u00fc\u00e7l\u00fcd\u00fcr ve dikkatli kullan\u0131lmal\u0131d\u0131r \u00e7\u00fcnk\u00fc ana nesne silindi\u011finde ili\u015fkili t\u00fcm alt nesneleri de kal\u0131c\u0131 olarak siler. Ayr\u0131ca, bir alt nesne ana nesnenin ili\u015fkili koleksiyonundan kald\u0131r\u0131ld\u0131\u011f\u0131nda (ili\u015fkisi kesildi\u011finde) bile onu veritaban\u0131ndan siler. Bu davran\u0131\u015f, \u00f6zellikle veri b\u00fct\u00fcnl\u00fc\u011f\u00fcn\u00fcn kritik oldu\u011fu veya silme i\u015flemlerinin geri al\u0131namaz oldu\u011fu durumlarda istenmeyebilir. Veri kayb\u0131n\u0131 \u00f6nlemek i\u00e7in \u00f6ncelikle uygulaman\u0131z\u0131n i\u015f kurallar\u0131n\u0131 iyi anlamal\u0131 ve bu se\u00e7ene\u011fi yaln\u0131zca kas\u0131tl\u0131 olarak ili\u015fkili verileri tamamen yok etmek istedi\u011finizde kullanmal\u0131s\u0131n\u0131z. Genellikle, <code>ondelete=&#039;CASCADE&#039;<\/code> yabanc\u0131 anahtar k\u0131s\u0131tlamalar\u0131 ile birlikte kullan\u0131ld\u0131\u011f\u0131nda benzer sonu\u00e7lar verebilir ancak <code>delete-orphan<\/code> koleksiyondan \u00e7\u0131karma durumunu da kapsar.<\/dd>\n<\/dl>\n<p><\/body><\/p>\n","protected":false},"excerpt":{"rendered":"Flask-SQLAlchemy \u0130li\u015fkilerini Anlama: relationship ve association_proxy Flask-SQLAlchemy ile veritaban\u0131 ili\u015fkilerini anlamak ve etkili y\u00f6netmek, sa\u011flam web uygulamalar\u0131 i\u00e7in&hellip;","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"csco_page_header_type":"","csco_page_load_nextpost":"","csco_page_subscribe_form":"","csco_page_contact_form":"","footnotes":""},"categories":[1],"tags":[],"class_list":{"0":"post-32760","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-genel","7":"cs-entry","8":"cs-video-wrap"},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.5 (Yoast SEO v25.3.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Veritaban\u0131 \u0130li\u015fkileri Neden Hayati \u00d6nem Ta\u015f\u0131r? Temel Kavramlara Giri\u015f<\/title>\n<meta name=\"description\" content=\"Flask-SQLAlchemy ile veritaban\u0131 ili\u015fkilerini anlamak ve etkili y\u00f6netmek, sa\u011flam web uygulamalar\u0131 i\u00e7in hayati. Bu makale, `db.relationship` ve `association_proxy`&#039;yi derinlemesine inceleyerek veri modellerinizi g\u00fc\u00e7lendirmenin yollar\u0131n\u0131 sunuyor. Uygulamalar\u0131n\u0131zda karma\u015f\u0131k veri yap\u0131lar\u0131n\u0131 basit ve anla\u015f\u0131l\u0131r bir \u015fekilde temsil etmek, gelecekteki bak\u0131m\u0131n\u0131 ve geni\u015flemesini do\u011frudan etkiler. Flask uygulamalar\u0131n\u0131zda veritaban\u0131 ili\u015fkileri konusunda zorlan\u0131yorsan\u0131z veya bilginizi peki\u015ftirmek istiyorsan\u0131z, do\u011fru yerdesiniz.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/fatihsoysal.com\/blog\/veritabani-iliskileri-neden-hayati-onem-tasir-temel-kavramlara-giris\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Veritaban\u0131 \u0130li\u015fkileri Neden Hayati \u00d6nem Ta\u015f\u0131r? Temel Kavramlara Giri\u015f\" \/>\n<meta property=\"og:description\" content=\"Flask-SQLAlchemy ile veritaban\u0131 ili\u015fkilerini anlamak ve etkili y\u00f6netmek, sa\u011flam web uygulamalar\u0131 i\u00e7in hayati. Bu makale, `db.relationship` ve `association_proxy`&#039;yi derinlemesine inceleyerek veri modellerinizi g\u00fc\u00e7lendirmenin yollar\u0131n\u0131 sunuyor. Uygulamalar\u0131n\u0131zda karma\u015f\u0131k veri yap\u0131lar\u0131n\u0131 basit ve anla\u015f\u0131l\u0131r bir \u015fekilde temsil etmek, gelecekteki bak\u0131m\u0131n\u0131 ve geni\u015flemesini do\u011frudan etkiler. Flask uygulamalar\u0131n\u0131zda veritaban\u0131 ili\u015fkileri konusunda zorlan\u0131yorsan\u0131z veya bilginizi peki\u015ftirmek istiyorsan\u0131z, do\u011fru yerdesiniz.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fatihsoysal.com\/blog\/veritabani-iliskileri-neden-hayati-onem-tasir-temel-kavramlara-giris\/\" \/>\n<meta property=\"og:site_name\" content=\"Kodlar\u0131n Gizemli D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2025-10-25T14:32:38+00:00\" \/>\n<meta name=\"author\" content=\"Fatih Soysal\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Yazan:\" \/>\n\t<meta name=\"twitter:data1\" content=\"Fatih Soysal\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tahmini okuma s\u00fcresi\" \/>\n\t<meta name=\"twitter:data2\" content=\"21 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/veritabani-iliskileri-neden-hayati-onem-tasir-temel-kavramlara-giris\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/veritabani-iliskileri-neden-hayati-onem-tasir-temel-kavramlara-giris\/\"},\"author\":{\"name\":\"Fatih Soysal\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"headline\":\"Veritaban\u0131 \u0130li\u015fkileri Neden Hayati \u00d6nem Ta\u015f\u0131r? Temel Kavramlara Giri\u015f\",\"datePublished\":\"2025-10-25T14:32:38+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/veritabani-iliskileri-neden-hayati-onem-tasir-temel-kavramlara-giris\/\"},\"wordCount\":2500,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/veritabani-iliskileri-neden-hayati-onem-tasir-temel-kavramlara-giris\/#respond\"]}],\"copyrightYear\":\"2025\",\"copyrightHolder\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/veritabani-iliskileri-neden-hayati-onem-tasir-temel-kavramlara-giris\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/veritabani-iliskileri-neden-hayati-onem-tasir-temel-kavramlara-giris\/\",\"name\":\"Veritaban\u0131 \u0130li\u015fkileri Neden Hayati \u00d6nem Ta\u015f\u0131r? Temel Kavramlara Giri\u015f\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\"},\"datePublished\":\"2025-10-25T14:32:38+00:00\",\"description\":\"Flask-SQLAlchemy ile veritaban\u0131 ili\u015fkilerini anlamak ve etkili y\u00f6netmek, sa\u011flam web uygulamalar\u0131 i\u00e7in hayati. Bu makale, `db.relationship` ve `association_proxy`'yi derinlemesine inceleyerek veri modellerinizi g\u00fc\u00e7lendirmenin yollar\u0131n\u0131 sunuyor. Uygulamalar\u0131n\u0131zda karma\u015f\u0131k veri yap\u0131lar\u0131n\u0131 basit ve anla\u015f\u0131l\u0131r bir \u015fekilde temsil etmek, gelecekteki bak\u0131m\u0131n\u0131 ve geni\u015flemesini do\u011frudan etkiler. Flask uygulamalar\u0131n\u0131zda veritaban\u0131 ili\u015fkileri konusunda zorlan\u0131yorsan\u0131z veya bilginizi peki\u015ftirmek istiyorsan\u0131z, do\u011fru yerdesiniz.\",\"breadcrumb\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/veritabani-iliskileri-neden-hayati-onem-tasir-temel-kavramlara-giris\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/veritabani-iliskileri-neden-hayati-onem-tasir-temel-kavramlara-giris\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/veritabani-iliskileri-neden-hayati-onem-tasir-temel-kavramlara-giris\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Anasayfa\",\"item\":\"https:\/\/fatihsoysal.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Veritaban\u0131 \u0130li\u015fkileri Neden Hayati \u00d6nem Ta\u015f\u0131r? Temel Kavramlara Giri\u015f\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/\",\"name\":\"Fatihsoysal.com\",\"description\":\"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim\",\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"tr\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\",\"name\":\"Fatih Soysal\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"contentUrl\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"width\":512,\"height\":512,\"caption\":\"Fatih Soysal\"},\"logo\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\"},\"description\":\"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Veritaban\u0131 \u0130li\u015fkileri Neden Hayati \u00d6nem Ta\u015f\u0131r? Temel Kavramlara Giri\u015f","description":"Flask-SQLAlchemy ile veritaban\u0131 ili\u015fkilerini anlamak ve etkili y\u00f6netmek, sa\u011flam web uygulamalar\u0131 i\u00e7in hayati. Bu makale, `db.relationship` ve `association_proxy`'yi derinlemesine inceleyerek veri modellerinizi g\u00fc\u00e7lendirmenin yollar\u0131n\u0131 sunuyor. Uygulamalar\u0131n\u0131zda karma\u015f\u0131k veri yap\u0131lar\u0131n\u0131 basit ve anla\u015f\u0131l\u0131r bir \u015fekilde temsil etmek, gelecekteki bak\u0131m\u0131n\u0131 ve geni\u015flemesini do\u011frudan etkiler. Flask uygulamalar\u0131n\u0131zda veritaban\u0131 ili\u015fkileri konusunda zorlan\u0131yorsan\u0131z veya bilginizi peki\u015ftirmek istiyorsan\u0131z, do\u011fru yerdesiniz.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/fatihsoysal.com\/blog\/veritabani-iliskileri-neden-hayati-onem-tasir-temel-kavramlara-giris\/","og_locale":"tr_TR","og_type":"article","og_title":"Veritaban\u0131 \u0130li\u015fkileri Neden Hayati \u00d6nem Ta\u015f\u0131r? Temel Kavramlara Giri\u015f","og_description":"Flask-SQLAlchemy ile veritaban\u0131 ili\u015fkilerini anlamak ve etkili y\u00f6netmek, sa\u011flam web uygulamalar\u0131 i\u00e7in hayati. Bu makale, `db.relationship` ve `association_proxy`'yi derinlemesine inceleyerek veri modellerinizi g\u00fc\u00e7lendirmenin yollar\u0131n\u0131 sunuyor. Uygulamalar\u0131n\u0131zda karma\u015f\u0131k veri yap\u0131lar\u0131n\u0131 basit ve anla\u015f\u0131l\u0131r bir \u015fekilde temsil etmek, gelecekteki bak\u0131m\u0131n\u0131 ve geni\u015flemesini do\u011frudan etkiler. Flask uygulamalar\u0131n\u0131zda veritaban\u0131 ili\u015fkileri konusunda zorlan\u0131yorsan\u0131z veya bilginizi peki\u015ftirmek istiyorsan\u0131z, do\u011fru yerdesiniz.","og_url":"https:\/\/fatihsoysal.com\/blog\/veritabani-iliskileri-neden-hayati-onem-tasir-temel-kavramlara-giris\/","og_site_name":"Kodlar\u0131n Gizemli D\u00fcnyas\u0131","article_published_time":"2025-10-25T14:32:38+00:00","author":"Fatih Soysal","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"Fatih Soysal","Tahmini okuma s\u00fcresi":"21 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fatihsoysal.com\/blog\/veritabani-iliskileri-neden-hayati-onem-tasir-temel-kavramlara-giris\/#article","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/veritabani-iliskileri-neden-hayati-onem-tasir-temel-kavramlara-giris\/"},"author":{"name":"Fatih Soysal","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"headline":"Veritaban\u0131 \u0130li\u015fkileri Neden Hayati \u00d6nem Ta\u015f\u0131r? Temel Kavramlara Giri\u015f","datePublished":"2025-10-25T14:32:38+00:00","mainEntityOfPage":{"@id":"https:\/\/fatihsoysal.com\/blog\/veritabani-iliskileri-neden-hayati-onem-tasir-temel-kavramlara-giris\/"},"wordCount":2500,"commentCount":0,"publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fatihsoysal.com\/blog\/veritabani-iliskileri-neden-hayati-onem-tasir-temel-kavramlara-giris\/#respond"]}],"copyrightYear":"2025","copyrightHolder":{"@id":"https:\/\/fatihsoysal.com\/blog\/#organization"}},{"@type":"WebPage","@id":"https:\/\/fatihsoysal.com\/blog\/veritabani-iliskileri-neden-hayati-onem-tasir-temel-kavramlara-giris\/","url":"https:\/\/fatihsoysal.com\/blog\/veritabani-iliskileri-neden-hayati-onem-tasir-temel-kavramlara-giris\/","name":"Veritaban\u0131 \u0130li\u015fkileri Neden Hayati \u00d6nem Ta\u015f\u0131r? Temel Kavramlara Giri\u015f","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/#website"},"datePublished":"2025-10-25T14:32:38+00:00","description":"Flask-SQLAlchemy ile veritaban\u0131 ili\u015fkilerini anlamak ve etkili y\u00f6netmek, sa\u011flam web uygulamalar\u0131 i\u00e7in hayati. Bu makale, `db.relationship` ve `association_proxy`'yi derinlemesine inceleyerek veri modellerinizi g\u00fc\u00e7lendirmenin yollar\u0131n\u0131 sunuyor. Uygulamalar\u0131n\u0131zda karma\u015f\u0131k veri yap\u0131lar\u0131n\u0131 basit ve anla\u015f\u0131l\u0131r bir \u015fekilde temsil etmek, gelecekteki bak\u0131m\u0131n\u0131 ve geni\u015flemesini do\u011frudan etkiler. Flask uygulamalar\u0131n\u0131zda veritaban\u0131 ili\u015fkileri konusunda zorlan\u0131yorsan\u0131z veya bilginizi peki\u015ftirmek istiyorsan\u0131z, do\u011fru yerdesiniz.","breadcrumb":{"@id":"https:\/\/fatihsoysal.com\/blog\/veritabani-iliskileri-neden-hayati-onem-tasir-temel-kavramlara-giris\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fatihsoysal.com\/blog\/veritabani-iliskileri-neden-hayati-onem-tasir-temel-kavramlara-giris\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/fatihsoysal.com\/blog\/veritabani-iliskileri-neden-hayati-onem-tasir-temel-kavramlara-giris\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Anasayfa","item":"https:\/\/fatihsoysal.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Veritaban\u0131 \u0130li\u015fkileri Neden Hayati \u00d6nem Ta\u015f\u0131r? Temel Kavramlara Giri\u015f"}]},{"@type":"WebSite","@id":"https:\/\/fatihsoysal.com\/blog\/#website","url":"https:\/\/fatihsoysal.com\/blog\/","name":"Fatihsoysal.com","description":"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim","publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"tr"},{"@type":["Person","Organization"],"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1","name":"Fatih Soysal","image":{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","contentUrl":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","width":512,"height":512,"caption":"Fatih Soysal"},"logo":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/"},"description":"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.","url":"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/"}]}},"yoast_meta":{"yoast_wpseo_title":"","yoast_wpseo_metadesc":"","yoast_wpseo_canonical":""},"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/32760","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/comments?post=32760"}],"version-history":[{"count":0,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/32760\/revisions"}],"wp:attachment":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/media?parent=32760"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/categories?post=32760"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/tags?post=32760"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}