成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Python-SQLALchemy

kumfo / 973人閱讀

摘要:因?yàn)槭枪ぷ髟谝粋€(gè)內(nèi)部,有時(shí)候我們可能不小心做了一些誤刪除的操作,可以回滾。我們先修改的用戶名為,然后重新添加一個(gè)新,但是記住這個(gè)時(shí)候我們還沒有。集合類型可以是各種合法類型,比如,但是默認(rèn)集合是一個(gè)。

官方文檔

Initialization
# 檢查是否已經(jīng)安裝以及版本號(hào)
>>> import sqlalchemy
>>> sqlalchemy.__version__ 
’1.1.4‘
>>> from sqlalchemy.ext.declarative import declarative_base
# model都是要繼承自Base
>>> Base = declarative_base()

>>> from sqlalchemy import Column, Integer, String
>>> class User(Base):
...     __tablename__ = "users" # 指定數(shù)據(jù)表名
...
...     id = Column(Integer, primary_key=True)
...     name = Column(String(50))
...     fullname = Column(String(50))
...     password = Column(String(50))
...
...     def __repr__(self):
...        return "" % (
...                             self.name, self.fullname, self.password)


# 查看創(chuàng)建的數(shù)據(jù)表結(jié)構(gòu)
>>> User.__table__ 
Table("users", MetaData(bind=None),
            Column("id", Integer(), table=, primary_key=True, nullable=False),
            Column("name", String(length=50), table=),
            Column("fullname", String(length=50), table=),
            Column("password", String(length=50), table=), schema=None)

正式創(chuàng)建數(shù)據(jù)表

>>> from sqlalchemy import create_engine

# 連接到mysql
>>> engine = create_engine("mysql://root:root@localhost:3306/python?charset=utf8",
                           encoding="utf-8", echo=True)

# 正式創(chuàng)建數(shù)據(jù)表
>>> Base.metadata.create_all(engine)
CREATE TABLE users (
    id INTEGER NOT NULL AUTO_INCREMENT, 
    name VARCHAR(50), 
    fullname VARCHAR(50), 
    password VARCHAR(50), 
    PRIMARY KEY (id)
)
Creating a Session

下面的操作都是要通過(guò)會(huì)話對(duì)象操作

>>> from sqlalchemy.orm import sessionmaker
>>> Session = sessionmaker(bind=engine)
>>> session = Session()
Adding and Updating Objects

添加一個(gè)User對(duì)象

>>> ed_user = User(name="ed", fullname="Ed Jones", password="edspassword")
>>> session.add(ed_user)

查詢一下,使用filter_by來(lái)過(guò)濾,first只列出第一個(gè)查詢到的對(duì)象

>>> our_user = session.query(User).filter_by(name="ed").first()
BEGIN (implicit)
INSERT INTO users (name, fullname, password) VALUES (?, ?, ?)
("ed", "Ed Jones", "edspassword")

SELECT users.id AS users_id,
        users.name AS users_name,
        users.fullname AS users_fullname,
        users.password AS users_password
FROM users
WHERE users.name = ?
 LIMIT ? OFFSET ?
("ed", 1, 0)

>>> our_user


>>> ed_user is our_user
True

使用add_all,一次性添加多個(gè)對(duì)象

>>> session.add_all([
...     User(name="wendy", fullname="Wendy Williams", password="foobar"),
...     User(name="mary", fullname="Mary Contrary", password="xxg527"),
...     User(name="fred", fullname="Fred Flinstone", password="blah")])

Session很智能,比如說(shuō),它知道Ed Jones被修改了

# 可以直接修改ed_user對(duì)象
>>> ed_user.password = "f8s7ccs"

# session會(huì)自動(dòng)知道哪些數(shù)據(jù)被修改了
>>> session.dirty
IdentitySet([])

# session也可以知道哪些對(duì)象被新建了
>>> session.new
IdentitySet([,
,
])

對(duì)數(shù)據(jù)庫(kù)進(jìn)行了變更,自然要進(jìn)行commit,從echo語(yǔ)句我們可以看出,我們更新了1個(gè)對(duì)象,創(chuàng)建了3個(gè)對(duì)象。

>>> session.commit()
UPDATE users SET password=? WHERE users.id = ?
("f8s7ccs", 1)
INSERT INTO users (name, fullname, password) VALUES (?, ?, ?)
("wendy", "Wendy Williams", "foobar")
INSERT INTO users (name, fullname, password) VALUES (?, ?, ?)
("mary", "Mary Contrary", "xxg527")
INSERT INTO users (name, fullname, password) VALUES (?, ?, ?)
("fred", "Fred Flinstone", "blah")
COMMIT

