Python-SQLALchemy
Initialization
# 检查是否已经安装以及版本号 >>> 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' # 指定数据表名 ... ... id = Column(Integer, primary_key=True) ... name = Column(String(50)) ... fullname = Column(String(50)) ... password = Column(String(50)) ... ... def __repr__(self): ... return "<User(name='%s', fullname='%s', password='%s')>" % ( ... self.name, self.fullname, self.password) # 查看创建的数据表结构 >>> User.__table__ Table('users', MetaData(bind=None), Column('id', Integer(), table=<users>, primary_key=True, nullable=False), Column('name', String(length=50), table=<users>), Column('fullname', String(length=50), table=<users>), Column('password', String(length=50), table=<users>), schema=None)
Formally creating a data table
>>> from sqlalchemy import create_engine # 连接到mysql >>> engine = create_engine("mysql://root:root@localhost:3306/python?charset=utf8", encoding="utf-8", echo=True) # 正式创建数据表 >>> 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
The following operations are all done through session object operations
>>> from sqlalchemy.orm import sessionmaker >>> Session = sessionmaker(bind=engine) >>> session = Session()
Adding and Updating Objects
Add a User object
>>> ed_user = User(name='ed', fullname='Ed Jones', password='edspassword') >>> session.add(ed_user)
Query it, use filter_by
to filter, first
Only list the first queried object
>>> 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 <User(name='ed', fullname='Ed Jones', password='edspassword')> >>> ed_user is our_user True
Use add_all
to add multiple objects at once
>>> 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 is very smart, for example, it knows that Ed Jones has been modified
# 可以直接修改ed_user对象 >>> ed_user.password = 'f8s7ccs' # session会自动知道哪些数据被修改了 >>> session.dirty IdentitySet([<User(name='ed', fullname='Ed Jones', password='f8s7ccs')>]) # session也可以知道哪些对象被新建了 >>> session.new IdentitySet([<User(name='wendy', fullname='Wendy Williams', password='foobar')>, <User(name='mary', fullname='Mary Contrary', password='xxg527')>, <User(name='fred', fullname='Fred Flinstone', password='blah')>])
When changes are made to the database, commit
is naturally required. From the echo
statement, we can see that we updated 1 object and created 3 objects.
>>> 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
Because Session works inside a transaction, sometimes we may accidentally do some deletion operations and can roll back. We first modify the username of ed_user to Edwardo
, and then add a new User, but remember that we have not commit
at this time.
>>> 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:
Check the query
>>> 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') [<User(name='Edwardo', fullname='Ed Jones', password='f8s7ccs')>, <User(name='fakeuser', fullname='Invalid', password='12345')>]
Rollback, we can know that ed_user's name is back to ed
and 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:
If you query again at this time, it is obvious that the fakeuser has disappeared, and the user's name ed
has changed back to ed
instead of 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') [<User(name='ed', fullname='Ed Jones', password='f8s7ccs')>]
Couting
The count() operation corresponding to the query operation
>>> 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
A pass in Session Use the query
method to create a Query
object
Sort by user id to query
>>> 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
The query method can also receive ORM-instrumented descriptors as parameters. The returned result is a 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) <User(name='ed', fullname='Ed Jones', password='f8s7ccs')> ed <User(name='wendy', fullname='Wendy Williams', password='foobar')> wendy <User(name='mary', fullname='Mary Contrary', password='xxg527')> mary <User(name='fred', fullname='Fred Flinstone', password='blah')> fred
You can control the names of inpidual 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) <User(name='ed', fullname='Ed Jones', password='f8s7ccs')> <User(name='wendy', fullname='Wendy Williams', password='foobar')> <User(name='mary', fullname='Mary Contrary', password='xxg527')> <User(name='fred', fullname='Fred Flinstone', password='blah')>
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) <User(name='wendy', fullname='Wendy Williams', password='foobar')> <User(name='mary', fullname='Mary Contrary', password='xxg527')> 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) <User(name='ed', fullname='Ed Jones', password='f8s7ccs')> Common Filter Operators
filter()
is listed below Some of the most commonly used 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
Create the relationship between objects. Let’s create a new Address table. The following operations are more cumbersome than Django’s ORM. They need to be done at the same time. Set relationship inside both classes at the same time
>>> 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") # 将地址表和用户表关联 ... ... def __repr__(self): ... return "<Address(email_address='%s')>" % self.email_address # 在用户表中还要重新设置一次 >>> User.addresses = relationship( ... "Address", order_by=Address.id, back_populates="user") >>> Base.metadata.create_all(engine)
Working with Related Objects
Now that we have created a User, an empty addresses collection corresponding to it will also be created. The collection type can be any legal type, such as set/dictionaries (see Customizing Collection Access for details), but the default collection is a list.
Now let’s create another user 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:
Now We associate user Jack with some addresses
>>> jack.addresses = [ ... Address(email_address='jack@google.com'), ... Address(email_address='j25@yahoo.com')]
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:
Now the user object can be accessed through the address object
>>> jack.addresses[1] <Address(email_address='j25@yahoo.com')> >>> jack.addresses[1].user <User(name='jack', fullname='Jack Bean', password='gjffdd')>
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:
Nextcommit
Saved to database
>>> session.add(jack) >>> session.commit() sqlalchemy.engine.base.Engine INSERT INTO addresses (email_address, user_id) VALUES (%s, %s) sqlalchemy.engine.base.Engine ('jack@google.com', 5L) sqlalchemy.engine.base.Engine INSERT INTO addresses (email_address, user_id) VALUES (%s, %s) sqlalchemy.engine.base.Engine ('j25@yahoo.com', 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 <User(name='jack', fullname='Jack Bean', password='gjffdd')> Let’s look at the addresses collection. Watch the SQL: >>> jack.addresses [<Address(email_address='jack@google.com')>, <Address(email_address='j25@yahoo.com')>]
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
Delete operation, next we try to delete the jack object, note that the address object will not be deleted because of this
>>> 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_(['jack@google.com', 'j25@yahoo.com']) ... ).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来rollback,并不进行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 "<User(name='%s', fullname='%s', password='%s')>" % ( ... 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 "<Address(email_address='%s')>" % 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_(['jack@google.com', 'j25@yahoo.com']) ... ).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_(['jack@google.com', 'j25@yahoo.com']) ... ).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
上面同时设置两个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 inpidually using back_populates on each.
mysql操作
检验一下我们上面的成果以及熟悉创建的mysql表的结构
地址表的结构
> 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 | <null> | auto_increment | | email_address | varchar(50) | NO | | <null> | | | user_id | int(11) | YES | MUL | <null> | | +---------------+-------------+--------+-------+-----------+----------------+ 3 rows in set Time: 0.002s
用户表的结构
> 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 | <null> | auto_increment | | name | varchar(50) | YES | | <null> | | | fullname | varchar(50) | YES | | <null> | | | password | varchar(50) | YES | | <null> | | +----------+-------------+--------+-------+-----------+----------------+ 4 rows in set Time: 0.003s
详细数据
> SELECT * FROM addresses; +------+-----------------+-----------+ | id | email_address | user_id | |------+-----------------+-----------| | 3 | jack@google.com | 5 | | 4 | j25@yahoo.com | 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设计模型
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种:
http://www.php.cn/ (未结束)
http://www.php.cn/ (已结束)
elasticsearch-dsl-py相比elasticsearch-py做了各种封装,DSL也支持用类代表一个doc_type(类似数据库中的Table),实现ORM的效果。我们就用它来写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() # 评分 topic_names = Text(analyzer='ik_max_word') # 话题标签名字 seats_taken = Integer() # 参与人数 subject = Text(analyzer='ik_max_word') # 标题 amount = Float() # 价格(RMB) description = Text(analyzer='ik_max_word') status = Boolean() # public(True)/ended(False) starts_at = Date() outline = Text(analyzer='ik_max_word') # Live内容 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
它允许我们用一种非常可维护的方法来组织字典:
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: <Response: [<Hit(live/live/789840559912009728): {'subject': 'Python 工程师的入门和进阶', 'feedback_score': 4.5, 'stat...}>]>
上述例子表示从live这个索引(类似数据库中的Database)中找到subject字典包含python,但是description字段不包含量化的Live。
更多Python-SQLALchemy 相关文章请关注PHP中文网!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics



PHP and Python have their own advantages and disadvantages, and the choice depends on project needs and personal preferences. 1.PHP is suitable for rapid development and maintenance of large-scale web applications. 2. Python dominates the field of data science and machine learning.

Docker uses Linux kernel features to provide an efficient and isolated application running environment. Its working principle is as follows: 1. The mirror is used as a read-only template, which contains everything you need to run the application; 2. The Union File System (UnionFS) stacks multiple file systems, only storing the differences, saving space and speeding up; 3. The daemon manages the mirrors and containers, and the client uses them for interaction; 4. Namespaces and cgroups implement container isolation and resource limitations; 5. Multiple network modes support container interconnection. Only by understanding these core concepts can you better utilize Docker.

Efficient training of PyTorch models on CentOS systems requires steps, and this article will provide detailed guides. 1. Environment preparation: Python and dependency installation: CentOS system usually preinstalls Python, but the version may be older. It is recommended to use yum or dnf to install Python 3 and upgrade pip: sudoyumupdatepython3 (or sudodnfupdatepython3), pip3install--upgradepip. CUDA and cuDNN (GPU acceleration): If you use NVIDIAGPU, you need to install CUDATool

Enable PyTorch GPU acceleration on CentOS system requires the installation of CUDA, cuDNN and GPU versions of PyTorch. The following steps will guide you through the process: CUDA and cuDNN installation determine CUDA version compatibility: Use the nvidia-smi command to view the CUDA version supported by your NVIDIA graphics card. For example, your MX450 graphics card may support CUDA11.1 or higher. Download and install CUDAToolkit: Visit the official website of NVIDIACUDAToolkit and download and install the corresponding version according to the highest CUDA version supported by your graphics card. Install cuDNN library:

Python and JavaScript have their own advantages and disadvantages in terms of community, libraries and resources. 1) The Python community is friendly and suitable for beginners, but the front-end development resources are not as rich as JavaScript. 2) Python is powerful in data science and machine learning libraries, while JavaScript is better in front-end development libraries and frameworks. 3) Both have rich learning resources, but Python is suitable for starting with official documents, while JavaScript is better with MDNWebDocs. The choice should be based on project needs and personal interests.

