SQLAlchemy neler yapabileceğini ve Django ORM örnek olamaz
Son zamanlarda bir çok araştırma Django geçerli bir uygulama tutmak SQLAlchemy karşı olan Piramit kullanarak yapıyorum. Tek başına bütün bir tartışma konusudur, ama bunu tartışmak için gelmedim.
Bilmek istiyorum ne, neden SQLAlchemy evrensel Django ORM daha iyi olarak kabul edilir. Her değilse hemen hemen her ikisi arasında buldum karşılaştırma SQLAlchemy yanadır. SQLAlchemy yapısı çok daha sorunsuz SQL çevirmek sağlar performans olarak büyük bir şey sanırım.
Ama, aynı zamanda daha zor görevlerle, Django ORM kullanmak neredeyse imkansız olduğunu duydum. Bu nasıl dışarı kapsam istiyorum. Nedenlerinden biri, Django ORM artık sizin ihtiyaçlarınıza uygun zaman olduğunu SQLAlchemy geçmek için okuyorum.
, SQLAlchemy yapabilir, ama Django ORM olabilir, ek ham SQL ekleme olmadan Kısacası, birileri bir sorgu (SQL sözdizimi gerçek olmak zorunda değil) sağlayabilir?
Güncelleme:
Ben bu soruyu ilk sorana oldukça ilgisini çekti izliyorum, ekstra benim iki kuruş atmak istiyorum.
Sonunda SQLAlchemy kullanarak bitirdik ve karardan mutlu olduğumu söylemeliyim.
Bu soru, şimdiye kadar, Django ORM çoğaltmak mümkün oldum değil SQLAlchemy ek bir özellik sağlamak için tekrar düşünüyordum. Eğer birisi bunu yapmak için nasıl bir örnek verebilir eğer seve seve sözlerimi yerim.
Diyelim ki kullanmak istediğiniz bazı postgresql gibi işlev benzerliği () sağlayan bir bulanık karşılaştırma (bkz: Finding similar strings with postgresql quickly - tl;dr giriş iki dize getir geri bir yüzde benzerlik).
Bu Django ORM kullanarak nasıl arama yapılır ve hiçbir şey onların belgelerden belli olduğu gibi ham sql kullanarak dışında bulduk: https://docs.djangoproject.com/en/dev/topics/db/sql/.
yani
Model.objects.raw('SELECT * FROM app_model ORDER BY \
similarity(name, %s) DESC;', [input_name])
Burada anlatıldığı gibi SQLalchemy, ancak işlev (),: http://docs.sqlalchemy.org/en/latest/core/sqlelement.html#sqlalchemy.sql.expression.func
from sqlalchemy import desc, func
session.query(Model).order_by(func.similarity(Model.name, input_name))
Bu tanımladığınız sql/postgresql/etc herhangi bir fonksiyon için sql oluşturmak ve ham sql gerektirmez sağlar.
CEVAP
Bu yapıcı olmayan olmak için tehlikeli bir şekilde bulunur, ama ısırırım.
Diyelim ki, farklı hesaplar bir dizi için belirli öğeleri stoklar korumak gerekir sanırım. DDL şöyle:
CREATE TABLE account (
id serial PRIMARY KEY,
...
);
CREATE TABLE item (
id serial PRIMARY KEY,
name text NOT NULL,
...
);
CREATE TABLE inventory (
account_id integer NOT NULL REFERENCES account(id),
item_id integer NOT NULL REFERENCES item(id),
amount integer NOT NULL DEFAULT 0 CHECK (amount >= 0),
PRIMARY KEY (account_id, item_id)
);
Öncelikle Django ORM bileşik birincil anahtarlar ile çalışamaz. Evet, her zaman yedek anahtar ve benzersiz bir kısıtlaması ekleyebilirsiniz, ama bir daha fazla sütun ve gerçekten ihtiyacınız birden fazla dizin. Sütunlar küçük bir sayı ile büyük bir tablo için bu fark boyut ve performans yükü eklemek istiyorum. Ayrıca, ORMs genellikle kimlik eşleme bir şey birincil anahtar kullanarak sorun var.
Şimdi, izin verilen hesap stok miktarını eşliğinde her öğe sorgu, ama aynı zamanda tüm öğeleri 0 miktar ayarla ile yok orada eklemek istiyoruz diyelim. Ve o miktara göre azalan sırada bu sıralama. SQL ilgili:
SELECT item.id, item.name, ..., coalesce(inventory.amount, 0) AS amount
FROM item LEFT OUTER JOIN inventory
ON item.id = inventory.item_id AND inventory.team_id = ?
ORDER BY amount DESC;
Dış özel durumu katılın Django ORM ifade etmek için bir yol yoktur. Evet, iki basit ayrı sorgular ve gerçekleştirmek katılmak Python döngü içinde elle yapabilirsiniz. Ve performansı muhtemelen daha kötüye gitmezbu özel durumda. Ama bu sonuçlar, çünkü konumuz bu değilhersorgu uygulama yan SELECT
s sadece temel kullanarak yeniden olabilir.
SQLAlchemy İle:
class Account(Base):
__tablename__ = 'account'
id = Column(Integer, primary_key=True)
...
class Item(Base):
__tablename__ = 'item'
id = Column(Integer, primary_key=True)
name = Column(String, nullable=False)
...
class Inventory(Base):
__tablename__ = 'inventory'
account_id = Column(Integer, ForeignKey('account.id'), primary_key=True,
nullable=False)
account = relationship(Account)
item_id = Column(Integer, ForeignKey('item.id'), primary_key=True,
nullable=False)
item = relationship(Item)
amount = Column(Integer, CheckConstraint('amount >= 0'), nullable=False,
default=0)
account = session.query(Account).get(some_id)
result = (session
.query(Item, func.coalesce(Inventory.amount, 0).label('amount'))
.outerjoin(Inventory,
and_(Item.id==Inventory.item_id, Inventory.account==account))
.order_by(desc('amount'))
.all())
Bir yan not olarak, SQLAlchemy sözlük tabanlı koleksiyonları çok kolay hale getirir. Inventory
ile ilişkisi ne olarak görünmesini sağlarsınız Account
modeli için aşağıdaki kodu ilavesi ile: miktarı için öğeleri eşleme.
items = relationship('Inventory',
collection_class=attribute_mapped_collection('item_id'))
inventory = association_proxy('items', 'amount',
creator=lambda k, v: Inventory(item_id=k, amount=v))
Bu gibi kod yazmak sağlar:
account.inventory[item_id] = added_value
bu şeffaf ekler veya günceller inventory
tabloda girdiler.
Kompleks birleşimler, alt sorgular, pencere toplamları — Django ORM böyle bir şey ile başa çıkmak için ham SQL düşen geri başarısız olur.
Basit django 1.3 için örnek Dosya için...
Az Django dosyası lazım örnek upload...
'<yöntem üyesi&;' olamaz ...
SQLAlchemy'In get_or_create Djang...
Nasıl Django model örnek bir nesne klo...