>>> ed_user.id
BEGIN (implicit)
SELECT users.id AS users_id,
        users.name AS users_name,
        users.fullname AS users_fullname,
        users.password AS users_password
FROM users
WHERE users.id = ?
(1,)
1
Rolling Back

因?yàn)镾ession是工作在一個(gè)transaction內(nèi)部,有時(shí)候我們可能不小心做了一些誤刪除的操作,可以回滾。我們先修改ed_user的用戶名為Edwardo,然后重新添加一個(gè)新User,但是記住這個(gè)時(shí)候我們還沒有commit。

>>> ed_user.name = "Edwardo"
and we’ll add another erroneous user, fake_user:

>>> fake_user = User(name="fakeuser", fullname="Invalid", password="12345")
>>> session.add(fake_user)
Querying the session, we can see that they’re flushed into the current transaction:

查詢檢驗(yàn)一下

>>> session.query(User).filter(User.name.in_(["Edwardo", "fakeuser"])).all()
UPDATE users SET name=? WHERE users.id = ?
("Edwardo", 1)
INSERT INTO users (name, fullname, password) VALUES (?, ?, ?)
("fakeuser", "Invalid", "12345")
SELECT users.id AS users_id,
        users.name AS users_name,
        users.fullname AS users_fullname,
        users.password AS users_password
FROM users
WHERE users.name IN (?, ?)
("Edwardo", "fakeuser")
[, ]

回滾,我們可以知道ed_user‘s name is back to ed以及fake_user has been kicked out of the session

>>> session.rollback()
ROLLBACK

>>> ed_user.name
BEGIN (implicit)
SELECT users.id AS users_id,
        users.name AS users_name,
        users.fullname AS users_fullname,
        users.password AS users_password
FROM users
WHERE users.id = ?
(1,)
u"ed"

>>> fake_user in session
False
issuing a SELECT illustrates the changes made to the database:

這個(gè)時(shí)候再查詢,很明顯fakeuser已經(jīng)消失了,ed用戶的名字重新變回了ed而不是Edwordo

>>> session.query(User).filter(User.name.in_(["ed", "fakeuser"])).all()
SELECT users.id AS users_id,
        users.name AS users_name,
        users.fullname AS users_fullname,
        users.password AS users_password
FROM users
WHERE users.name IN (?, ?)
("ed", "fakeuser")
[]
Couting

用于查詢操作相對(duì)應(yīng)的count()操作

>>> session.query(User).filter(User.name.like("%ed")).count()
2

>>> from sqlalchemy import func
>>> session.query(func.count(User.name), User.name).group_by(User.name).all()
[(1, u"ed"), (1, u"fred"), (1, u"mary"), (1, u"wendy")]
Querying

一個(gè)通過(guò)在Session上使用query方法可以創(chuàng)建一個(gè)Query object

按照用戶id進(jìn)行排序來(lái)進(jìn)行查詢

>>> for instance in session.query(User).order_by(User.id):
...     print(instance.name, instance.fullname)
ed Ed Jones
wendy Wendy Williams
mary Mary Contrary
fred Fred Flinstone

query方法也可以接收ORM-instrumented descriptors作為參數(shù)。返回結(jié)果是一個(gè)named tuples

>>> for name, fullname in session.query(User.name, User.fullname):
...     print(name, fullname)
ed Ed Jones
wendy Wendy Williams
mary Mary Contrary
fred Fred Flinstone

The tuples returned by Query are named tuples, supplied by the KeyedTuple class, and can be treated much like an ordinary Python object. The names are the same as the attribute’s name for an attribute, and the class name for a class:

>>> for row in session.query(User, User.name).all():
...    print(row.User, row.name)
 ed
 wendy
 mary
 fred

You can control the names of individual column expressions using the label() construct, which is available from any ColumnElement-derived object, as well as any class attribute which is mapped to one (such as User.name):

>>> for row in session.query(User.name.label("name_label")).all():
...    print(row.name_label)
ed
wendy
mary
fred

The name given to a full entity such as User, assuming that multiple entities are present in the call to query(), can be controlled using aliased() :

>>> from sqlalchemy.orm import aliased
>>> user_alias = aliased(User, name="user_alias")

