Author: phd
Date: 2005-10-28 11:34:54 +0000 (Fri, 28 Oct 2005)
New Revision: 1160
Modified:
home/phd/SQLObject/paramstyles/docs/News.txt
home/phd/SQLObject/paramstyles/docs/sqlobject-admin.txt
home/phd/SQLObject/paramstyles/sqlobject/mssql/mssqlconnection.py
home/phd/SQLObject/paramstyles/sqlobject/sqlbuilder.py
Log:
Merged revisions 1154:1159 from the trunk
Modified: home/phd/SQLObject/paramstyles/docs/News.txt
===================================================================
--- home/phd/SQLObject/paramstyles/docs/News.txt 2005-10-28 11:31:50 UTC (rev 1159)
+++ home/phd/SQLObject/paramstyles/docs/News.txt 2005-10-28 11:34:54 UTC (rev 1160)
@@ -29,6 +29,13 @@
instead you must manually create it (e.g., with explicit SQLObject
classes for the joins).
+* Added ``createSQL`` as an option for sqlmeta. Here you can add related SQL
+ you want executed by sqlobject-admin create after table creation. createSQL
+ expects a string, list, or dictionary. If using a dictionary the key should
+ be a dbName value (ex. 'postgres') and the value should be a string or list.
+ Examples in sqlobject/tests/test_sqlobject_admin.py or at
+ <http://sqlobject.org/sqlobject-admin.html#the-create-command>
+
SQLObject 0.7.0
===============
Modified: home/phd/SQLObject/paramstyles/docs/sqlobject-admin.txt
===================================================================
--- home/phd/SQLObject/paramstyles/docs/sqlobject-admin.txt 2005-10-28 11:31:50 UTC (rev 1159)
+++ home/phd/SQLObject/paramstyles/docs/sqlobject-admin.txt 2005-10-28 11:34:54 UTC (rev 1160)
@@ -94,6 +94,19 @@
This finds the tables and creates them. Any tables that exist are
simply skipped.
+It also collects data from sqlmeta.createSQL and runs the queries
+after table creation. createSQL can be a string with a single SQL
+command, a list of SQL commands, or a dictionary with keys that are
+dbNames and values that are either single SQL command string or a list
+of SQL commands. An example follows::
+
+ class MyTable(SQLObject):
+ class sqlmeta:
+ createSQL = {'postgres': [
+ "ALTER TABLE my_table ADD CHECK(my_field != '');",
+ ]}
+ myField = StringCol()
+
The ``sql`` Command
-------------------
Modified: home/phd/SQLObject/paramstyles/sqlobject/mssql/mssqlconnection.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/mssql/mssqlconnection.py 2005-10-28 11:31:50 UTC (rev 1159)
+++ home/phd/SQLObject/paramstyles/sqlobject/mssql/mssqlconnection.py 2005-10-28 11:34:54 UTC (rev 1160)
@@ -16,14 +16,25 @@
if not sqlmodule:
try:
import adodbapi as sqlmodule
- self.dbconnection = sqlmodule.Connection
- self.make_conn_str = lambda keys: \
- ["Provider=SQLOLEDB;Data Source=%s;User Id=%s;Password=%s;Initial Catalog=%s" % (
- keys.host, keys.user, keys.password, keys.db)]
- except:
+ self.dbconnection = sqlmodule.connect
+ # ADO uses unicode only (AFAIK)
+ self.usingUnicodeStrings = True
+ # MSDE does not allow SQL server login
+ if "sspi" in kw and kw["sspi"]:
+ self.make_conn_str = lambda keys: \
+ ["Provider=SQLOLEDB;Data Source=%s;Initial Catalog=%s;Integrated Security=SSPI;Persist Security Info=False" % (
+ keys.host, keys.db)]
+ del kw["sspi"]
+ else:
+ self.make_conn_str = lambda keys: \
+ ["Provider=SQLOLEDB;Data Source=%s;User Id=%s;Password=%s;Initial Catalog=%s" % (
+ keys.host, keys.user, keys.password, keys.db)]
+ except ImportError: # raise the exceptions other than ImportError for adodbapi absence
import pymssql as sqlmodule
self.dbconnection = sqlmodule.connect
sqlmodule.Binary = lambda st: str(st)
+ # don't know whether pymssql uses unicode
+ self.usingUnicodeStrings = False
self.make_conn_str = lambda keys: \
["", keys.user, keys.password, keys.host, keys.db]
self.autoCommit=autoCommit
@@ -155,6 +166,8 @@
(tableName,
column.dbName))
+ # precision and scale is gotten from column table so that we can create
+ # decimal columns if needed
SHOW_COLUMNS = """
select
name,
@@ -163,6 +176,8 @@
from systypes
where cast(xusertype as int)= cast(sc.xtype as int)
) datatype,
+ prec,
+ scale,
isnullable,
cdefault,
m.text default_text,
@@ -181,11 +196,12 @@
colData = self.queryAll(self.SHOW_COLUMNS
% tableName)
results = []
- for field, size, t, nullAllowed, default, defaultText, is_identity in colData:
+ for field, size, t, precision, scale, nullAllowed, default, defaultText, is_identity in colData:
# Seems strange to skip the pk column? What if it's not 'id'?
if field == 'id':
continue
- colClass, kw = self.guessClass(t, size)
+ # precision is needed for decimal columns
+ colClass, kw = self.guessClass(t, size, precision, scale)
kw['name'] = soClass.sqlmeta.style.dbColumnToPythonAttr(field)
kw['notNone'] = not nullAllowed
if (defaultText):
@@ -213,21 +229,30 @@
if auto == 0:
option = "OFF"
c = conn.cursor()
- c.execute("SET AUTOCOMMIT "+option)
+ c.execute("SET AUTOCOMMIT " + option)
conn.setconnectoption(SQL.AUTOCOMMIT, option)
- def guessClass(self, t, size):
+ # precision and scale is needed for decimal columns
+ def guessClass(self, t, size, precision, scale):
"""
Here we take raw values coming out of syscolumns and map to SQLObject class types.
"""
if t.startswith('int'):
return col.IntCol, {}
elif t.startswith('varchar'):
+ if self.usingUnicodeStrings:
+ return col.UnicodeCol, {'length': size}
return col.StringCol, {'length': size}
elif t.startswith('char'):
+ if self.usingUnicodeStrings:
+ return col.UnicodeCol, {'length': size,
+ 'varchar': False}
return col.StringCol, {'length': size,
'varchar': False}
elif t.startswith('datetime'):
return col.DateTimeCol, {}
+ elif t.startswith('decimal'):
+ return col.DecimalCol, {'size': precision, # be careful for awkward naming
+ 'precision': scale}
else:
return col.Col, {}
Modified: home/phd/SQLObject/paramstyles/sqlobject/sqlbuilder.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/sqlbuilder.py 2005-10-28 11:31:50 UTC (rev 1159)
+++ home/phd/SQLObject/paramstyles/sqlobject/sqlbuilder.py 2005-10-28 11:34:54 UTC (rev 1160)
@@ -72,11 +72,14 @@
import re, fnmatch
import operator
import threading
+import types
+
from converters import sqlrepr, registerConverter, TRUE, FALSE
safeSQLRE = re.compile(r'^[a-zA-Z_][a-zA-Z0-9_\.]*$')
def sqlIdentifier(obj):
- return type(obj) is type("") and not not safeSQLRE.search(obj.strip())
+ # some db drivers return unicode column names
+ return isinstance(obj, types.StringTypes) and bool(safeSQLRE.search(obj.strip()))
def execute(expr, executor):
|