datanommer.models 1.0.4__py3-none-any.whl → 1.3.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- datanommer/models/__init__.py +104 -74
- datanommer/models/testing/__init__.py +37 -27
- datanommer_models-1.3.0.dist-info/METADATA +55 -0
- datanommer_models-1.3.0.dist-info/RECORD +10 -0
- {datanommer.models-1.0.4.dist-info → datanommer_models-1.3.0.dist-info}/WHEEL +1 -1
- datanommer/models/testing/startup.sql +0 -1
- datanommer.models-1.0.4.dist-info/METADATA +0 -43
- datanommer.models-1.0.4.dist-info/RECORD +0 -11
- {datanommer.models-1.0.4.dist-info → datanommer_models-1.3.0.dist-info}/LICENSE +0 -0
datanommer/models/__init__.py
CHANGED
@@ -14,6 +14,7 @@
|
|
14
14
|
# You should have received a copy of the GNU General Public License along
|
15
15
|
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
16
16
|
import datetime
|
17
|
+
import importlib.metadata
|
17
18
|
import json
|
18
19
|
import logging
|
19
20
|
import math
|
@@ -21,7 +22,6 @@ import traceback
|
|
21
22
|
import uuid
|
22
23
|
from warnings import warn
|
23
24
|
|
24
|
-
import pkg_resources
|
25
25
|
from sqlalchemy import (
|
26
26
|
and_,
|
27
27
|
between,
|
@@ -31,11 +31,14 @@ from sqlalchemy import (
|
|
31
31
|
DDL,
|
32
32
|
event,
|
33
33
|
ForeignKey,
|
34
|
+
func,
|
34
35
|
Integer,
|
35
36
|
not_,
|
36
37
|
or_,
|
38
|
+
select,
|
37
39
|
String,
|
38
40
|
Table,
|
41
|
+
text,
|
39
42
|
TypeDecorator,
|
40
43
|
Unicode,
|
41
44
|
UnicodeText,
|
@@ -61,6 +64,9 @@ except ImportError: # pragma: no cover
|
|
61
64
|
UniqueViolation = lookup_error("23505")
|
62
65
|
|
63
66
|
|
67
|
+
__version__ = importlib.metadata.version("datanommer.models")
|
68
|
+
|
69
|
+
|
64
70
|
log = logging.getLogger("datanommer")
|
65
71
|
|
66
72
|
maker = sessionmaker()
|
@@ -80,7 +86,7 @@ def init(uri=None, alembic_ini=None, engine=None, create=False):
|
|
80
86
|
raise ValueError("One of uri or engine must be specified")
|
81
87
|
|
82
88
|
if uri and not engine:
|
83
|
-
engine = create_engine(uri)
|
89
|
+
engine = create_engine(uri, future=True)
|
84
90
|
|
85
91
|
# We need to hang our own attribute on the sqlalchemy session to stop
|
86
92
|
# ourselves from initializing twice. That is only a problem if the code
|
@@ -90,11 +96,12 @@ def init(uri=None, alembic_ini=None, engine=None, create=False):
|
|
90
96
|
return
|
91
97
|
session._datanommer_initialized = True
|
92
98
|
|
93
|
-
|
99
|
+
maker.configure(bind=engine)
|
94
100
|
DeclarativeBase.query = session.query_property()
|
95
101
|
|
96
102
|
if create:
|
97
|
-
|
103
|
+
with engine.begin() as connection:
|
104
|
+
connection.execute(text("CREATE EXTENSION IF NOT EXISTS timescaledb"))
|
98
105
|
DeclarativeBase.metadata.create_all(engine)
|
99
106
|
# Loads the alembic configuration and generates the version table, with
|
100
107
|
# the most recent revision stamped as head
|
@@ -122,7 +129,7 @@ def add(message):
|
|
122
129
|
log.exception("Failed to parse sent-at timestamp value")
|
123
130
|
return
|
124
131
|
else:
|
125
|
-
sent_at = datetime.datetime.
|
132
|
+
sent_at = datetime.datetime.now(tz=datetime.timezone.utc)
|
126
133
|
|
127
134
|
# Workaround schemas misbehaving
|
128
135
|
try:
|
@@ -158,15 +165,10 @@ def add(message):
|
|
158
165
|
session.commit()
|
159
166
|
|
160
167
|
|
161
|
-
def source_version_default(context):
|
162
|
-
dist = pkg_resources.get_distribution("datanommer.models")
|
163
|
-
return dist.version
|
164
|
-
|
165
|
-
|
166
168
|
# https://docs.sqlalchemy.org/en/14/core/custom_types.html#marshal-json-strings
|
167
169
|
|
168
170
|
|
169
|
-
class
|
171
|
+
class _JSONEncodedDict(TypeDecorator):
|
170
172
|
"""Represents an immutable structure as a json-encoded string."""
|
171
173
|
|
172
174
|
impl = UnicodeText
|
@@ -224,8 +226,8 @@ class Message(DeclarativeBase):
|
|
224
226
|
username = Column(Unicode)
|
225
227
|
crypto = Column(UnicodeText)
|
226
228
|
source_name = Column(Unicode, default="datanommer")
|
227
|
-
source_version = Column(Unicode, default=
|
228
|
-
msg = Column(
|
229
|
+
source_version = Column(Unicode, default=lambda context: __version__)
|
230
|
+
msg = Column(_JSONEncodedDict, nullable=False)
|
229
231
|
headers = Column(postgresql.JSONB(none_as_null=True))
|
230
232
|
users = relationship(
|
231
233
|
"User",
|
@@ -314,7 +316,7 @@ class Message(DeclarativeBase):
|
|
314
316
|
|
315
317
|
@classmethod
|
316
318
|
def from_msg_id(cls, msg_id):
|
317
|
-
return cls.
|
319
|
+
return session.execute(select(cls).where(cls.msg_id == msg_id)).scalar_one_or_none()
|
318
320
|
|
319
321
|
def as_dict(self, request=None):
|
320
322
|
return dict(
|
@@ -337,13 +339,12 @@ class Message(DeclarativeBase):
|
|
337
339
|
def as_fedora_message_dict(self):
|
338
340
|
headers = self.headers or {}
|
339
341
|
if "sent-at" not in headers:
|
340
|
-
headers["sent-at"] = self.timestamp.astimezone(
|
341
|
-
datetime.timezone.utc
|
342
|
-
).isoformat()
|
342
|
+
headers["sent-at"] = self.timestamp.astimezone(datetime.timezone.utc).isoformat()
|
343
343
|
return dict(
|
344
344
|
body=self.msg,
|
345
345
|
headers=headers,
|
346
346
|
id=self.msg_id,
|
347
|
+
priority=headers.get("priority", 0),
|
347
348
|
queue=None,
|
348
349
|
topic=self.topic,
|
349
350
|
)
|
@@ -353,17 +354,15 @@ class Message(DeclarativeBase):
|
|
353
354
|
"The __json__() method has been renamed to as_dict(), and will be removed "
|
354
355
|
"in the next major version",
|
355
356
|
DeprecationWarning,
|
357
|
+
stacklevel=2,
|
356
358
|
)
|
357
359
|
return self.as_dict(request)
|
358
360
|
|
359
361
|
@classmethod
|
360
|
-
def
|
362
|
+
def make_query(
|
361
363
|
cls,
|
362
364
|
start=None,
|
363
365
|
end=None,
|
364
|
-
page=1,
|
365
|
-
rows_per_page=100,
|
366
|
-
order="asc",
|
367
366
|
msg_id=None,
|
368
367
|
users=None,
|
369
368
|
not_users=None,
|
@@ -374,7 +373,6 @@ class Message(DeclarativeBase):
|
|
374
373
|
topics=None,
|
375
374
|
not_topics=None,
|
376
375
|
contains=None,
|
377
|
-
defer=False,
|
378
376
|
):
|
379
377
|
"""Flexible query interface for messages.
|
380
378
|
|
@@ -402,11 +400,6 @@ class Message(DeclarativeBase):
|
|
402
400
|
|
403
401
|
(user == 'ralph') AND
|
404
402
|
NOT (category == 'bodhi' OR category == 'wiki')
|
405
|
-
|
406
|
-
----
|
407
|
-
|
408
|
-
If the `defer` argument evaluates to True, the query won't actually
|
409
|
-
be executed, but a SQLAlchemy query object returned instead.
|
410
403
|
"""
|
411
404
|
|
412
405
|
users = users or []
|
@@ -419,87 +412,137 @@ class Message(DeclarativeBase):
|
|
419
412
|
not_topics = not_topics or []
|
420
413
|
contains = contains or []
|
421
414
|
|
422
|
-
|
415
|
+
Message = cls
|
416
|
+
query = select(Message)
|
423
417
|
|
424
418
|
# A little argument validation. We could provide some defaults in
|
425
419
|
# these mixed cases.. but instead we'll just leave it up to our caller.
|
426
420
|
if (start is not None and end is None) or (end is not None and start is None):
|
427
421
|
raise ValueError(
|
428
|
-
"Either both start and end must be specified "
|
429
|
-
"or neither must be specified"
|
422
|
+
"Either both start and end must be specified or neither must be specified"
|
430
423
|
)
|
431
424
|
|
432
425
|
if start and end:
|
433
|
-
query = query.
|
426
|
+
query = query.where(between(Message.timestamp, start, end))
|
434
427
|
|
435
428
|
if msg_id:
|
436
|
-
query = query.
|
429
|
+
query = query.where(Message.msg_id == msg_id)
|
437
430
|
|
438
431
|
# Add the four positive filters as necessary
|
439
432
|
if users:
|
440
|
-
query = query.
|
441
|
-
or_(*(Message.users.any(User.name == u) for u in users))
|
442
|
-
)
|
433
|
+
query = query.where(or_(*(Message.users.any(User.name == u) for u in users)))
|
443
434
|
|
444
435
|
if packages:
|
445
|
-
query = query.
|
446
|
-
or_(*(Message.packages.any(Package.name == p) for p in packages))
|
447
|
-
)
|
436
|
+
query = query.where(or_(*(Message.packages.any(Package.name == p) for p in packages)))
|
448
437
|
|
449
438
|
if categories:
|
450
|
-
query = query.
|
451
|
-
or_(*(Message.category == category for category in categories))
|
452
|
-
)
|
439
|
+
query = query.where(or_(*(Message.category == category for category in categories)))
|
453
440
|
|
454
441
|
if topics:
|
455
|
-
query = query.
|
442
|
+
query = query.where(or_(*(Message.topic == topic for topic in topics)))
|
456
443
|
|
457
444
|
if contains:
|
458
|
-
query = query.
|
459
|
-
or_(*(Message.msg.like(f"%{contain}%") for contain in contains))
|
460
|
-
)
|
445
|
+
query = query.where(or_(*(Message.msg.like(f"%{contain}%") for contain in contains)))
|
461
446
|
|
462
447
|
# And then the four negative filters as necessary
|
463
448
|
if not_users:
|
464
|
-
query = query.
|
465
|
-
not_(or_(*(Message.users.any(User.name == u) for u in not_users)))
|
466
|
-
)
|
449
|
+
query = query.where(not_(or_(*(Message.users.any(User.name == u) for u in not_users))))
|
467
450
|
|
468
451
|
if not_packs:
|
469
|
-
query = query.
|
452
|
+
query = query.where(
|
470
453
|
not_(or_(*(Message.packages.any(Package.name == p) for p in not_packs)))
|
471
454
|
)
|
472
455
|
|
473
456
|
if not_cats:
|
474
|
-
query = query.
|
475
|
-
not_(or_(*(Message.category == category for category in not_cats)))
|
476
|
-
)
|
457
|
+
query = query.where(not_(or_(*(Message.category == category for category in not_cats))))
|
477
458
|
|
478
459
|
if not_topics:
|
479
|
-
query = query.
|
480
|
-
|
481
|
-
|
460
|
+
query = query.where(not_(or_(*(Message.topic == topic for topic in not_topics))))
|
461
|
+
|
462
|
+
return query
|
463
|
+
|
464
|
+
@classmethod
|
465
|
+
def grep(
|
466
|
+
cls,
|
467
|
+
*,
|
468
|
+
page=1,
|
469
|
+
rows_per_page=100,
|
470
|
+
order="asc",
|
471
|
+
defer=False,
|
472
|
+
**kwargs,
|
473
|
+
):
|
474
|
+
"""Flexible query interface for messages.
|
475
|
+
|
476
|
+
Arguments are filters. start and end should be :mod:`datetime` objs.
|
477
|
+
|
478
|
+
Other filters should be lists of strings. They are applied in a
|
479
|
+
conjunctive-normal-form (CNF) kind of way
|
482
480
|
|
481
|
+
for example, the following::
|
482
|
+
|
483
|
+
users = ['ralph', 'lmacken']
|
484
|
+
categories = ['bodhi', 'wiki']
|
485
|
+
|
486
|
+
should return messages where
|
487
|
+
|
488
|
+
(user=='ralph' OR user=='lmacken') AND
|
489
|
+
(category=='bodhi' OR category=='wiki')
|
490
|
+
|
491
|
+
Furthermore, you can use a negative version of each argument.
|
492
|
+
|
493
|
+
users = ['ralph']
|
494
|
+
not_categories = ['bodhi', 'wiki']
|
495
|
+
|
496
|
+
should return messages where
|
497
|
+
|
498
|
+
(user == 'ralph') AND
|
499
|
+
NOT (category == 'bodhi' OR category == 'wiki')
|
500
|
+
|
501
|
+
----
|
502
|
+
|
503
|
+
The ``jsons`` argument is a list of jsonpath filters, please refer to
|
504
|
+
`PostgreSQL's documentation
|
505
|
+
<https://www.postgresql.org/docs/current/functions-json.html#FUNCTIONS-SQLJSON-PATH>`_
|
506
|
+
on the matter to learn how to build the jsonpath expression.
|
507
|
+
|
508
|
+
The ``jsons_and`` argument is similar to the ``jsons`` argument, but all
|
509
|
+
the values must match for a message to be returned.
|
510
|
+
"""
|
511
|
+
query = cls.make_query(**kwargs)
|
483
512
|
# Finally, tag on our pagination arguments
|
484
|
-
|
513
|
+
Message = cls
|
514
|
+
|
515
|
+
query_total = query.with_only_columns(func.count(Message.id))
|
516
|
+
total = None
|
485
517
|
query = query.order_by(getattr(Message.timestamp, order)())
|
486
518
|
|
487
519
|
if not rows_per_page:
|
488
520
|
pages = 1
|
489
521
|
else:
|
522
|
+
total = session.scalar(query_total)
|
490
523
|
pages = int(math.ceil(total / float(rows_per_page)))
|
491
524
|
query = query.offset(rows_per_page * (page - 1)).limit(rows_per_page)
|
492
525
|
|
493
526
|
if defer:
|
494
|
-
|
527
|
+
if total is None:
|
528
|
+
total = session.scalar(query_total)
|
529
|
+
return total, pages, query
|
495
530
|
else:
|
496
531
|
# Execute!
|
497
|
-
messages = query.all()
|
532
|
+
messages = session.scalars(query).all()
|
533
|
+
if pages == 1:
|
534
|
+
total = len(messages)
|
498
535
|
return total, pages, messages
|
499
536
|
|
537
|
+
@classmethod
|
538
|
+
def get_first(cls, *, order="asc", **kwargs):
|
539
|
+
"""Get the first message matching the regular grep filters."""
|
540
|
+
query = cls.make_query(**kwargs)
|
541
|
+
query = query.order_by(getattr(Message.timestamp, order)())
|
542
|
+
return session.scalars(query).first()
|
500
543
|
|
501
|
-
class NamedSingleton:
|
502
544
|
|
545
|
+
class NamedSingleton:
|
503
546
|
id = Column(Integer, primary_key=True, autoincrement=True)
|
504
547
|
name = Column(UnicodeText, index=True, unique=True)
|
505
548
|
|
@@ -513,8 +556,8 @@ class NamedSingleton:
|
|
513
556
|
if name in cls._cache:
|
514
557
|
# If we cache the instance, SQLAlchemy will run this query anyway because the instance
|
515
558
|
# will be from a different transaction. So just cache the id.
|
516
|
-
return
|
517
|
-
obj = cls.
|
559
|
+
return session.get(cls, cls._cache[name])
|
560
|
+
obj = session.execute(select(cls).where(cls.name == name)).scalar_one_or_none()
|
518
561
|
if obj is None:
|
519
562
|
obj = cls(name=name)
|
520
563
|
session.add(obj)
|
@@ -546,16 +589,3 @@ def _setup_hypertable(table_class):
|
|
546
589
|
|
547
590
|
|
548
591
|
_setup_hypertable(Message)
|
549
|
-
|
550
|
-
|
551
|
-
# Set the version
|
552
|
-
try: # pragma: no cover
|
553
|
-
import importlib.metadata
|
554
|
-
|
555
|
-
__version__ = importlib.metadata.version("datanommer.models")
|
556
|
-
except ImportError: # pragma: no cover
|
557
|
-
try:
|
558
|
-
__version__ = pkg_resources.get_distribution("datanommer.models").version
|
559
|
-
except pkg_resources.DistributionNotFound:
|
560
|
-
# The app is not installed, but the flask dev server can run it nonetheless.
|
561
|
-
__version__ = None
|
@@ -1,46 +1,56 @@
|
|
1
|
-
import os
|
2
|
-
|
3
1
|
import pytest
|
2
|
+
import sqlalchemy as sa
|
4
3
|
from pytest_postgresql import factories
|
4
|
+
from pytest_postgresql.janitor import DatabaseJanitor
|
5
5
|
from sqlalchemy.orm import scoped_session
|
6
6
|
|
7
7
|
import datanommer.models as dm
|
8
8
|
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
with open(os.path.join(postgresql_proc.datadir, "postgresql.conf"), "a") as pgconf:
|
13
|
-
pgconf.write("\nshared_preload_libraries = 'timescaledb'\n")
|
14
|
-
pgconf.write("timescaledb.telemetry_level=off\n")
|
15
|
-
postgresql_proc.stop()
|
16
|
-
postgresql_proc.start()
|
17
|
-
yield postgresql_proc
|
18
|
-
|
19
|
-
|
20
|
-
_inital_sql = os.path.abspath(os.path.join(os.path.dirname(__file__), "startup.sql"))
|
21
|
-
pgsql = factories.postgresql(
|
22
|
-
"postgresql_proc_with_timescaledb",
|
23
|
-
load=[_inital_sql],
|
10
|
+
postgresql_proc = factories.postgresql_proc(
|
11
|
+
postgres_options="-c shared_preload_libraries=timescaledb -c timescaledb.telemetry_level=off",
|
24
12
|
)
|
25
13
|
|
26
14
|
|
27
|
-
@pytest.fixture()
|
28
|
-
def datanommer_db_url(
|
15
|
+
@pytest.fixture(scope="session")
|
16
|
+
def datanommer_db_url(postgresql_proc):
|
29
17
|
return (
|
30
|
-
f"postgresql+psycopg2://{
|
31
|
-
f"{
|
32
|
-
f"/{
|
18
|
+
f"postgresql+psycopg2://{postgresql_proc.user}:@"
|
19
|
+
f"{postgresql_proc.host}:{postgresql_proc.port}"
|
20
|
+
f"/{postgresql_proc.dbname}"
|
33
21
|
)
|
34
22
|
|
35
23
|
|
24
|
+
@pytest.fixture(scope="session")
|
25
|
+
def datanommer_db_engine(postgresql_proc, datanommer_db_url):
|
26
|
+
with DatabaseJanitor(
|
27
|
+
user=postgresql_proc.user,
|
28
|
+
host=postgresql_proc.host,
|
29
|
+
port=postgresql_proc.port,
|
30
|
+
dbname=postgresql_proc.dbname,
|
31
|
+
# Don't use a template database
|
32
|
+
# template_dbname=postgresql_proc.template_dbname,
|
33
|
+
version=postgresql_proc.version,
|
34
|
+
):
|
35
|
+
engine = sa.create_engine(datanommer_db_url, future=True)
|
36
|
+
# Renew the global object, dm.init checks a custom attribute
|
37
|
+
dm.session = scoped_session(dm.maker)
|
38
|
+
dm.init(engine=engine, create=True)
|
39
|
+
yield engine
|
40
|
+
engine.dispose()
|
41
|
+
|
42
|
+
|
43
|
+
@pytest.fixture()
|
44
|
+
def datanommer_db(datanommer_db_url, datanommer_db_engine):
|
45
|
+
for table in reversed(dm.DeclarativeBase.metadata.sorted_tables):
|
46
|
+
dm.session.execute(table.delete())
|
47
|
+
dm.session.commit()
|
48
|
+
yield datanommer_db_engine
|
49
|
+
|
50
|
+
|
36
51
|
@pytest.fixture()
|
37
|
-
def datanommer_models(
|
38
|
-
dm.session = scoped_session(dm.maker)
|
39
|
-
dm.init(datanommer_db_url, create=True)
|
52
|
+
def datanommer_models(datanommer_db):
|
40
53
|
dm.User.clear_cache()
|
41
54
|
dm.Package.clear_cache()
|
42
55
|
yield dm.session
|
43
56
|
dm.session.rollback()
|
44
|
-
# engine = dm.session.get_bind()
|
45
|
-
dm.session.close()
|
46
|
-
# dm.DeclarativeBase.metadata.drop_all(engine)
|
@@ -0,0 +1,55 @@
|
|
1
|
+
Metadata-Version: 2.1
|
2
|
+
Name: datanommer.models
|
3
|
+
Version: 1.3.0
|
4
|
+
Summary: SQLAlchemy models for datanommer
|
5
|
+
Home-page: https://github.com/fedora-infra/datanommer
|
6
|
+
License: GPL-3.0-or-later
|
7
|
+
Author: Fedora Infrastructure
|
8
|
+
Author-email: admin@fedoraproject.org
|
9
|
+
Requires-Python: >=3.10,<4.0
|
10
|
+
Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
12
|
+
Classifier: Programming Language :: Python :: 3.10
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
15
|
+
Provides-Extra: schemas
|
16
|
+
Requires-Dist: SQLAlchemy (>=1.3.24,<3.0.0)
|
17
|
+
Requires-Dist: alembic (>=1.6.5,<2.0.0)
|
18
|
+
Requires-Dist: anitya-schema ; extra == "schemas"
|
19
|
+
Requires-Dist: bodhi-messages ; extra == "schemas"
|
20
|
+
Requires-Dist: bugzilla2fedmsg-schema ; extra == "schemas"
|
21
|
+
Requires-Dist: ci-messages ; extra == "schemas"
|
22
|
+
Requires-Dist: copr-messaging ; extra == "schemas"
|
23
|
+
Requires-Dist: discourse2fedmsg-messages ; extra == "schemas"
|
24
|
+
Requires-Dist: fedocal-messages ; extra == "schemas"
|
25
|
+
Requires-Dist: fedora-elections-messages ; extra == "schemas"
|
26
|
+
Requires-Dist: fedora-messaging (>=2.1.0)
|
27
|
+
Requires-Dist: fedora-messaging-git-hook-messages ; extra == "schemas"
|
28
|
+
Requires-Dist: fedora-messaging-the-new-hotness-schema ; extra == "schemas"
|
29
|
+
Requires-Dist: fedora-planet-messages ; extra == "schemas"
|
30
|
+
Requires-Dist: fedorainfra-ansible-messages ; extra == "schemas"
|
31
|
+
Requires-Dist: fmn-messages ; extra == "schemas"
|
32
|
+
Requires-Dist: kerneltest-messages (>=1.0.0,<2.0.0) ; extra == "schemas"
|
33
|
+
Requires-Dist: koji-fedoramessaging-messages (>=1.2.2,<2.0.0) ; extra == "schemas"
|
34
|
+
Requires-Dist: koschei-messages ; extra == "schemas"
|
35
|
+
Requires-Dist: maubot-fedora-messages ; extra == "schemas"
|
36
|
+
Requires-Dist: mdapi-messages ; extra == "schemas"
|
37
|
+
Requires-Dist: mediawiki-messages ; extra == "schemas"
|
38
|
+
Requires-Dist: meetbot-messages ; extra == "schemas"
|
39
|
+
Requires-Dist: noggin-messages ; extra == "schemas"
|
40
|
+
Requires-Dist: nuancier-messages ; extra == "schemas"
|
41
|
+
Requires-Dist: pagure-messages ; extra == "schemas"
|
42
|
+
Requires-Dist: psycopg2 (>=2.9.1,<3.0.0)
|
43
|
+
Requires-Dist: tahrir-messages ; extra == "schemas"
|
44
|
+
Project-URL: Repository, https://github.com/fedora-infra/datanommer
|
45
|
+
Description-Content-Type: text/x-rst
|
46
|
+
|
47
|
+
datanommer.models
|
48
|
+
=================
|
49
|
+
|
50
|
+
This package contains the SQLAlchemy data model for datanommer.
|
51
|
+
|
52
|
+
Datanommer is a storage consumer for the Fedora Infrastructure Message Bus
|
53
|
+
(fedmsg). It is comprised of a `fedmsg <http://fedmsg.com>`_ consumer that
|
54
|
+
stuffs every message into a sqlalchemy database.
|
55
|
+
|
@@ -0,0 +1,10 @@
|
|
1
|
+
datanommer/models/__init__.py,sha256=j3ZIgc2XnXoHaTuC2edq9RoVEqx0g8dc9-3dKi3ctBU,18628
|
2
|
+
datanommer/models/alembic/env.py,sha256=WNTimgnH70CakhvuV5QCilCnOcjTy7kcx0nD7hryYx0,2793
|
3
|
+
datanommer/models/alembic/script.py.mako,sha256=D8kFI44_9vBJZrAYSkZxDTX2-S5Y-oEetEd9BKlo9S8,412
|
4
|
+
datanommer/models/alembic/versions/5db25abc63be_init.py,sha256=xMD7WGCOqeVNFroCZds_aS_jta2yTrAHc_XhtmZLZRs,249
|
5
|
+
datanommer/models/alembic/versions/951c40020acc_unique.py,sha256=GwKDhppKW7y5BUV8BqILZCAiR7GsNyIvoTXUu2A1ZMI,843
|
6
|
+
datanommer/models/testing/__init__.py,sha256=wwAZ-s1U4M7nYNxHgJsn5ZIqLuHMzHrJwGJOwgHAFgc,1693
|
7
|
+
datanommer_models-1.3.0.dist-info/LICENSE,sha256=jOtLnuWt7d5Hsx6XXB2QxzrSe2sWWh3NgMfFRetluQM,35147
|
8
|
+
datanommer_models-1.3.0.dist-info/METADATA,sha256=wKhrCYMD6cECmPOoosFOEIZdtAezEhw1SxwDxlotE54,2561
|
9
|
+
datanommer_models-1.3.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
10
|
+
datanommer_models-1.3.0.dist-info/RECORD,,
|
@@ -1 +0,0 @@
|
|
1
|
-
CREATE EXTENSION IF NOT EXISTS timescaledb;
|
@@ -1,43 +0,0 @@
|
|
1
|
-
Metadata-Version: 2.1
|
2
|
-
Name: datanommer.models
|
3
|
-
Version: 1.0.4
|
4
|
-
Summary: SQLAlchemy models for datanommer
|
5
|
-
Home-page: https://github.com/fedora-infra/datanommer
|
6
|
-
License: GPL-3.0-or-later
|
7
|
-
Author: Fedora Infrastructure
|
8
|
-
Author-email: admin@fedoraproject.org
|
9
|
-
Requires-Python: >=3.7,<4.0
|
10
|
-
Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
|
11
|
-
Classifier: Programming Language :: Python :: 3
|
12
|
-
Classifier: Programming Language :: Python :: 3.7
|
13
|
-
Classifier: Programming Language :: Python :: 3.8
|
14
|
-
Classifier: Programming Language :: Python :: 3.9
|
15
|
-
Provides-Extra: schemas
|
16
|
-
Requires-Dist: SQLAlchemy (>=1.3.24,<2.0.0)
|
17
|
-
Requires-Dist: alembic (>=1.6.5,<2.0.0)
|
18
|
-
Requires-Dist: anitya-schema; extra == "schemas"
|
19
|
-
Requires-Dist: bodhi-messages; extra == "schemas"
|
20
|
-
Requires-Dist: copr-messaging; extra == "schemas"
|
21
|
-
Requires-Dist: discourse2fedmsg-messages; extra == "schemas"
|
22
|
-
Requires-Dist: fedocal-messages; extra == "schemas"
|
23
|
-
Requires-Dist: fedora-messaging (>=2.1.0)
|
24
|
-
Requires-Dist: fedora-messaging-the-new-hotness-schema; extra == "schemas"
|
25
|
-
Requires-Dist: fedora-planet-messages; extra == "schemas"
|
26
|
-
Requires-Dist: fedorainfra-ansible-messages; extra == "schemas"
|
27
|
-
Requires-Dist: mdapi-messages; extra == "schemas"
|
28
|
-
Requires-Dist: noggin-messages; extra == "schemas"
|
29
|
-
Requires-Dist: nuancier-messages; extra == "schemas"
|
30
|
-
Requires-Dist: pagure-messages; extra == "schemas"
|
31
|
-
Requires-Dist: psycopg2 (>=2.9.1,<3.0.0)
|
32
|
-
Project-URL: Repository, https://github.com/fedora-infra/datanommer
|
33
|
-
Description-Content-Type: text/x-rst
|
34
|
-
|
35
|
-
datanommer.models
|
36
|
-
=================
|
37
|
-
|
38
|
-
This package contains the SQLAlchemy data model for datanommer.
|
39
|
-
|
40
|
-
Datanommer is a storage consumer for the Fedora Infrastructure Message Bus
|
41
|
-
(fedmsg). It is comprised of a `fedmsg <http://fedmsg.com>`_ consumer that
|
42
|
-
stuffs every message into a sqlalchemy database.
|
43
|
-
|
@@ -1,11 +0,0 @@
|
|
1
|
-
datanommer/models/__init__.py,sha256=4smdWjO0DSxKQeOn0UAfH93eUKQPtTKklqnBdWbGP0Q,17280
|
2
|
-
datanommer/models/alembic/env.py,sha256=WNTimgnH70CakhvuV5QCilCnOcjTy7kcx0nD7hryYx0,2793
|
3
|
-
datanommer/models/alembic/script.py.mako,sha256=D8kFI44_9vBJZrAYSkZxDTX2-S5Y-oEetEd9BKlo9S8,412
|
4
|
-
datanommer/models/alembic/versions/5db25abc63be_init.py,sha256=xMD7WGCOqeVNFroCZds_aS_jta2yTrAHc_XhtmZLZRs,249
|
5
|
-
datanommer/models/alembic/versions/951c40020acc_unique.py,sha256=GwKDhppKW7y5BUV8BqILZCAiR7GsNyIvoTXUu2A1ZMI,843
|
6
|
-
datanommer/models/testing/__init__.py,sha256=4aNMycVGrYA6Ljo74ePweDrzSr9oaA7K_W2gtn0YZ74,1271
|
7
|
-
datanommer/models/testing/startup.sql,sha256=tdjQMZcM7bVDoLnfSg1-fpKKiAPihiVPy-syF0H8mvo,44
|
8
|
-
datanommer.models-1.0.4.dist-info/LICENSE,sha256=jOtLnuWt7d5Hsx6XXB2QxzrSe2sWWh3NgMfFRetluQM,35147
|
9
|
-
datanommer.models-1.0.4.dist-info/WHEEL,sha256=N0LZrBtofpkS5mJXgVHTCEy52Sam4D6PHQWC8HnMeTs,83
|
10
|
-
datanommer.models-1.0.4.dist-info/METADATA,sha256=P6Jrz1-dqJlXlhbsANOKWcXNiVpJI4-W0jOiLB5vW0g,1828
|
11
|
-
datanommer.models-1.0.4.dist-info/RECORD,,
|
File without changes
|