>>> for row in session.query(user_alias, user_alias.name).all():
...    print(row.user_alias)



Basic operations with Query include issuing LIMIT and OFFSET, most conveniently using Python array slices and typically in conjunction with ORDER BY:

>>> for u in session.query(User).order_by(User.id)[1:3]:
...    print(u)


and filtering results, which is accomplished either with filter_by(), which uses keyword arguments:

>>> for name, in session.query(User.name).
...             filter_by(fullname="Ed Jones"):
...    print(name)
ed

>>> for name, in session.query(User.name).
...             filter(User.fullname=="Ed Jones"):
...    print(name)
ed

The Query object is fully generative, meaning that most method calls return a new Query object upon which further criteria may be added. For example, to query for users named “ed” with a full name of “Ed Jones”, you can call filter() twice, which joins criteria using AND:

>>> for user in session.query(User).
...          filter(User.name=="ed").
...          filter(User.fullname=="Ed Jones"):
...    print(user)

Common Filter Operators

下面列出了filter()最常用的一些operators

equals:
query.filter(User.name == "ed")

not equals:
query.filter(User.name != "ed")

LIKE:
query.filter(User.name.like("%ed%"))

IN:
query.filter(User.name.in_(["ed", "wendy", "jack"]))

# works with query objects too:
query.filter(User.name.in_(
        session.query(User.name).filter(User.name.like("%ed%"))
))

NOT IN:
query.filter(User.name.in_(["ed", "wendy", "jack"]))

IS NULL:
query.filter(User.name == None)

# alternatively, if pep8/linters are a concern
query.filter(User.name.is_(None))

IS NOT NULL:
query.filter(User.name != None)

# alternatively, if pep8/linters are a concern
query.filter(User.name.isnot(None))

AND:
# use and_()
from sqlalchemy import and_
query.filter(and_(User.name == "ed", User.fullname == "Ed Jones"))

# or send multiple expressions to .filter()
query.filter(User.name == "ed", User.fullname == "Ed Jones")

# or chain multiple filter()/filter_by() calls
query.filter(User.name == "ed").filter(User.fullname == "Ed Jones")

Note
Make sure you use and_() and not the Python and operator!

OR:
from sqlalchemy import or_
query.filter(or_(User.name == "ed", User.name == "wendy"))

Note
Make sure you use or_() and not the Python or operator!

MATCH:
query.filter(User.name.match("wendy"))

Note
match() uses a database-specific MATCH or CONTAINS function;
its behavior will vary by backend and is not available on some backends such as SQLite.
Building a Relationship

創(chuàng)建對(duì)象與對(duì)象之間的關(guān)系,下面我們新建一個(gè)Address表,下面的操作相比django的orm繁瑣一些,要同時(shí)在兩個(gè)class內(nèi)部同時(shí)設(shè)置relationship

>>> from sqlalchemy import ForeignKey
>>> from sqlalchemy.orm import relationship

>>> class Address(Base):
...     __tablename__ = "addresses"
...     id = Column(Integer, primary_key=True)
...     email_address = Column(String(50), nullable=False)
...     user_id = Column(Integer, ForeignKey("users.id"))
...
...     user = relationship("User", back_populates="addresses") # 將地址表和用戶表關(guān)聯(lián)
...
...     def __repr__(self):
...         return "" % self.email_address


# 在用戶表中還要重新設(shè)置一次
>>> User.addresses = relationship(
...     "Address", order_by=Address.id, back_populates="user")

>>> Base.metadata.create_all(engine)
Working with Related Objects

現(xiàn)在我們創(chuàng)建了一個(gè)User,與它對(duì)應(yīng)的一個(gè)空addresses集合也將創(chuàng)立。集合類型可以是各種合法類型,比如set/dictionaries(see Customizing Collection Access for details),但是默認(rèn)集合是一個(gè)list。

現(xiàn)在我們?cè)賮?lái)創(chuàng)建一個(gè)用戶Jack

>>> jack = User(name="jack", fullname="Jack Bean", password="gjffdd")
>>> jack.addresses
[]

We are free to add Address objects on our User object. In this case we just assign a full list directly:

現(xiàn)在我們將用戶Jack和一些地址關(guān)聯(lián)起來(lái)

>>> jack.addresses = [
...                 Address(email_address="[email protected]"),
...                 Address(email_address="[email protected]")]

