⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 firebird.py

📁 SQLAlchemy. 经典的Python ORM框架。学习必看。
💻 PY
📖 第 1 页 / 共 2 页
字号:
        return [self._normalize_name(row[0]) for row in connection.execute(s)]    def has_table(self, connection, table_name, schema=None):        """Return ``True`` if the given table exists, ignoring the `schema`."""        tblqry = """        SELECT 1 FROM rdb$database        WHERE EXISTS (SELECT rdb$relation_name                      FROM rdb$relations                      WHERE rdb$relation_name=?)        """        c = connection.execute(tblqry, [self._denormalize_name(table_name)])        row = c.fetchone()        if row is not None:            return True        else:            return False    def has_sequence(self, connection, sequence_name):        """Return ``True`` if the given sequence (generator) exists."""        genqry = """        SELECT 1 FROM rdb$database        WHERE EXISTS (SELECT rdb$generator_name                      FROM rdb$generators                      WHERE rdb$generator_name=?)        """        c = connection.execute(genqry, [self._denormalize_name(sequence_name)])        row = c.fetchone()        if row is not None:            return True        else:            return False    def is_disconnect(self, e):        if isinstance(e, self.dbapi.OperationalError):            return 'Unable to complete network request to host' in str(e)        elif isinstance(e, self.dbapi.ProgrammingError):            return 'Invalid connection state' in str(e)        else:            return False    def reflecttable(self, connection, table, include_columns):        # Query to extract the details of all the fields of the given table        tblqry = """        SELECT DISTINCT r.rdb$field_name AS fname,                        r.rdb$null_flag AS null_flag,                        t.rdb$type_name AS ftype,                        f.rdb$field_sub_type AS stype,                        f.rdb$field_length AS flen,                        f.rdb$field_precision AS fprec,                        f.rdb$field_scale AS fscale,                        COALESCE(r.rdb$default_source, f.rdb$default_source) AS fdefault        FROM rdb$relation_fields r             JOIN rdb$fields f ON r.rdb$field_source=f.rdb$field_name             JOIN rdb$types t ON t.rdb$type=f.rdb$field_type AND t.rdb$field_name='RDB$FIELD_TYPE'        WHERE f.rdb$system_flag=0 AND r.rdb$relation_name=?        ORDER BY r.rdb$field_position        """        # Query to extract the PK/FK constrained fields of the given table        keyqry = """        SELECT se.rdb$field_name AS fname        FROM rdb$relation_constraints rc             JOIN rdb$index_segments se ON rc.rdb$index_name=se.rdb$index_name        WHERE rc.rdb$constraint_type=? AND rc.rdb$relation_name=?        """        # Query to extract the details of each UK/FK of the given table        fkqry = """        SELECT rc.rdb$constraint_name AS cname,               cse.rdb$field_name AS fname,               ix2.rdb$relation_name AS targetrname,               se.rdb$field_name AS targetfname        FROM rdb$relation_constraints rc             JOIN rdb$indices ix1 ON ix1.rdb$index_name=rc.rdb$index_name             JOIN rdb$indices ix2 ON ix2.rdb$index_name=ix1.rdb$foreign_key             JOIN rdb$index_segments cse ON cse.rdb$index_name=ix1.rdb$index_name             JOIN rdb$index_segments se ON se.rdb$index_name=ix2.rdb$index_name AND se.rdb$field_position=cse.rdb$field_position        WHERE rc.rdb$constraint_type=? AND rc.rdb$relation_name=?        ORDER BY se.rdb$index_name, se.rdb$field_position        """        # Heuristic-query to determine the generator associated to a PK field        genqry = """        SELECT trigdep.rdb$depended_on_name AS fgenerator        FROM rdb$dependencies tabdep             JOIN rdb$dependencies trigdep ON (tabdep.rdb$dependent_name=trigdep.rdb$dependent_name                                               AND trigdep.rdb$depended_on_type=14                                               AND trigdep.rdb$dependent_type=2)             JOIN rdb$triggers trig ON (trig.rdb$trigger_name=tabdep.rdb$dependent_name)        WHERE tabdep.rdb$depended_on_name=?          AND tabdep.rdb$depended_on_type=0          AND trig.rdb$trigger_type=1          AND tabdep.rdb$field_name=?          AND (SELECT count(*)               FROM rdb$dependencies trigdep2               WHERE trigdep2.rdb$dependent_name = trigdep.rdb$dependent_name) = 2        """        tablename = self._denormalize_name(table.name)        # get primary key fields        c = connection.execute(keyqry, ["PRIMARY KEY", tablename])        pkfields =[self._normalize_name(r['fname']) for r in c.fetchall()]        # get all of the fields for this table        c = connection.execute(tblqry, [tablename])        found_table = False        while True:            row = c.fetchone()            if row is None:                break            found_table = True            name = self._normalize_name(row['fname'])            if include_columns and name not in include_columns:                continue            args = [name]            kw = {}            # get the data type            coltype = ischema_names.get(row['ftype'].rstrip())            if coltype is None:                util.warn("Did not recognize type '%s' of column '%s'" %                          (str(row['ftype']), name))                coltype = sqltypes.NULLTYPE            else:                coltype = coltype(row)            args.append(coltype)            # is it a primary key?            kw['primary_key'] = name in pkfields            # is it nullable?            kw['nullable'] = not bool(row['null_flag'])            # does it have a default value?            if row['fdefault'] is not None:                # the value comes down as "DEFAULT 'value'"                assert row['fdefault'].startswith('DEFAULT ')                defvalue = row['fdefault'][8:]                args.append(schema.PassiveDefault(sql.text(defvalue)))            col = schema.Column(*args, **kw)            if kw['primary_key']:                # if the PK is a single field, try to see if its linked to                # a sequence thru a trigger                if len(pkfields)==1:                    genc = connection.execute(genqry, [tablename, row['fname']])                    genr = genc.fetchone()                    if genr is not None:                        col.sequence = schema.Sequence(self._normalize_name(genr['fgenerator']))            table.append_column(col)        if not found_table:            raise exceptions.NoSuchTableError(table.name)        # get the foreign keys        c = connection.execute(fkqry, ["FOREIGN KEY", tablename])        fks = {}        while True:            row = c.fetchone()            if not row: break            cname = self._normalize_name(row['cname'])            try:                fk = fks[cname]            except KeyError:                fks[cname] = fk = ([], [])            rname = self._normalize_name(row['targetrname'])            schema.Table(rname, table.metadata, autoload=True, autoload_with=connection)            fname = self._normalize_name(row['fname'])            refspec = rname + '.' + self._normalize_name(row['targetfname'])            fk[0].append(fname)            fk[1].append(refspec)        for name,value in fks.iteritems():            table.append_constraint(schema.ForeignKeyConstraint(value[0], value[1], name=name))    def do_execute(self, cursor, statement, parameters, **kwargs):        # kinterbase does not accept a None, but wants an empty list        # when there are no arguments.        cursor.execute(statement, parameters or [])    def do_rollback(self, connection):        # Use the retaining feature, that keeps the transaction going        connection.rollback(True)    def do_commit(self, connection):        # Use the retaining feature, that keeps the transaction going        connection.commit(True)class FBCompiler(sql.compiler.DefaultCompiler):    """Firebird specific idiosincrasies"""    # Firebird lacks a builtin modulo operator, but there is    # an equivalent function in the ib_udf library.    operators = sql.compiler.DefaultCompiler.operators.copy()    operators.update({        sql.operators.mod : lambda x, y:"mod(%s, %s)" % (x, y)        })    def visit_alias(self, alias, asfrom=False, **kwargs):        # Override to not use the AS keyword which FB 1.5 does not like        if asfrom:            return self.process(alias.original, asfrom=True, **kwargs) + " " + self.preparer.format_alias(alias, self._anonymize(alias.name))        else:            return self.process(alias.original, **kwargs)    def function_argspec(self, func):        if func.clauses:            return self.process(func.clause_expr)        else:            return ""    def default_from(self):        return " FROM rdb$database"    def visit_sequence(self, seq):        return "gen_id(%s, 1)" % self.preparer.format_sequence(seq)    def get_select_precolumns(self, select):        """Called when building a ``SELECT`` statement, position is just        before column list Firebird puts the limit and offset right        after the ``SELECT``...        """        result = ""        if select._limit:            result += "FIRST %d "  % select._limit        if select._offset:            result +="SKIP %d "  %  select._offset        if select._distinct:            result += "DISTINCT "        return result    def limit_clause(self, select):        """Already taken care of in the `get_select_precolumns` method."""        return ""    LENGTH_FUNCTION_NAME = 'char_length'    def function_string(self, func):        """Substitute the ``length`` function.        On newer FB there is a ``char_length`` function, while older        ones need the ``strlen`` UDF.        """        if func.name == 'length':            return self.LENGTH_FUNCTION_NAME + '%(expr)s'        return super(FBCompiler, self).function_string(func)class FBSchemaGenerator(sql.compiler.SchemaGenerator):    """Firebird syntactic idiosincrasies"""    def get_column_specification(self, column, **kwargs):        colspec = self.preparer.format_column(column)        colspec += " " + column.type.dialect_impl(self.dialect, _for_ddl=column).get_col_spec()        default = self.get_column_default_string(column)        if default is not None:            colspec += " DEFAULT " + default        if not column.nullable or column.primary_key:            colspec += " NOT NULL"        return colspec    def visit_sequence(self, sequence):        """Generate a ``CREATE GENERATOR`` statement for the sequence."""        self.append("CREATE GENERATOR %s" % self.preparer.format_sequence(sequence))        self.execute()class FBSchemaDropper(sql.compiler.SchemaDropper):    """Firebird syntactic idiosincrasies"""    def visit_sequence(self, sequence):        """Generate a ``DROP GENERATOR`` statement for the sequence."""        self.append("DROP GENERATOR %s" % self.preparer.format_sequence(sequence))        self.execute()class FBDefaultRunner(base.DefaultRunner):    """Firebird specific idiosincrasies"""    def visit_sequence(self, seq):        """Get the next value from the sequence using ``gen_id()``."""        return self.execute_string("SELECT gen_id(%s, 1) FROM rdb$database" % \            self.dialect.identifier_preparer.format_sequence(seq))RESERVED_WORDS = util.Set(    ["action", "active", "add", "admin", "after", "all", "alter", "and", "any",     "as", "asc", "ascending", "at", "auto", "autoddl", "avg", "based", "basename",     "base_name", "before", "begin", "between", "bigint", "blob", "blobedit", "buffer",     "by", "cache", "cascade", "case", "cast", "char", "character", "character_length",     "char_length", "check", "check_point_len", "check_point_length", "close", "collate",     "collation", "column", "commit", "committed", "compiletime", "computed", "conditional",     "connect", "constraint", "containing", "continue", "count", "create", "cstring",     "current", "current_connection", "current_date", "current_role", "current_time",     "current_timestamp", "current_transaction", "current_user", "cursor", "database",     "date", "day", "db_key", "debug", "dec", "decimal", "declare", "default", "delete",     "desc", "descending", "describe", "descriptor", "disconnect", "display", "distinct",     "do", "domain", "double", "drop", "echo", "edit", "else", "end", "entry_point",     "escape", "event", "exception", "execute", "exists", "exit", "extern", "external",     "extract", "fetch", "file", "filter", "float", "for", "foreign", "found", "free_it",     "from", "full", "function", "gdscode", "generator", "gen_id", "global", "goto",     "grant", "group", "group_commit_", "group_commit_wait", "having", "help", "hour",     "if", "immediate", "in", "inactive", "index", "indicator", "init", "inner", "input",     "input_type", "insert", "int", "integer", "into", "is", "isolation", "isql", "join",     "key", "lc_messages", "lc_type", "left", "length", "lev", "level", "like", "logfile",     "log_buffer_size", "log_buf_size", "long", "manual", "max", "maximum", "maximum_segment",     "max_segment", "merge", "message", "min", "minimum", "minute", "module_name", "month",     "names", "national", "natural", "nchar", "no", "noauto", "not", "null", "numeric",     "num_log_buffers", "num_log_bufs", "octet_length", "of", "on", "only", "open", "option",     "or", "order", "outer", "output", "output_type", "overflow", "page", "pagelength",     "pages", "page_size", "parameter", "password", "plan", "position", "post_event",     "precision", "prepare", "primary", "privileges", "procedure", "protected", "public",     "quit", "raw_partitions", "rdb$db_key", "read", "real", "record_version", "recreate",     "references", "release", "release", "reserv", "reserving", "restrict", "retain",     "return", "returning_values", "returns", "revoke", "right", "role", "rollback",     "row_count", "runtime", "savepoint", "schema", "second", "segment", "select",     "set", "shadow", "shared", "shell", "show", "singular", "size", "smallint",     "snapshot", "some", "sort", "sqlcode", "sqlerror", "sqlwarning", "stability",     "starting", "starts", "statement", "static", "statistics", "sub_type", "sum",     "suspend", "table", "terminator", "then", "time", "timestamp", "to", "transaction",     "translate", "translation", "trigger", "trim", "type", "uncommitted", "union",     "unique", "update", "upper", "user", "using", "value", "values", "varchar",     "variable", "varying", "version", "view", "wait", "wait_time", "weekday", "when",     "whenever", "where", "while", "with", "work", "write", "year", "yearday" ])class FBIdentifierPreparer(sql.compiler.IdentifierPreparer):    """Install Firebird specific reserved words."""    reserved_words = RESERVED_WORDS    def __init__(self, dialect):        super(FBIdentifierPreparer,self).__init__(dialect, omit_schema=True)dialect = FBDialectdialect.statement_compiler = FBCompilerdialect.schemagenerator = FBSchemaGeneratordialect.schemadropper = FBSchemaDropperdialect.defaultrunner = FBDefaultRunnerdialect.preparer = FBIdentifierPreparer

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -