forked from getsentry/sentry-python
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_sqlalchemy.py
More file actions
135 lines (107 loc) · 4.43 KB
/
test_sqlalchemy.py
File metadata and controls
135 lines (107 loc) · 4.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
import sys
import pytest
from sqlalchemy import Column, ForeignKey, Integer, String, create_engine
from sqlalchemy.exc import IntegrityError
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship, sessionmaker
from sentry_sdk import capture_message, start_transaction
from sentry_sdk.integrations.sqlalchemy import SqlalchemyIntegration
def test_orm_queries(sentry_init, capture_events):
sentry_init(
integrations=[SqlalchemyIntegration()], _experiments={"record_sql_params": True}
)
events = capture_events()
Base = declarative_base() # noqa: N806
class Person(Base):
__tablename__ = "person"
id = Column(Integer, primary_key=True)
name = Column(String(250), nullable=False)
class Address(Base):
__tablename__ = "address"
id = Column(Integer, primary_key=True)
street_name = Column(String(250))
street_number = Column(String(250))
post_code = Column(String(250), nullable=False)
person_id = Column(Integer, ForeignKey("person.id"))
person = relationship(Person)
engine = create_engine("sqlite:///:memory:")
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine) # noqa: N806
session = Session()
bob = Person(name="Bob")
session.add(bob)
assert session.query(Person).first() == bob
capture_message("hi")
(event,) = events
for crumb in event["breadcrumbs"]:
del crumb["timestamp"]
assert event["breadcrumbs"][-2:] == [
{
"category": "query",
"data": {"db.params": ["Bob"], "db.paramstyle": "qmark"},
"message": "INSERT INTO person (name) VALUES (?)",
"type": "default",
},
{
"category": "query",
"data": {"db.params": [1, 0], "db.paramstyle": "qmark"},
"message": "SELECT person.id AS person_id, person.name AS person_name \n"
"FROM person\n"
" LIMIT ? OFFSET ?",
"type": "default",
},
]
@pytest.mark.skipif(
sys.version_info < (3,), reason="This sqla usage seems to be broken on Py2"
)
def test_transactions(sentry_init, capture_events, render_span_tree):
sentry_init(
integrations=[SqlalchemyIntegration()], _experiments={"record_sql_params": True}
)
events = capture_events()
Base = declarative_base() # noqa: N806
class Person(Base):
__tablename__ = "person"
id = Column(Integer, primary_key=True)
name = Column(String(250), nullable=False)
class Address(Base):
__tablename__ = "address"
id = Column(Integer, primary_key=True)
street_name = Column(String(250))
street_number = Column(String(250))
post_code = Column(String(250), nullable=False)
person_id = Column(Integer, ForeignKey("person.id"))
person = relationship(Person)
engine = create_engine("sqlite:///:memory:")
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine) # noqa: N806
session = Session()
with start_transaction(name="test_transaction", sampled=True):
with session.begin_nested():
session.query(Person).first()
for _ in range(2):
with pytest.raises(IntegrityError):
with session.begin_nested():
session.add(Person(id=1, name="bob"))
session.add(Person(id=1, name="bob"))
with session.begin_nested():
session.query(Person).first()
(event,) = events
assert (
render_span_tree(event)
== """\
- op=None: description=None
- op='db': description='SAVEPOINT sa_savepoint_1'
- op='db': description='SELECT person.id AS person_id, person.name AS person_name \\nFROM person\\n LIMIT ? OFFSET ?'
- op='db': description='RELEASE SAVEPOINT sa_savepoint_1'
- op='db': description='SAVEPOINT sa_savepoint_2'
- op='db': description='INSERT INTO person (id, name) VALUES (?, ?)'
- op='db': description='ROLLBACK TO SAVEPOINT sa_savepoint_2'
- op='db': description='SAVEPOINT sa_savepoint_3'
- op='db': description='INSERT INTO person (id, name) VALUES (?, ?)'
- op='db': description='ROLLBACK TO SAVEPOINT sa_savepoint_3'
- op='db': description='SAVEPOINT sa_savepoint_4'
- op='db': description='SELECT person.id AS person_id, person.name AS person_name \\nFROM person\\n LIMIT ? OFFSET ?'
- op='db': description='RELEASE SAVEPOINT sa_savepoint_4'\
"""
)