When using a bidirectional relationship, elements added in one direction automatically become visible in the other direction. This behavior occurs based on attribute on-change events and is evaluated in Python, without using any SQL:
現(xiàn)在可以通過(guò)地址對(duì)象訪問用戶對(duì)象了

>>> jack.addresses[1]


>>> jack.addresses[1].user

Let’s add and commit Jack Bean to the database. jack as well as the two Address members in the corresponding addresses collection are both added to the session at once, using a process known as cascading:

接下來(lái)commit保存到數(shù)據(jù)庫(kù)

>>> session.add(jack)
>>> session.commit()
sqlalchemy.engine.base.Engine INSERT INTO addresses (email_address, user_id) VALUES (%s, %s)
sqlalchemy.engine.base.Engine ("[email protected]", 5L)
sqlalchemy.engine.base.Engine INSERT INTO addresses (email_address, user_id) VALUES (%s, %s)
sqlalchemy.engine.base.Engine ("[email protected]", 5L)
sqlalchemy.engine.base.Engine COMMIT

Querying for Jack, we get just Jack back. No SQL is yet issued for Jack’s addresses:

>>> jack = session.query(User).
... filter_by(name="jack").one()
>>> jack

Let’s look at the addresses collection. Watch the SQL:

>>> jack.addresses
[, ]

When we accessed the addresses collection, SQL was suddenly issued. This is an example of a lazy loading relationship. The addresses collection is now loaded and behaves just like an ordinary list. We’ll cover ways to optimize the loading of this collection in a bit.

Delete

刪除操作,接下來(lái)我們嘗試刪除jack對(duì)象,注意地址對(duì)象并不會(huì)因此而刪除

>>> session.delete(jack)
>>> session.query(User).filter_by(name="jack").count()
0
So far, so good. How about Jack’s Address objects ?

>>> session.query(Address).filter(
...     Address.email_address.in_(["[email protected]", "[email protected]"])
...  ).count()
2

Uh oh, they’re still there ! Analyzing the flush SQL, we can see that the user_id column of each address was set to NULL, but the rows weren’t deleted. SQLAlchemy doesn’t assume that deletes cascade, you have to tell it to do so. Configuring delete/delete-orphan Cascade. We will configure cascade options on the User.addresses relationship to change the behavior. While SQLAlchemy allows you to add new attributes and relationships to mappings at any point in time, in this case the existing relationship needs to be removed, so we need to tear down the mappings completely and start again - we’ll close the Session:

直接close來(lái)rollback,并不進(jìn)行commit

>>> session.close()
ROLLBACK

Use a new declarative_base():

>>> Base = declarative_base()

Next we’ll declare the User class, adding in the addresses relationship
including the cascade configuration (we’ll leave the constructor out too):

>>> class User(Base):
...     __tablename__ = "users"
...
...     id = Column(Integer, primary_key=True)
...     name = Column(String(50))
...     fullname = Column(String(50))
...     password = Column(String(50))
...
...     addresses = relationship("Address", back_populates="user",
...                     cascade="all, delete, delete-orphan")
...
...     def __repr__(self):
...        return "" % (
...                                self.name, self.fullname, self.password)

Then we recreate Address, noting that in this case
we’ve created the Address.user relationship via the User class already:

>>> class Address(Base):
...     __tablename__ = "addresses"
...     id = Column(Integer, primary_key=True)
...     email_address = Column(String(50), nullable=False)
...     user_id = Column(Integer, ForeignKey("users.id"))
...     user = relationship("User", back_populates="addresses")
...
...     def __repr__(self):
...         return "" % self.email_address

Now when we load the user jack (below using get(), which loads by primary key), removing an address from the corresponding addresses collection will result in that Address being deleted:

# load Jack by primary key
>>> jack = session.query(User).get(5)

# remove one Address (lazy load fires off)
>>> del jack.addresses[1]

# only one address remains
>>> session.query(Address).filter(
...     Address.email_address.in_(["[email protected]", "[email protected]"])
... ).count()
1

Deleting Jack will delete both Jack and the remaining Address associated with the user:

>>> session.delete(jack)

>>> session.query(User).filter_by(name="jack").count()
0

>>> session.query(Address).filter(
...    Address.email_address.in_(["[email protected]", "[email protected]"])
... ).count()
0

Further detail on configuration of cascades is at Cascades. The cascade functionality can also integrate smoothly with the ON DELETE CASCADE functionality of the relational database. See Using Passive Deletes for details.

