3
from sqlalchemy.testing.assertions import eq_, assert_raises, \
4
assert_raises_message, AssertsExecutionResults, \
6
from sqlalchemy.testing import engines, fixtures
7
from sqlalchemy import testing
9
from sqlalchemy import Table, Column, select, MetaData, text, Integer, \
10
String, Sequence, ForeignKey, join, Numeric, \
11
PrimaryKeyConstraint, DateTime, tuple_, Float, BigInteger, \
12
func, literal_column, literal, bindparam, cast, extract, \
13
SmallInteger, Enum, REAL, update, insert, Index, delete, \
14
and_, Date, TypeDecorator, Time, Unicode, Interval, or_, Text
15
from sqlalchemy import exc, schema
16
from sqlalchemy.dialects.postgresql import base as postgresql
18
import logging.handlers
19
from sqlalchemy.testing.mock import Mock
21
class MiscTest(fixtures.TestBase, AssertsExecutionResults, AssertsCompiledSQL):
23
__only_on__ = 'postgresql'
25
@testing.provide_metadata
26
def test_date_reflection(self):
27
metadata = self.metadata
28
t1 = Table('pgdate', metadata, Column('date1',
29
DateTime(timezone=True)), Column('date2',
30
DateTime(timezone=False)))
32
m2 = MetaData(testing.db)
33
t2 = Table('pgdate', m2, autoload=True)
34
assert t2.c.date1.type.timezone is True
35
assert t2.c.date2.type.timezone is False
37
@testing.fails_on('+zxjdbc',
38
'The JDBC driver handles the version parsing')
39
def test_version_parsing(self):
44
return_value=Mock(scalar=Mock(return_value=res))
48
for string, version in \
49
[('PostgreSQL 8.3.8 on i686-redhat-linux-gnu, compiled by '
50
'GCC gcc (GCC) 4.1.2 20070925 (Red Hat 4.1.2-33)', (8, 3,
52
('PostgreSQL 8.5devel on x86_64-unknown-linux-gnu, '
53
'compiled by GCC gcc (GCC) 4.4.2, 64-bit', (8, 5)),
54
('EnterpriseDB 9.1.2.2 on x86_64-unknown-linux-gnu, '
55
'compiled by gcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-50), '
56
'64-bit', (9, 1, 2))]:
57
eq_(testing.db.dialect._get_server_version_info(mock_conn(string)),
60
@testing.only_on('postgresql+psycopg2', 'psycopg2-specific feature')
61
def test_psycopg2_version(self):
62
v = testing.db.dialect.psycopg2_version
63
assert testing.db.dialect.dbapi.__version__.\
64
startswith(".".join(str(x) for x in v))
66
@testing.only_on('postgresql+psycopg2', 'psycopg2-specific feature')
67
def test_notice_logging(self):
68
log = logging.getLogger('sqlalchemy.dialects.postgresql')
69
buf = logging.handlers.BufferingHandler(100)
72
log.setLevel(logging.INFO)
74
conn = testing.db.connect()
77
conn.execute('create table foo (id serial primary key)')
81
log.removeHandler(buf)
83
msgs = ' '.join(b.msg for b in buf.buffer)
84
assert 'will create implicit sequence' in msgs
85
assert 'will create implicit index' in msgs
87
@testing.only_on('postgresql+psycopg2', 'psycopg2-specific feature')
88
@engines.close_open_connections
89
def test_client_encoding(self):
90
c = testing.db.connect()
91
current_encoding = c.connection.connection.encoding
94
# attempt to use an encoding that's not
96
if current_encoding == 'UTF8':
97
test_encoding = 'LATIN1'
99
test_encoding = 'UTF8'
101
e = engines.testing_engine(
102
options={'client_encoding':test_encoding}
105
eq_(c.connection.connection.encoding, test_encoding)
107
@testing.only_on('postgresql+psycopg2', 'psycopg2-specific feature')
108
@engines.close_open_connections
109
def test_autocommit_isolation_level(self):
110
extensions = __import__('psycopg2.extensions').extensions
112
c = testing.db.connect()
113
c = c.execution_options(isolation_level='AUTOCOMMIT')
114
eq_(c.connection.connection.isolation_level,
115
extensions.ISOLATION_LEVEL_AUTOCOMMIT)
117
@testing.fails_on('+zxjdbc',
118
"Can't infer the SQL type to use for an instance "
119
"of org.python.core.PyObjectDerived.")
120
@testing.fails_on('+pg8000', "Can't determine correct type.")
121
def test_extract(self):
122
fivedaysago = datetime.datetime.now() \
123
- datetime.timedelta(days=5)
124
for field, exp in ('year', fivedaysago.year), ('month',
125
fivedaysago.month), ('day', fivedaysago.day):
126
r = testing.db.execute(select([extract(field, func.now()
127
+ datetime.timedelta(days=-5))])).scalar()
130
def test_checksfor_sequence(self):
131
meta1 = MetaData(testing.db)
132
seq = Sequence('fooseq')
133
t = Table('mytable', meta1, Column('col1', Integer,
137
testing.db.execute('CREATE SEQUENCE fooseq')
138
t.create(checkfirst=True)
140
t.drop(checkfirst=True)
142
def test_schema_roundtrips(self):
143
meta = MetaData(testing.db)
144
users = Table('users', meta, Column('id', Integer,
145
primary_key=True), Column('name', String(50)),
146
schema='test_schema')
149
users.insert().execute(id=1, name='name1')
150
users.insert().execute(id=2, name='name2')
151
users.insert().execute(id=3, name='name3')
152
users.insert().execute(id=4, name='name4')
153
eq_(users.select().where(users.c.name == 'name2'
154
).execute().fetchall(), [(2, 'name2')])
155
eq_(users.select(use_labels=True).where(users.c.name
156
== 'name2').execute().fetchall(), [(2, 'name2')])
157
users.delete().where(users.c.id == 3).execute()
158
eq_(users.select().where(users.c.name == 'name3'
159
).execute().fetchall(), [])
160
users.update().where(users.c.name == 'name4'
161
).execute(name='newname')
162
eq_(users.select(use_labels=True).where(users.c.id
163
== 4).execute().fetchall(), [(4, 'newname')])
167
def test_preexecute_passivedefault(self):
168
"""test that when we get a primary key column back from
169
reflecting a table which has a default value on it, we pre-
170
execute that DefaultClause upon insert."""
173
meta = MetaData(testing.db)
174
testing.db.execute("""
175
CREATE TABLE speedy_users
177
speedy_user_id SERIAL PRIMARY KEY,
179
user_name VARCHAR NOT NULL,
180
user_password VARCHAR NOT NULL
183
t = Table('speedy_users', meta, autoload=True)
184
r = t.insert().execute(user_name='user',
185
user_password='lala')
186
assert r.inserted_primary_key == [1]
187
l = t.select().execute().fetchall()
188
assert l == [(1, 'user', 'lala')]
190
testing.db.execute('drop table speedy_users')
193
@testing.fails_on('+zxjdbc', 'psycopg2/pg8000 specific assertion')
194
@testing.fails_on('pypostgresql',
195
'psycopg2/pg8000 specific assertion')
196
def test_numeric_raise(self):
197
stmt = text("select cast('hi' as char) as hi", typemap={'hi'
199
assert_raises(exc.InvalidRequestError, testing.db.execute, stmt)
201
def test_serial_integer(self):
202
for type_, expected in [
204
(BigInteger, 'BIGSERIAL'),
205
(SmallInteger, 'SMALLINT'),
206
(postgresql.INTEGER, 'SERIAL'),
207
(postgresql.BIGINT, 'BIGSERIAL'),
211
t = Table('t', m, Column('c', type_, primary_key=True))
212
ddl_compiler = testing.db.dialect.ddl_compiler(testing.db.dialect, schema.CreateTable(t))
214
ddl_compiler.get_column_specification(t.c.c),
215
"c %s NOT NULL" % expected