When selecting a PyTorch version under CentOS, the following key factors need to be considered: 1. CUDA version compatibility GPU support: If you have NVIDIA GPU and want to utilize GPU acceleration, you need to choose PyTorch that supports the corresponding CUDA version. You can view the CUDA version supported by running the nvidia-smi command. CPU version: If you don't have a GPU or don't want to use a GPU, you can choose a CPU version of PyTorch. 2. Python version PyTorch

CentOS Installing Nginx requires following the following steps: Installing dependencies such as development tools, pcre-devel, and openssl-devel. Download the Nginx source code package, unzip it and compile and install it, and specify the installation path as /usr/local/nginx. Create Nginx users and user groups and set permissions. Modify the configuration file nginx.conf, and configure the listening port and domain name/IP address. Start the Nginx service. Common errors need to be paid attention to, such as dependency issues, port conflicts, and configuration file errors. Performance optimization needs to be adjusted according to the specific situation, such as turning on cache and adjusting the number of worker processes.

Efficiently process PyTorch data on CentOS system, the following steps are required: Dependency installation: First update the system and install Python3 and pip: sudoyumupdate-ysudoyuminstallpython3-ysudoyuminstallpython3-pip-y Then, download and install CUDAToolkit and cuDNN from the NVIDIA official website according to your CentOS version and GPU model. Virtual environment configuration (recommended): Use conda to create and activate a new virtual environment, for example: condacreate-n