backref

上面同時(shí)設(shè)置兩個(gè)relationship太麻煩了,可以使用backref

from sqlalchemy import Integer, ForeignKey, String, Column
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship

Base = declarative_base()

class User(Base):
    __tablename__ = "user"
    id = Column(Integer, primary_key=True)
    name = Column(String)

    addresses = relationship("Address", backref="user")

class Address(Base):
    __tablename__ = "address"
    id = Column(Integer, primary_key=True)
    email = Column(String)
    user_id = Column(Integer, ForeignKey("user.id"))

The above configuration establishes a collection of Address objects on User called User.addresses. It also establishes a .user attribute on Address which will refer to the parent User object.

In fact, the backref keyword is only a common shortcut for placing a second relationship() onto the Address mapping, including the establishment of an event listener on both sides which will mirror attribute operations in both directions. The above configuration is equivalent to:

rom sqlalchemy import Integer, ForeignKey, String, Column
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship

Base = declarative_base()

class User(Base):
    __tablename__ = "user"
    id = Column(Integer, primary_key=True)
    name = Column(String)

    addresses = relationship("Address", back_populates="user")
        
class Address(Base):
    __tablename__ = "address"
    id = Column(Integer, primary_key=True)
    email = Column(String)
    user_id = Column(Integer, ForeignKey("user.id"))

    user = relationship("User", back_populates="addresses")

Above, we add a .user relationship to Address explicitly. On both relationships, the back_populates directive tells each relationship about the other one, indicating that they should establish “bidirectional” behavior between each other. The primary effect of this configuration is that the relationship adds event handlers to both attributes which have the behavior of “when an append or set event occurs here, set ourselves onto the incoming attribute using this particular attribute name”. The behavior is illustrated as follows. Start with a User and an Address instance. The .addresses collection is empty, and the .user attribute is None:

>>> u1 = User()
>>> a1 = Address()
>>> u1.addresses
[]
>>> print(a1.user)
None

However, once the Address is appended to the u1.addresses collection, both the collection and the scalar attribute have been populated:

>>> u1.addresses.append(a1)
>>> u1.addresses
[<__main__.Address object at 0x12a6ed0>]
>>> a1.user
<__main__.User object at 0x12a6590>

This behavior of course works in reverse for removal operations as well, as well as for equivalent operations on both sides. Such as when .user is set again to None, the Address object is removed from the reverse collection:

>>> a1.user = None
>>> u1.addresses
[]

The manipulation of the .addresses collection and the .user attribute occurs entirely in Python without any interaction with the SQL database. Without this behavior, the proper state would be apparent on both sides once the data has been flushed to the database, and later reloaded after a commit or expiration operation occurs. The backref/back_populates behavior has the advantage that common bidirectional operations can reflect the correct state without requiring a database round trip.

Remember, when the backref keyword is used on a single relationship, it’s exactly the same as if the above two relationships were created individually using back_populates on each.

mysql操作

檢驗(yàn)一下我們上面的成果以及熟悉創(chuàng)建的mysql表的結(jié)構(gòu)

地址表的結(jié)構(gòu)

> SHOW CREATE TABLE addresses;
+-----------+----------------+
| Table     | Create Table   |
|-----------+----------------|
| addresses | CREATE TABLE `addresses` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `email_address` varchar(50) NOT NULL,
  `user_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `user_id` (`user_id`),
  CONSTRAINT `addresses_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8                |
+-----------+----------------+
1 row in set
Time: 0.005s

> DESC addresses;
+---------------+-------------+--------+-------+-----------+----------------+
| Field         | Type        | Null   | Key   |   Default | Extra          |
|---------------+-------------+--------+-------+-----------+----------------|
| id            | int(11)     | NO     | PRI   |     | auto_increment |
| email_address | varchar(50) | NO     |       |     |                |
| user_id       | int(11)     | YES    | MUL   |     |                |
+---------------+-------------+--------+-------+-----------+----------------+
3 rows in set
Time: 0.002s

用戶表的結(jié)構(gòu)

> SHOW CREATE TABLE users;
+---------+----------------+
| Table   | Create Table   |
|---------+----------------|
| users   | CREATE TABLE `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) DEFAULT NULL,
  `fullname` varchar(50) DEFAULT NULL,
  `password` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8                |
+---------+----------------+
1 row in set
Time: 0.002s

> DESC users;
+----------+-------------+--------+-------+-----------+----------------+
| Field    | Type        | Null   | Key   |   Default | Extra          |
|----------+-------------+--------+-------+-----------+----------------|
| id       | int(11)     | NO     | PRI   |     | auto_increment |
| name     | varchar(50) | YES    |       |     |                |
| fullname | varchar(50) | YES    |       |     |                |
| password | varchar(50) | YES    |       |     |                |
+----------+-------------+--------+-------+-----------+----------------+
4 rows in set
Time: 0.003s

詳細(xì)數(shù)據(jù)

> SELECT * FROM addresses;
+------+-----------------+-----------+
|   id | email_address   |   user_id |
|------+-----------------+-----------|
|    3 | [email protected] |         5 |
|    4 | [email protected]   |         5 |
+------+-----------------+-----------+
2 rows in set
Time: 0.002s

> SELECT * FROM users;
+------+--------+----------------+------------+
|   id | name   | fullname       | password   |
|------+--------+----------------+------------|
|    1 | ed     | Ed Jones       | f8s7ccs    |
|    2 | wendy  | Wendy Williams | foobar     |
|    3 | mary   | Mary Contrary  | xxg527     |
|    4 | fred   | Fred Flinstone | blah       |
|    5 | jack   | Jack Bean      | gjffdd     |
+------+--------+----------------+------------+
5 rows in set
Time: 0.003s
知乎live設(shè)計(jì)模型
from sqlalchemy import Column, String, Integer, create_engine, SmallInteger
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base

DB_URI = "sqlite:///user.db"
Base = declarative_base()
engine = create_engine(DB_URI)
Base.metadata.bind = engine
Session = sessionmaker(bind=engine)
session = Session()
class User(Base):
    __tablename__ = "live_user"
    
    id = Column(Integer, unique=True, primary_key=True, autoincrement=True)
    speaker_id = Column(String(40), index=True, unique=True)
    name = Column(String(40), index=True, nullable=False)
    gender = Column(SmallInteger, default=2)
    headline = Column(String(200))
    avatar_url = Column(String(100), nullable=False)
    bio = Column(String(200))
    description = Column(String())
    
    @classmethod
    def add(cls, **kwargs):
        speaker_id = kwargs.get("speaker_id", None)
        if id is not None:
            r = session.query(cls).filter_by(speaker_id=speaker_id).first()
            if r:
                return r
        try:
            r = cls(**kwargs)
            session.add(r)
            session.commit()
        except:
            session.rollback()
            raise
        else:
            return r
Base.metadata.create_all()

接口分為2種:

https://api.zhihu.com/lives/o... (未結(jié)束)

https://api.zhihu.com/lives/e... (已結(jié)束)

elasticsearch-dsl-py相比elasticsearch-py做了各種封裝,DSL也支持用類代表一個(gè)doc_type(類似數(shù)據(jù)庫(kù)中的Table),實(shí)現(xiàn)ORM的效果。我們就用它來(lái)寫Live模型:

from elasticsearch_dsl import DocType, Date, Integer, Text, Float, Boolean
from elasticsearch_dsl.connections import connections
from elasticsearch_dsl.query import SF, Q
from config import SEARCH_FIELDS
from .speaker import User, session

connections.create_connection(hosts=["localhost"])
class Live(DocType):
    id = Integer()
    speaker_id = Integer()
    feedback_score = Float() # 評(píng)分
    topic_names = Text(analyzer="ik_max_word")  # 話題標(biāo)簽名字
    seats_taken = Integer()  # 參與人數(shù)
    subject = Text(analyzer="ik_max_word")  # 標(biāo)題
    amount = Float()  # 價(jià)格(RMB)
    description = Text(analyzer="ik_max_word")
    status = Boolean()  # public(True)/ended(False)
    starts_at = Date()
    outline = Text(analyzer="ik_max_word")  # Live內(nèi)容
    speaker_message_count = Integer()
    tag_names = Text(analyzer="ik_max_word")
    liked_num = Integer()
    
    class Meta:
        index = "live"
        
    @classmethod
    def add(cls, **kwargs):
        id = kwargs.pop("id", None)
        if id is None:
            return False
        live = cls(meta={"id": id}, **kwargs)
        live.save()
        return live

它允許我們用一種非常可維護(hù)的方法來(lái)組織字典:

In : from elasticsearch_dsl.query import Q
In : Q("multi_match", subject="python").to_dict()
Out: {"multi_match": {"subject": "python"}}
In : from elasticsearch import Elasticsearch
In : from elasticsearch_dsl import Search, Q
In : s = Search(using=client, index="live")
In : s = s.query("match", subject="python").query(~Q("match", description="量化"))
In : s.execute()
Out: ]>

上述例子表示從live這個(gè)索引(類似數(shù)據(jù)庫(kù)中的Database)中找到subject字典包含python,但是description字段不包含量化的Live。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/38390.html

相關(guān)文章

  • Python-SQLAlchemy:第2節(jié):查詢條件設(shè)置

    摘要:上一篇文章第節(jié)入門下一篇文章第節(jié)關(guān)系操作在實(shí)際編程中需要根據(jù)各種不同的條件查詢數(shù)據(jù)庫(kù)記錄,查詢條件被稱為過(guò)濾器。通配符用百分號(hào)表示。以下條語(yǔ)句查詢結(jié)果相同,都是為的記錄。引入或邏輯關(guān)鍵字查詢是或者為的記錄,返回結(jié)果為為的記錄 上一篇文章:Python-SQLAlchemy:第1節(jié):SQLAlchemy入門下一篇文章:Python-SQLAlchemy:第3節(jié):關(guān)系操作 在實(shí)際編程中需...

    selfimpr 評(píng)論0 收藏0
  • Python-SQLAlchemy:第3節(jié):關(guān)系操作

    摘要:本節(jié)圍繞在中如何定義關(guān)系及如何使用關(guān)系進(jìn)行查詢進(jìn)行講解,使讀者能夠快速掌握的關(guān)系操作。班級(jí)與學(xué)生為一對(duì)多關(guān)系,班級(jí)與老師之間為多對(duì)多關(guān)系。三年二班多對(duì)多關(guān)系的使用通過(guò)關(guān)聯(lián)模型實(shí)現(xiàn),在其中分別設(shè)置模型和的外鍵,并且在父模型中設(shè)置相應(yīng)的實(shí)現(xiàn)。 上一篇文章:Python-SQLAlchemy:第2節(jié):查詢條件設(shè)置下一篇文章:Python-SQLAlchemy:第4節(jié):級(jí)聯(lián) 關(guān)系數(shù)據(jù)庫(kù)是建立...

    William_Sang 評(píng)論0 收藏0
  • Python-SQLAlchemy:第1節(jié):SQLAlchemy入門

    摘要:下一篇文章第節(jié)查詢條件設(shè)置是編程語(yǔ)言下的一款開源軟件。提供了工具包及對(duì)象關(guān)系映射工具,使用許可證發(fā)行。在關(guān)閉連接時(shí)會(huì)自動(dòng)進(jìn)行事務(wù)提交操作。引入多條件查詢時(shí)使用。由于上下文函數(shù)退出時(shí)會(huì)自動(dòng)提交事務(wù),所以無(wú)需顯示的調(diào)用使新增生效。 下一篇文章:Python-SQLAlchemy:第2節(jié):查詢條件設(shè)置 SQLAlchemy是Python編程語(yǔ)言下的一款開源軟件。提供了SQL工具包及對(duì)象關(guān)系...

    noONE 評(píng)論0 收藏0
  • Python-SQLAlchemy:第4節(jié):級(jí)聯(lián)

    摘要:上一篇文章第節(jié)關(guān)系操作級(jí)聯(lián)是在一對(duì)多關(guān)系中父表與子表進(jìn)行聯(lián)動(dòng)操作的數(shù)據(jù)庫(kù)術(shù)語(yǔ)。注意級(jí)聯(lián)獨(dú)立于本身針對(duì)外鍵的級(jí)聯(lián)定義。代碼執(zhí)行后數(shù)據(jù)庫(kù)表中的內(nèi)容的變化表五年二班理想路號(hào)樓表理想男靜安區(qū)女靜安區(qū)小馬哥女閘口區(qū)張三韓永躍男靜安區(qū) 上一篇文章:Python-SQLAlchemy:第3節(jié):關(guān)系操作 級(jí)聯(lián)是在一對(duì)多關(guān)系中父表與子表進(jìn)行聯(lián)動(dòng)操作的數(shù)據(jù)庫(kù)術(shù)語(yǔ)。因?yàn)楦副砼c子表通過(guò)外鍵關(guān)聯(lián),所以對(duì)父表或...

    henry14 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<